5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 extern char *server_version;
30 /* Received private message. This resolves the destination of the message
31 and sends the packet. This is used by both server and router. If the
32 destination is our locally connected client this sends the packet to
33 the client. This may also send the message for further routing if
34 the destination is not in our server (or router). */
36 void silc_server_private_message(SilcServer server,
37 SilcSocketConnection sock,
38 SilcPacketContext *packet)
41 SilcServerEntry router;
42 SilcSocketConnection dst_sock;
43 SilcClientEntry client;
46 SILC_LOG_DEBUG(("Start"));
51 /* Decode destination Client ID */
52 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
54 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
58 /* If the destination belongs to our server we don't have to route
59 the message anywhere but to send it to the local destination. */
60 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
62 /* It exists, now deliver the message to the destination */
63 dst_sock = (SilcSocketConnection)client->connection;
65 /* If we are router and the client has router then the client is in
66 our cell but not directly connected to us. */
67 if (server->server_type == SILC_ROUTER && client->router) {
68 /* We are of course in this case the client's router thus the real
69 "router" of the client is the server who owns the client. Thus
70 we will send the packet to that server. */
71 router = (SilcServerEntry)dst_sock->user_data;
72 idata = (SilcIDListData)router;
74 silc_server_send_private_message(server, dst_sock,
81 /* Seems that client really is directly connected to us */
82 idata = (SilcIDListData)client;
83 silc_server_send_private_message(server, dst_sock,
89 /* Destination belongs to someone not in this server. If we are normal
90 server our action is to send the packet to our router. */
91 if (server->server_type == SILC_SERVER && !server->standalone) {
92 router = server->router;
94 /* Send to primary route */
96 dst_sock = (SilcSocketConnection)router->connection;
97 idata = (SilcIDListData)router;
98 silc_server_send_private_message(server, dst_sock,
100 idata->hmac, packet);
105 /* We are router and we will perform route lookup for the destination
106 and send the message to fastest route. */
107 if (server->server_type == SILC_ROUTER && !server->standalone) {
108 /* Check first that the ID is valid */
109 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
111 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
112 router = (SilcServerEntry)dst_sock->user_data;
113 idata = (SilcIDListData)router;
115 /* Get fastest route and send packet. */
117 silc_server_send_private_message(server, dst_sock,
119 idata->hmac, packet);
125 silc_server_send_error(server, sock,
126 "No such nickname: Private message not sent");
129 /* Processes incoming command reply packet. The command reply packet may
130 be destined to one of our clients or it may directly for us. We will
131 call the command reply routine after processing the packet. */
133 void silc_server_command_reply(SilcServer server,
134 SilcSocketConnection sock,
135 SilcPacketContext *packet)
137 SilcBuffer buffer = packet->buffer;
138 SilcClientEntry client = NULL;
139 SilcSocketConnection dst_sock;
140 SilcIDListData idata;
141 SilcClientID *id = NULL;
143 SILC_LOG_DEBUG(("Start"));
145 /* Source must be server or router */
146 if (packet->src_id_type != SILC_ID_SERVER &&
147 sock->type != SILC_SOCKET_TYPE_ROUTER)
150 if (packet->dst_id_type == SILC_ID_CHANNEL)
153 if (packet->dst_id_type == SILC_ID_CLIENT) {
154 /* Destination must be one of ours */
155 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
156 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
158 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
164 if (packet->dst_id_type == SILC_ID_SERVER) {
165 /* For now this must be for us */
166 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
167 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
172 /* Execute command reply locally for the command */
173 silc_server_command_reply_process(server, sock, buffer);
175 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
176 /* Relay the packet to the client */
178 dst_sock = (SilcSocketConnection)client->connection;
179 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
180 + packet->dst_id_len + packet->padlen);
182 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
183 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
185 idata = (SilcIDListData)client;
188 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
191 /* Send the packet */
192 silc_server_packet_send_real(server, dst_sock, TRUE);
198 /* Process received channel message. The message can be originated from
201 void silc_server_channel_message(SilcServer server,
202 SilcSocketConnection sock,
203 SilcPacketContext *packet)
205 SilcChannelEntry channel = NULL;
206 SilcChannelClientEntry chl;
207 SilcChannelID *id = NULL;
210 SILC_LOG_DEBUG(("Processing channel message"));
213 if (packet->dst_id_type != SILC_ID_CHANNEL) {
214 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
218 /* Find channel entry */
219 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
220 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
222 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
224 SILC_LOG_DEBUG(("Could not find channel"));
229 /* See that this client is on the channel. If the message is coming
230 from router we won't do the check as the message is from client that
231 we don't know about. Also, if the original sender is not client
232 (as it can be server as well) we don't do the check. */
233 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
234 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
235 packet->src_id_type == SILC_ID_CLIENT) {
236 silc_list_start(channel->user_list);
237 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
238 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
241 if (chl == SILC_LIST_END)
245 /* Distribute the packet to our local clients. This will send the
246 packet for further routing as well, if needed. */
247 silc_server_packet_relay_to_channel(server, sock, channel, sender,
249 packet->buffer->data,
250 packet->buffer->len, FALSE);
259 /* Received channel key packet. We distribute the key to all of our locally
260 connected clients on the channel. */
262 void silc_server_channel_key(SilcServer server,
263 SilcSocketConnection sock,
264 SilcPacketContext *packet)
266 SilcBuffer buffer = packet->buffer;
267 SilcChannelEntry channel;
269 if (packet->src_id_type != SILC_ID_SERVER)
272 /* Save the channel key */
273 channel = silc_server_save_channel_key(server, buffer, NULL);
277 /* Distribute the key to everybody who is on the channel. If we are router
278 we will also send it to locally connected servers. */
279 silc_server_send_channel_key(server, sock, channel, FALSE);
282 /* Received packet to replace a ID. This checks that the requested ID
283 exists and replaces it with the new one. */
285 void silc_server_replace_id(SilcServer server,
286 SilcSocketConnection sock,
287 SilcPacketContext *packet)
289 SilcBuffer buffer = packet->buffer;
290 unsigned char *old_id = NULL, *new_id = NULL;
291 SilcIdType old_id_type, new_id_type;
292 unsigned short old_id_len, new_id_len;
293 void *id = NULL, *id2 = NULL;
295 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
296 packet->src_id_type == SILC_ID_CLIENT)
299 SILC_LOG_DEBUG(("Replacing ID"));
301 silc_buffer_unformat(buffer,
302 SILC_STR_UI_SHORT(&old_id_type),
303 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
304 SILC_STR_UI_SHORT(&new_id_type),
305 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
308 if (old_id_type != new_id_type)
311 if (old_id_len != silc_id_get_len(old_id_type) ||
312 new_id_len != silc_id_get_len(new_id_type))
315 id = silc_id_str2id(old_id, old_id_type);
319 id2 = silc_id_str2id(new_id, new_id_type);
323 /* If we are router and this packet is not already broadcast packet
324 we will broadcast it. The sending socket really cannot be router or
325 the router is buggy. If this packet is coming from router then it must
326 have the broadcast flag set already and we won't do anything. */
327 if (!server->standalone && server->server_type == SILC_ROUTER &&
328 sock->type == SILC_SOCKET_TYPE_SERVER &&
329 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
330 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
331 silc_server_packet_send(server, server->router->connection, packet->type,
332 packet->flags | SILC_PACKET_FLAG_BROADCAST,
333 buffer->data, buffer->len, FALSE);
336 /* Replace the old ID */
337 switch(old_id_type) {
339 SILC_LOG_DEBUG(("Old Client ID id(%s)",
340 silc_id_render(id, SILC_ID_CLIENT)));
341 SILC_LOG_DEBUG(("New Client ID id(%s)",
342 silc_id_render(id2, SILC_ID_CLIENT)));
343 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
344 if (server->server_type == SILC_ROUTER)
345 silc_idlist_replace_client_id(server->global_list, id, id2);
349 SILC_LOG_DEBUG(("Old Server ID id(%s)",
350 silc_id_render(id, SILC_ID_CLIENT)));
351 SILC_LOG_DEBUG(("New Server ID id(%s)",
352 silc_id_render(id2, SILC_ID_CLIENT)));
353 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
354 if (server->server_type == SILC_ROUTER)
355 silc_idlist_replace_server_id(server->global_list, id, id2);
358 case SILC_ID_CHANNEL:
359 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
379 /* Received New Client packet and processes it. Creates Client ID for the
380 client. Client becomes registered after calling this functions. */
382 SilcClientEntry silc_server_new_client(SilcServer server,
383 SilcSocketConnection sock,
384 SilcPacketContext *packet)
386 SilcBuffer buffer = packet->buffer;
387 SilcClientEntry client;
388 SilcIDCacheEntry cache;
389 SilcClientID *client_id;
391 SilcIDListData idata;
392 char *username = NULL, *realname = NULL, *id_string;
394 SILC_LOG_DEBUG(("Creating new client"));
396 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
399 /* Take client entry */
400 client = (SilcClientEntry)sock->user_data;
401 idata = (SilcIDListData)client;
403 /* Fetch the old client cache entry so that we can update it. */
404 if (!silc_idcache_find_by_context(server->local_list->clients,
405 sock->user_data, &cache)) {
406 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
410 /* Parse incoming packet */
411 silc_buffer_unformat(buffer,
412 SILC_STR_UI16_STRING_ALLOC(&username),
413 SILC_STR_UI16_STRING_ALLOC(&realname),
416 /* Create Client ID */
417 silc_id_create_client_id(server->id, server->rng, server->md5hash,
418 username, &client_id);
420 /* Update client entry */
421 idata->registered = TRUE;
422 client->nickname = strdup(username);
423 client->username = username;
424 client->userinfo = realname;
425 client->id = client_id;
427 /* Update the cache entry */
428 cache->id = (void *)client_id;
429 cache->type = SILC_ID_CLIENT;
430 cache->data = username;
431 silc_idcache_sort_by_data(server->local_list->clients);
433 /* Notify our router about new client on the SILC network */
434 if (!server->standalone)
435 silc_server_send_new_id(server, (SilcSocketConnection)
436 server->router->connection,
437 server->server_type == SILC_ROUTER ? TRUE : FALSE,
438 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
440 /* Send the new client ID to the client. */
441 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
442 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
443 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
444 silc_buffer_format(reply,
445 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
446 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
447 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
449 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
450 reply->data, reply->len, FALSE);
451 silc_free(id_string);
452 silc_buffer_free(reply);
454 /* Send some nice info to the client */
455 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
456 ("Welcome to the SILC Network %s@%s",
457 username, sock->hostname));
458 if (server->server_type == SILC_ROUTER) {
459 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
460 ("There are %d clients on %d servers in SILC "
461 "Network", server->stat.clients,
462 server->stat.servers));
463 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
464 ("There are %d clients on %d server in our cell",
465 server->stat.cell_clients,
466 server->stat.cell_servers));
467 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
468 ("I have %d clients, %d channels, %d servers and "
470 server->stat.my_clients,
471 server->stat.my_channels,
472 server->stat.my_servers,
473 server->stat.my_routers));
474 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
475 ("%d server operators and %d router operators "
477 server->stat.my_server_ops,
478 server->stat.my_router_ops));
480 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
481 ("I have %d clients and %d channels formed",
482 server->stat.my_clients,
483 server->stat.my_channels));
484 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
485 ("%d operators online",
486 server->stat.my_server_ops));
488 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
489 ("Your host is %s, running version %s",
490 server->config->server_info->server_name,
492 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
493 ("Your connection is secured with %s cipher, "
494 "key length %d bits",
495 idata->send_key->cipher->name,
496 idata->send_key->cipher->key_len));
497 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
498 ("Your current nickname is %s",
502 silc_server_send_motd(server, sock);
507 /* Create new server. This processes received New Server packet and
508 saves the received Server ID. The server is our locally connected
509 server thus we save all the information and save it to local list.
510 This funtion can be used by both normal server and router server.
511 If normal server uses this it means that its router has connected
512 to the server. If router uses this it means that one of the cell's
513 servers is connected to the router. */
515 SilcServerEntry silc_server_new_server(SilcServer server,
516 SilcSocketConnection sock,
517 SilcPacketContext *packet)
519 SilcBuffer buffer = packet->buffer;
520 SilcServerEntry new_server;
521 SilcIDCacheEntry cache;
522 SilcServerID *server_id;
523 SilcIDListData idata;
524 unsigned char *server_name, *id_string;
525 unsigned short id_len;
527 SILC_LOG_DEBUG(("Creating new server"));
529 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
530 sock->type != SILC_SOCKET_TYPE_ROUTER)
533 /* Take server entry */
534 new_server = (SilcServerEntry)sock->user_data;
535 idata = (SilcIDListData)new_server;
537 /* Fetch the old server cache entry so that we can update it. */
538 if (!silc_idcache_find_by_context(server->local_list->servers,
539 sock->user_data, &cache)) {
540 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
544 /* Parse the incoming packet */
545 silc_buffer_unformat(buffer,
546 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
547 SILC_STR_UI16_STRING_ALLOC(&server_name),
550 if (id_len > buffer->len) {
551 silc_free(id_string);
552 silc_free(server_name);
557 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
558 silc_free(id_string);
560 /* Update client entry */
561 idata->registered = TRUE;
562 new_server->server_name = server_name;
563 new_server->id = server_id;
565 /* Update the cache entry */
566 cache->id = (void *)server_id;
567 cache->type = SILC_ID_SERVER;
568 cache->data = server_name;
569 silc_idcache_sort_by_data(server->local_list->servers);
571 /* Distribute the information about new server in the SILC network
572 to our router. If we are normal server we won't send anything
573 since this connection must be our router connection. */
574 if (server->server_type == SILC_ROUTER && !server->standalone &&
575 server->router->connection != sock)
576 silc_server_send_new_id(server, server->router->connection,
577 TRUE, new_server->id, SILC_ID_SERVER,
583 /* Processes incoming New ID packet. New ID Payload is used to distribute
584 information about newly registered clients and servers. */
586 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
587 SilcPacketContext *packet)
589 SilcBuffer buffer = packet->buffer;
591 SilcServerEntry router;
592 SilcSocketConnection router_sock;
595 unsigned char *hash = NULL;
598 SILC_LOG_DEBUG(("Processing new ID"));
600 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
601 server->server_type == SILC_SERVER ||
602 packet->src_id_type != SILC_ID_SERVER)
605 idp = silc_id_payload_parse(buffer);
609 id_type = silc_id_payload_get_type(idp);
611 /* Normal server cannot have other normal server connections */
612 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
615 id = silc_id_payload_get_id(idp);
619 /* If the sender of this packet is server and we are router we need to
620 broadcast this packet to other routers in the network. */
621 if (!server->standalone && server->server_type == SILC_ROUTER &&
622 sock->type == SILC_SOCKET_TYPE_SERVER &&
623 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
624 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
625 silc_server_packet_send(server, server->router->connection,
627 packet->flags | SILC_PACKET_FLAG_BROADCAST,
628 buffer->data, buffer->len, FALSE);
631 if (sock->type == SILC_SOCKET_TYPE_SERVER)
632 id_list = server->local_list;
634 id_list = server->global_list;
637 router = sock->user_data;
642 SilcClientEntry entry;
644 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
645 silc_id_render(id, SILC_ID_CLIENT),
646 sock->type == SILC_SOCKET_TYPE_SERVER ?
647 "Server" : "Router", sock->hostname));
649 /* As a router we keep information of all global information in our
650 global list. Cell wide information however is kept in the local
651 list. The client is put to global list and we will take the hash
652 value of the Client ID and save it to the ID Cache system for fast
653 searching in the future. */
654 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
655 sizeof(unsigned char));
656 memcpy(hash, ((SilcClientID *)id)->hash,
657 sizeof(((SilcClientID *)id)->hash));
658 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
659 router, router_sock);
660 entry->nickname = NULL;
662 if (sock->type == SILC_SOCKET_TYPE_SERVER)
663 server->stat.cell_clients++;
664 server->stat.clients++;
667 /* XXX Adding two ID's with same IP number replaces the old entry thus
668 gives wrong route. Thus, now disabled until figured out a better way
669 to do this or when removed the whole thing. This could be removed
670 because entry->router->connection gives always the most optimal route
671 for the ID anyway (unless new routes (faster perhaps) are established
672 after receiving this ID, this we don't know however). */
673 /* Add route cache for this ID */
674 silc_server_route_add(silc_server_route_hash(
675 ((SilcClientID *)id)->ip.s_addr,
676 server->id->port), ((SilcClientID *)id)->ip.s_addr,
683 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
684 silc_id_render(id, SILC_ID_SERVER),
685 sock->type == SILC_SOCKET_TYPE_SERVER ?
686 "Server" : "Router", sock->hostname));
688 /* As a router we keep information of all global information in our global
689 list. Cell wide information however is kept in the local list. */
690 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
692 if (sock->type == SILC_SOCKET_TYPE_SERVER)
693 server->stat.cell_servers++;
694 server->stat.servers++;
697 /* Add route cache for this ID */
698 silc_server_route_add(silc_server_route_hash(
699 ((SilcServerID *)id)->ip.s_addr,
700 ((SilcServerID *)id)->port),
701 ((SilcServerID *)id)->ip.s_addr,
706 case SILC_ID_CHANNEL:
707 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
715 silc_id_payload_free(idp);
718 /* Received Remove Channel User packet to remove a user from a channel.
719 Routers notify other routers that user has left a channel. Client must
720 not send this packet. Normal server may send this packet but must not
723 void silc_server_remove_channel_user(SilcServer server,
724 SilcSocketConnection sock,
725 SilcPacketContext *packet)
727 SilcBuffer buffer = packet->buffer;
728 unsigned char *tmp1 = NULL, *tmp2 = NULL;
729 SilcClientID *client_id = NULL;
730 SilcChannelID *channel_id = NULL;
731 SilcChannelEntry channel;
732 SilcClientEntry client;
734 SILC_LOG_DEBUG(("Removing user from channel"));
736 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
737 server->server_type == SILC_SERVER)
740 silc_buffer_unformat(buffer,
741 SILC_STR_UI16_STRING_ALLOC(&tmp1),
742 SILC_STR_UI16_STRING_ALLOC(&tmp2),
748 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
749 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
750 if (!client_id || !channel_id)
753 /* If we are router and this packet is not already broadcast packet
754 we will broadcast it. The sending socket really cannot be router or
755 the router is buggy. If this packet is coming from router then it must
756 have the broadcast flag set already and we won't do anything. */
757 if (!server->standalone && server->server_type == SILC_ROUTER &&
758 sock->type == SILC_SOCKET_TYPE_SERVER &&
759 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
760 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
761 silc_server_packet_send(server, server->router->connection, packet->type,
762 packet->flags | SILC_PACKET_FLAG_BROADCAST,
763 buffer->data, buffer->len, FALSE);
766 /* Get channel entry */
767 channel = silc_idlist_find_channel_by_id(server->local_list,
770 channel = silc_idlist_find_channel_by_id(server->global_list,
776 /* Get client entry */
777 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
779 client = silc_idlist_find_client_by_id(server->global_list,
785 /* Remove user from channel */
786 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
794 silc_free(client_id);
796 silc_free(channel_id);
799 /* Received New Channel packet. Information about new channels in the
800 network are distributed using this packet. Save the information about
803 void silc_server_new_channel(SilcServer server,
804 SilcSocketConnection sock,
805 SilcPacketContext *packet)
808 SilcChannelID *channel_id;
809 unsigned short channel_id_len;
812 SILC_LOG_DEBUG(("Processing New Channel"));
814 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
815 server->server_type == SILC_SERVER ||
816 packet->src_id_type != SILC_ID_SERVER)
820 if (!silc_buffer_unformat(packet->buffer,
821 SILC_STR_UI16_STRING_ALLOC(&channel_name),
822 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
826 if (!channel_name || !id)
829 /* Decode the channel ID */
830 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
835 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
836 silc_id_render(channel_id, SILC_ID_CHANNEL),
839 /* Add the new channel. Add it always to global list since if we receive
840 this packet then it cannot be created by ourselves but some other
841 router hence global channel. */
842 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
843 server->router->connection, NULL);
845 server->stat.channels++;
848 /* Received notify packet. Server can receive notify packets from router.
849 Server then relays the notify messages to clients if needed. */
851 void silc_server_notify(SilcServer server,
852 SilcSocketConnection sock,
853 SilcPacketContext *packet)
855 SilcNotifyPayload payload;
857 SilcArgumentPayload args;
858 SilcChannelID *channel_id;
859 SilcClientID *client_id;
860 SilcChannelEntry channel;
861 SilcClientEntry client;
863 unsigned int tmp_len;
865 SILC_LOG_DEBUG(("Start"));
867 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
868 packet->src_id_type != SILC_ID_SERVER)
871 /* XXX: For now we expect that the we are normal server and that the
872 sender is router. Server could send (protocol allows it) notify to
873 router but we don't support it yet. */
874 if (server->server_type != SILC_SERVER &&
875 sock->type != SILC_SOCKET_TYPE_ROUTER)
878 payload = silc_notify_payload_parse(packet->buffer);
882 type = silc_notify_get_type(payload);
883 args = silc_notify_get_args(payload);
888 case SILC_NOTIFY_TYPE_JOIN:
890 * Distribute the notify to local clients on the channel
892 SILC_LOG_DEBUG(("JOIN notify"));
894 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
898 /* Get channel entry */
899 channel = silc_idlist_find_channel_by_id(server->local_list,
902 silc_free(channel_id);
907 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
909 silc_free(channel_id);
912 client_id = silc_id_payload_parse_id(tmp, tmp_len);
914 /* Send to channel */
915 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
916 FALSE, packet->buffer->data,
917 packet->buffer->len, FALSE);
919 /* If the the client is not in local list we check global list (ie. the
920 channel will be global channel) and if it does not exist then create
921 entry for the client. */
922 client = silc_idlist_find_client_by_id(server->local_list,
925 SilcChannelClientEntry chl;
927 client = silc_idlist_find_client_by_id(server->global_list,
930 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
931 client_id, sock->user_data, sock);
933 /* The channel is global now */
934 channel->global_users = TRUE;
936 /* Now actually JOIN the global client to the channel */
937 chl = silc_calloc(1, sizeof(*chl));
938 chl->client = client;
939 chl->channel = channel;
940 silc_list_add(channel->user_list, chl);
941 silc_list_add(client->channels, chl);
943 silc_free(client_id);
947 case SILC_NOTIFY_TYPE_LEAVE:
949 * Distribute the notify to local clients on the channel
951 SILC_LOG_DEBUG(("LEAVE notify"));
953 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
957 /* Get channel entry */
958 channel = silc_idlist_find_channel_by_id(server->local_list,
961 silc_free(channel_id);
966 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
968 silc_free(channel_id);
971 client_id = silc_id_payload_parse_id(tmp, tmp_len);
973 /* Send to channel */
974 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
975 FALSE, packet->buffer->data,
976 packet->buffer->len, FALSE);
978 /* Get client entry */
979 client = silc_idlist_find_client_by_id(server->global_list,
982 client = silc_idlist_find_client_by_id(server->local_list,
985 silc_free(channel_id);
989 silc_free(client_id);
991 /* Remove the user from channel */
992 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
995 case SILC_NOTIFY_TYPE_SIGNOFF:
997 * Distribute the notify to local clients on the channel
999 SILC_LOG_DEBUG(("SIGNOFF notify"));
1002 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1005 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1007 /* Get client entry */
1008 client = silc_idlist_find_client_by_id(server->global_list,
1011 client = silc_idlist_find_client_by_id(server->local_list,
1016 silc_free(client_id);
1018 /* Remove the client from all channels */
1019 silc_server_remove_from_channels(server, NULL, client);
1021 /* Remove the client entry */
1022 silc_idlist_del_client(server->global_list, client);
1025 /* Ignore rest notify types for now */
1026 case SILC_NOTIFY_TYPE_NONE:
1027 case SILC_NOTIFY_TYPE_INVITE:
1028 case SILC_NOTIFY_TYPE_TOPIC_SET:
1029 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1030 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1031 case SILC_NOTIFY_TYPE_MOTD:
1037 silc_notify_payload_free(payload);
1040 /* Received new channel user packet. Information about new users on a
1041 channel are distributed between routers using this packet. The
1042 router receiving this will redistribute it and also sent JOIN notify
1043 to local clients on the same channel. Normal server sends JOIN notify
1044 to its local clients on the channel. */
1046 void silc_server_new_channel_user(SilcServer server,
1047 SilcSocketConnection sock,
1048 SilcPacketContext *packet)
1050 unsigned char *tmpid1, *tmpid2;
1051 SilcClientID *client_id = NULL;
1052 SilcChannelID *channel_id = NULL;
1053 unsigned short channel_id_len;
1054 unsigned short client_id_len;
1055 SilcClientEntry client;
1056 SilcChannelEntry channel;
1057 SilcChannelClientEntry chl;
1060 SILC_LOG_DEBUG(("Start"));
1062 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1063 server->server_type != SILC_ROUTER ||
1064 packet->src_id_type != SILC_ID_SERVER)
1068 if (!silc_buffer_unformat(packet->buffer,
1069 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1071 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1076 if (!tmpid1 || !tmpid2)
1079 /* Decode the channel ID */
1080 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
1084 /* Decode the client ID */
1085 client_id = silc_id_str2id(tmpid2, SILC_ID_CLIENT);
1089 /* Find the channel */
1090 channel = silc_idlist_find_channel_by_id(server->local_list,
1093 channel = silc_idlist_find_channel_by_id(server->global_list,
1099 /* If we are router and this packet is not already broadcast packet
1100 we will broadcast it. */
1101 if (!server->standalone && server->server_type == SILC_ROUTER &&
1102 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1103 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1104 silc_server_packet_send(server, server->router->connection, packet->type,
1105 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1106 packet->buffer->data, packet->buffer->len, FALSE);
1109 /* Get client entry */
1110 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1112 client = silc_idlist_find_client_by_id(server->global_list,
1118 /* Join the client to the channel by adding it to channel's user list.
1119 Add also the channel to client entry's channels list for fast cross-
1121 chl = silc_calloc(1, sizeof(*chl));
1122 chl->client = client;
1123 chl->channel = channel;
1124 silc_list_add(channel->user_list, chl);
1125 silc_list_add(client->channels, chl);
1127 server->stat.chanclients++;
1129 /* Send JOIN notify to local clients on the channel. As we are router
1130 it is assured that this is sent only to our local clients and locally
1131 connected servers if needed. */
1132 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1133 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1134 SILC_NOTIFY_TYPE_JOIN,
1135 1, clidp->data, clidp->len);
1136 silc_buffer_free(clidp);
1142 silc_free(client_id);
1144 silc_free(channel_id);
1149 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1150 that certain ID should be removed. After that the ID will become invalid. */
1152 void silc_server_remove_id(SilcServer server,
1153 SilcSocketConnection sock,
1154 SilcPacketContext *packet)
1159 void *id, *id_entry;
1161 SILC_LOG_DEBUG(("Start"));
1163 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1164 server->server_type == SILC_SERVER ||
1165 packet->src_id_type != SILC_ID_SERVER)
1168 idp = silc_id_payload_parse(packet->buffer);
1172 id_type = silc_id_payload_get_type(idp);
1174 id = silc_id_payload_get_id(idp);
1178 /* If the sender of this packet is server and we are router we need to
1179 broadcast this packet to other routers in the network. */
1180 if (!server->standalone && server->server_type == SILC_ROUTER &&
1181 sock->type == SILC_SOCKET_TYPE_SERVER &&
1182 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1183 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1184 silc_server_packet_send(server, server->router->connection,
1186 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1187 packet->buffer->data, packet->buffer->len, FALSE);
1190 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1191 id_list = server->local_list;
1193 id_list = server->global_list;
1197 case SILC_ID_CLIENT:
1198 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1201 /* Remove from channels */
1202 silc_server_remove_from_channels(server, NULL, id_entry);
1204 /* Remove the client entry */
1205 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1206 server->stat.clients--;
1208 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1209 silc_id_render(id, SILC_ID_CLIENT),
1210 sock->type == SILC_SOCKET_TYPE_SERVER ?
1211 "Server" : "Router", sock->hostname));
1215 case SILC_ID_SERVER:
1216 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1219 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1220 server->stat.servers--;
1222 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1223 silc_id_render(id, SILC_ID_SERVER),
1224 sock->type == SILC_SOCKET_TYPE_SERVER ?
1225 "Server" : "Router", sock->hostname));
1229 case SILC_ID_CHANNEL:
1230 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1233 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1234 server->stat.channels--;
1236 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1237 silc_id_render(id, SILC_ID_CHANNEL),
1238 sock->type == SILC_SOCKET_TYPE_SERVER ?
1239 "Server" : "Router", sock->hostname));
1248 silc_id_payload_free(idp);