5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 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 notify packet. Server can receive notify packets from router.
31 Server then relays the notify messages to clients if needed. */
33 void silc_server_notify(SilcServer server,
34 SilcSocketConnection sock,
35 SilcPacketContext *packet)
37 SilcNotifyPayload payload;
39 SilcArgumentPayload args;
40 SilcChannelID *channel_id;
41 SilcClientID *client_id, *client_id2;
42 SilcChannelEntry channel;
43 SilcClientEntry client;
44 SilcChannelClientEntry chl;
49 SILC_LOG_DEBUG(("Start"));
51 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
52 packet->src_id_type != SILC_ID_SERVER)
55 /* If we are router and this packet is not already broadcast packet
56 we will broadcast it. The sending socket really cannot be router or
57 the router is buggy. If this packet is coming from router then it must
58 have the broadcast flag set already and we won't do anything. */
59 if (!server->standalone && server->server_type == SILC_ROUTER &&
60 sock->type == SILC_SOCKET_TYPE_SERVER &&
61 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
62 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
63 silc_server_packet_send(server, server->router->connection, packet->type,
64 packet->flags | SILC_PACKET_FLAG_BROADCAST,
65 packet->buffer->data, packet->buffer->len, FALSE);
68 payload = silc_notify_payload_parse(packet->buffer);
72 type = silc_notify_get_type(payload);
73 args = silc_notify_get_args(payload);
78 case SILC_NOTIFY_TYPE_JOIN:
80 * Distribute the notify to local clients on the channel
82 SILC_LOG_DEBUG(("JOIN notify"));
85 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
88 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
92 /* Get channel entry */
93 channel = silc_idlist_find_channel_by_id(server->local_list,
96 channel = silc_idlist_find_channel_by_id(server->global_list,
99 silc_free(channel_id);
103 silc_free(channel_id);
106 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
109 client_id = silc_id_payload_parse_id(tmp, tmp_len);
113 /* Send to channel */
114 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
115 FALSE, packet->buffer->data,
116 packet->buffer->len, FALSE);
118 /* If the the client is not in local list we check global list (ie. the
119 channel will be global channel) and if it does not exist then create
120 entry for the client. */
121 client = silc_idlist_find_client_by_id(server->local_list,
124 client = silc_idlist_find_client_by_id(server->global_list,
127 /* If router did not find the client the it is bogus */
128 if (server->server_type == SILC_ROUTER)
132 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
133 silc_id_dup(client_id, SILC_ID_CLIENT),
134 sock->user_data, NULL);
136 silc_free(client_id);
142 /* Do not add client to channel if it is there already */
143 if (silc_server_client_on_channel(client, channel))
146 if (server->server_type == SILC_SERVER &&
147 sock->type == SILC_SOCKET_TYPE_ROUTER)
148 /* The channel is global now */
149 channel->global_users = TRUE;
151 /* JOIN the global client to the channel (local clients (if router
152 created the channel) is joined in the pending JOIN command). */
153 chl = silc_calloc(1, sizeof(*chl));
154 chl->client = client;
155 chl->channel = channel;
156 silc_list_add(channel->user_list, chl);
157 silc_list_add(client->channels, chl);
158 silc_free(client_id);
162 case SILC_NOTIFY_TYPE_LEAVE:
164 * Distribute the notify to local clients on the channel
166 SILC_LOG_DEBUG(("LEAVE notify"));
168 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
169 packet->dst_id_type);
173 /* Get channel entry */
174 channel = silc_idlist_find_channel_by_id(server->local_list,
177 silc_free(channel_id);
182 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
184 silc_free(channel_id);
187 client_id = silc_id_payload_parse_id(tmp, tmp_len);
189 silc_free(channel_id);
193 /* Send to channel */
194 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
195 FALSE, packet->buffer->data,
196 packet->buffer->len, FALSE);
198 /* Get client entry */
199 client = silc_idlist_find_client_by_id(server->global_list,
202 client = silc_idlist_find_client_by_id(server->local_list,
205 silc_free(client_id);
206 silc_free(channel_id);
210 silc_free(client_id);
212 /* Remove the user from channel */
213 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
216 case SILC_NOTIFY_TYPE_SIGNOFF:
218 * Distribute the notify to local clients on the channel
220 SILC_LOG_DEBUG(("SIGNOFF notify"));
223 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
226 client_id = silc_id_payload_parse_id(tmp, tmp_len);
230 /* Get client entry */
231 client = silc_idlist_find_client_by_id(server->global_list,
234 client = silc_idlist_find_client_by_id(server->local_list,
237 silc_free(client_id);
241 silc_free(client_id);
243 /* Get signoff message */
244 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
248 /* Remove the client from all channels */
249 silc_server_remove_from_channels(server, NULL, client, tmp);
251 /* Remove the client entry */
252 if (!silc_idlist_del_client(server->global_list, client))
253 silc_idlist_del_client(server->local_list, client);
256 case SILC_NOTIFY_TYPE_TOPIC_SET:
258 * Distribute the notify to local clients on the channel
261 SILC_LOG_DEBUG(("TOPIC SET notify"));
263 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
264 packet->dst_id_type);
268 /* Get channel entry */
269 channel = silc_idlist_find_channel_by_id(server->local_list,
272 channel = silc_idlist_find_channel_by_id(server->global_list,
275 silc_free(channel_id);
281 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
283 silc_free(channel_id);
288 silc_free(channel->topic);
289 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
290 memcpy(channel->topic, tmp, tmp_len);
292 /* Send the same notify to the channel */
293 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
294 FALSE, packet->buffer->data,
295 packet->buffer->len, FALSE);
296 silc_free(channel_id);
299 case SILC_NOTIFY_TYPE_NICK_CHANGE:
302 * Distribute the notify to local clients on the channel
304 unsigned char *id, *id2;
306 SILC_LOG_DEBUG(("NICK CHANGE notify"));
308 /* Get old client ID */
309 id = silc_argument_get_arg_type(args, 1, &tmp_len);
312 client_id = silc_id_payload_parse_id(id, tmp_len);
316 /* Get new client ID */
317 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
320 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
324 SILC_LOG_DEBUG(("Old Client ID id(%s)",
325 silc_id_render(client_id, SILC_ID_CLIENT)));
326 SILC_LOG_DEBUG(("New Client ID id(%s)",
327 silc_id_render(client_id2, SILC_ID_CLIENT)));
329 /* Replace the Client ID */
330 client = silc_idlist_replace_client_id(server->global_list, client_id,
333 client = silc_idlist_replace_client_id(server->local_list, client_id,
337 /* The nickname is not valid anymore, set it NULL. This causes that
338 the nickname will be queried if someone wants to know it. */
339 if (client->nickname)
340 silc_free(client->nickname);
341 client->nickname = NULL;
343 /* Send the NICK_CHANGE notify type to local clients on the channels
344 this client is joined to. */
345 silc_server_send_notify_on_channels(server, client,
346 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
351 silc_free(client_id);
353 silc_free(client_id2);
357 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
359 * Distribute the notify to local clients on the channel
362 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
364 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
365 packet->dst_id_type);
369 /* Get channel entry */
370 channel = silc_idlist_find_channel_by_id(server->local_list,
373 channel = silc_idlist_find_channel_by_id(server->global_list,
376 silc_free(channel_id);
381 /* Send the same notify to the channel */
382 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
383 FALSE, packet->buffer->data,
384 packet->buffer->len, FALSE);
387 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
389 silc_free(channel_id);
393 SILC_GET32_MSB(mode, tmp);
396 channel->mode = mode;
397 silc_free(channel_id);
400 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
402 * Distribute the notify to local clients on the channel
405 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
407 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
408 packet->dst_id_type);
412 /* Get channel entry */
413 channel = silc_idlist_find_channel_by_id(server->local_list,
416 channel = silc_idlist_find_channel_by_id(server->global_list,
419 silc_free(channel_id);
425 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
427 silc_free(channel_id);
431 SILC_GET32_MSB(mode, tmp);
433 /* Get target client */
434 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
437 client_id = silc_id_payload_parse_id(tmp, tmp_len);
441 /* Get client entry */
442 client = silc_idlist_find_client_by_id(server->global_list,
445 client = silc_idlist_find_client_by_id(server->local_list,
448 silc_free(client_id);
452 silc_free(client_id);
454 /* Get entry to the channel user list */
455 silc_list_start(channel->user_list);
456 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
457 if (chl->client == client) {
458 /* Change the mode */
463 /* Send the same notify to the channel */
464 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
465 FALSE, packet->buffer->data,
466 packet->buffer->len, FALSE);
467 silc_free(channel_id);
470 case SILC_NOTIFY_TYPE_INVITE:
471 SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
474 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
475 SILC_LOG_DEBUG(("CHANNEL CHANGE notify (not-impl XXX)"));
478 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
479 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
482 /* Ignore rest of the notify types for now */
483 case SILC_NOTIFY_TYPE_NONE:
484 case SILC_NOTIFY_TYPE_MOTD:
491 silc_notify_payload_free(payload);
494 void silc_server_notify_list(SilcServer server,
495 SilcSocketConnection sock,
496 SilcPacketContext *packet)
498 SilcPacketContext *new;
502 SILC_LOG_DEBUG(("Processing New Notify List"));
504 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
505 packet->src_id_type != SILC_ID_SERVER)
508 /* Make copy of the original packet context, except for the actual
509 data buffer, which we will here now fetch from the original buffer. */
510 new = silc_packet_context_alloc();
511 new->type = SILC_PACKET_NOTIFY;
512 new->flags = packet->flags;
513 new->src_id = packet->src_id;
514 new->src_id_len = packet->src_id_len;
515 new->src_id_type = packet->src_id_type;
516 new->dst_id = packet->dst_id;
517 new->dst_id_len = packet->dst_id_len;
518 new->dst_id_type = packet->dst_id_type;
520 buffer = silc_buffer_alloc(1024);
521 new->buffer = buffer;
523 while (packet->buffer->len) {
524 SILC_GET16_MSB(len, packet->buffer->data + 2);
525 if (len > packet->buffer->len)
528 if (len > buffer->truelen) {
529 silc_buffer_free(buffer);
530 buffer = silc_buffer_alloc(1024 + len);
533 silc_buffer_pull_tail(buffer, len);
534 silc_buffer_put(buffer, packet->buffer->data, len);
536 /* Process the Notify */
537 silc_server_notify(server, sock, new);
539 silc_buffer_push_tail(buffer, len);
540 silc_buffer_pull(packet->buffer, len);
543 silc_buffer_free(buffer);
547 /* Received private message. This resolves the destination of the message
548 and sends the packet. This is used by both server and router. If the
549 destination is our locally connected client this sends the packet to
550 the client. This may also send the message for further routing if
551 the destination is not in our server (or router). */
553 void silc_server_private_message(SilcServer server,
554 SilcSocketConnection sock,
555 SilcPacketContext *packet)
558 SilcServerEntry router;
559 SilcSocketConnection dst_sock;
560 SilcClientEntry client;
561 SilcIDListData idata;
563 SILC_LOG_DEBUG(("Start"));
568 /* Decode destination Client ID */
569 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
571 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
575 /* If the destination belongs to our server we don't have to route
576 the message anywhere but to send it to the local destination. */
577 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
579 /* It exists, now deliver the message to the destination */
580 dst_sock = (SilcSocketConnection)client->connection;
582 /* If we are router and the client has router then the client is in
583 our cell but not directly connected to us. */
584 if (server->server_type == SILC_ROUTER && client->router) {
585 /* We are of course in this case the client's router thus the real
586 "router" of the client is the server who owns the client. Thus
587 we will send the packet to that server. */
588 router = (SilcServerEntry)client->router;
589 idata = (SilcIDListData)router;
591 silc_server_send_private_message(server, router->connection,
598 /* Seems that client really is directly connected to us */
599 idata = (SilcIDListData)client;
600 silc_server_send_private_message(server, dst_sock,
602 idata->hmac, packet);
606 /* Destination belongs to someone not in this server. If we are normal
607 server our action is to send the packet to our router. */
608 if (server->server_type == SILC_SERVER && !server->standalone) {
609 router = server->router;
611 /* Send to primary route */
613 dst_sock = (SilcSocketConnection)router->connection;
614 idata = (SilcIDListData)router;
615 silc_server_send_private_message(server, dst_sock,
617 idata->hmac, packet);
622 /* We are router and we will perform route lookup for the destination
623 and send the message to fastest route. */
624 if (server->server_type == SILC_ROUTER && !server->standalone) {
625 /* Check first that the ID is valid */
626 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
628 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
629 router = (SilcServerEntry)dst_sock->user_data;
630 idata = (SilcIDListData)router;
632 /* Get fastest route and send packet. */
634 silc_server_send_private_message(server, dst_sock,
636 idata->hmac, packet);
642 silc_server_send_error(server, sock,
643 "No such nickname: Private message not sent");
646 /* Processes incoming command reply packet. The command reply packet may
647 be destined to one of our clients or it may directly for us. We will
648 call the command reply routine after processing the packet. */
650 void silc_server_command_reply(SilcServer server,
651 SilcSocketConnection sock,
652 SilcPacketContext *packet)
654 SilcBuffer buffer = packet->buffer;
655 SilcClientEntry client = NULL;
656 SilcSocketConnection dst_sock;
657 SilcIDListData idata;
658 SilcClientID *id = NULL;
660 SILC_LOG_DEBUG(("Start"));
662 /* Source must be server or router */
663 if (packet->src_id_type != SILC_ID_SERVER &&
664 sock->type != SILC_SOCKET_TYPE_ROUTER)
667 if (packet->dst_id_type == SILC_ID_CHANNEL)
670 if (packet->dst_id_type == SILC_ID_CLIENT) {
671 /* Destination must be one of ours */
672 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
675 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
677 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
683 if (packet->dst_id_type == SILC_ID_SERVER) {
684 /* For now this must be for us */
685 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
686 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
691 /* Execute command reply locally for the command */
692 silc_server_command_reply_process(server, sock, buffer);
694 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
695 /* Relay the packet to the client */
697 dst_sock = (SilcSocketConnection)client->connection;
698 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
699 + packet->dst_id_len + packet->padlen);
701 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
702 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
704 idata = (SilcIDListData)client;
707 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
710 /* Send the packet */
711 silc_server_packet_send_real(server, dst_sock, TRUE);
717 /* Process received channel message. The message can be originated from
720 void silc_server_channel_message(SilcServer server,
721 SilcSocketConnection sock,
722 SilcPacketContext *packet)
724 SilcChannelEntry channel = NULL;
725 SilcChannelClientEntry chl;
726 SilcChannelID *id = NULL;
729 SILC_LOG_DEBUG(("Processing channel message"));
732 if (packet->dst_id_type != SILC_ID_CHANNEL) {
733 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
737 /* Find channel entry */
738 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
741 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
743 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
745 SILC_LOG_DEBUG(("Could not find channel"));
750 /* See that this client is on the channel. If the message is coming
751 from router we won't do the check as the message is from client that
752 we don't know about. Also, if the original sender is not client
753 (as it can be server as well) we don't do the check. */
754 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
755 packet->src_id_type);
758 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
759 packet->src_id_type == SILC_ID_CLIENT) {
760 silc_list_start(channel->user_list);
761 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
762 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
765 if (chl == SILC_LIST_END) {
766 SILC_LOG_DEBUG(("Client not on channel"));
771 /* Distribute the packet to our local clients. This will send the
772 packet for further routing as well, if needed. */
773 silc_server_packet_relay_to_channel(server, sock, channel, sender,
775 packet->buffer->data,
776 packet->buffer->len, FALSE);
785 /* Received channel key packet. We distribute the key to all of our locally
786 connected clients on the channel. */
788 void silc_server_channel_key(SilcServer server,
789 SilcSocketConnection sock,
790 SilcPacketContext *packet)
792 SilcBuffer buffer = packet->buffer;
793 SilcChannelEntry channel;
795 if (packet->src_id_type != SILC_ID_SERVER)
798 /* Save the channel key */
799 channel = silc_server_save_channel_key(server, buffer, NULL);
803 /* Distribute the key to everybody who is on the channel. If we are router
804 we will also send it to locally connected servers. */
805 silc_server_send_channel_key(server, sock, channel, FALSE);
808 /* Received New Client packet and processes it. Creates Client ID for the
809 client. Client becomes registered after calling this functions. */
811 SilcClientEntry silc_server_new_client(SilcServer server,
812 SilcSocketConnection sock,
813 SilcPacketContext *packet)
815 SilcBuffer buffer = packet->buffer;
816 SilcClientEntry client;
817 SilcIDCacheEntry cache;
818 SilcClientID *client_id;
820 SilcIDListData idata;
821 char *username = NULL, *realname = NULL, *id_string;
824 SILC_LOG_DEBUG(("Creating new client"));
826 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
829 /* Take client entry */
830 client = (SilcClientEntry)sock->user_data;
831 idata = (SilcIDListData)client;
833 /* Fetch the old client cache entry so that we can update it. */
834 if (!silc_idcache_find_by_context(server->local_list->clients,
835 sock->user_data, &cache)) {
836 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
840 /* Parse incoming packet */
841 ret = silc_buffer_unformat(buffer,
842 SILC_STR_UI16_STRING_ALLOC(&username),
843 SILC_STR_UI16_STRING_ALLOC(&realname),
857 silc_server_disconnect_remote(server, sock, "Server closed connection: "
858 "Incomplete client information");
862 /* Create Client ID */
863 silc_id_create_client_id(server->id, server->rng, server->md5hash,
864 username, &client_id);
866 /* Update client entry */
867 idata->registered = TRUE;
868 client->nickname = strdup(username);
869 client->username = username;
870 client->userinfo = realname ? realname : strdup("");
871 client->id = client_id;
873 /* Update the cache entry */
874 cache->id = (void *)client_id;
875 cache->type = SILC_ID_CLIENT;
876 cache->data = username;
877 silc_idcache_sort_by_data(server->local_list->clients);
879 /* Notify our router about new client on the SILC network */
880 if (!server->standalone)
881 silc_server_send_new_id(server, (SilcSocketConnection)
882 server->router->connection,
883 server->server_type == SILC_ROUTER ? TRUE : FALSE,
884 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
886 /* Send the new client ID to the client. */
887 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
888 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
889 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
890 silc_buffer_format(reply,
891 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
892 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
893 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
895 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
896 reply->data, reply->len, FALSE);
897 silc_free(id_string);
898 silc_buffer_free(reply);
900 /* Send some nice info to the client */
901 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
902 ("Welcome to the SILC Network %s@%s",
903 username, sock->hostname));
904 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
905 ("Your host is %s, running version %s",
906 server->config->server_info->server_name,
908 if (server->server_type == SILC_ROUTER) {
909 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
910 ("There are %d clients on %d servers in SILC "
911 "Network", server->stat.clients,
912 server->stat.servers + 1));
913 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
914 ("There are %d clients on %d server in our cell",
915 server->stat.cell_clients,
916 server->stat.cell_servers + 1));
917 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
918 ("I have %d clients, %d channels, %d servers and "
920 server->stat.my_clients,
921 server->stat.my_channels,
922 server->stat.my_servers,
923 server->stat.my_routers));
924 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
925 ("%d server operators and %d router operators "
927 server->stat.my_server_ops,
928 server->stat.my_router_ops));
930 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
931 ("I have %d clients and %d channels formed",
932 server->stat.my_clients,
933 server->stat.my_channels));
934 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
935 ("%d operators online",
936 server->stat.my_server_ops));
938 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
939 ("Your connection is secured with %s cipher, "
940 "key length %d bits",
941 idata->send_key->cipher->name,
942 idata->send_key->cipher->key_len));
943 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
944 ("Your current nickname is %s",
948 silc_server_send_motd(server, sock);
953 /* Create new server. This processes received New Server packet and
954 saves the received Server ID. The server is our locally connected
955 server thus we save all the information and save it to local list.
956 This funtion can be used by both normal server and router server.
957 If normal server uses this it means that its router has connected
958 to the server. If router uses this it means that one of the cell's
959 servers is connected to the router. */
961 SilcServerEntry silc_server_new_server(SilcServer server,
962 SilcSocketConnection sock,
963 SilcPacketContext *packet)
965 SilcBuffer buffer = packet->buffer;
966 SilcServerEntry new_server;
967 SilcIDCacheEntry cache;
968 SilcServerID *server_id;
969 SilcIDListData idata;
970 unsigned char *server_name, *id_string;
971 unsigned short id_len;
974 SILC_LOG_DEBUG(("Creating new server"));
976 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
977 sock->type != SILC_SOCKET_TYPE_ROUTER)
980 /* Take server entry */
981 new_server = (SilcServerEntry)sock->user_data;
982 idata = (SilcIDListData)new_server;
984 /* Fetch the old server cache entry so that we can update it. */
985 if (!silc_idcache_find_by_context(server->local_list->servers,
986 sock->user_data, &cache)) {
987 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
991 /* Parse the incoming packet */
992 ret = silc_buffer_unformat(buffer,
993 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
994 SILC_STR_UI16_STRING_ALLOC(&server_name),
998 silc_free(id_string);
1000 silc_free(server_name);
1004 if (id_len > buffer->len) {
1005 silc_free(id_string);
1006 silc_free(server_name);
1011 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1013 silc_free(id_string);
1014 silc_free(server_name);
1017 silc_free(id_string);
1019 /* Update client entry */
1020 idata->registered = TRUE;
1021 new_server->server_name = server_name;
1022 new_server->id = server_id;
1024 /* Update the cache entry */
1025 cache->id = (void *)server_id;
1026 cache->type = SILC_ID_SERVER;
1027 cache->data = server_name;
1028 silc_idcache_sort_by_data(server->local_list->servers);
1030 /* Distribute the information about new server in the SILC network
1031 to our router. If we are normal server we won't send anything
1032 since this connection must be our router connection. */
1033 if (server->server_type == SILC_ROUTER && !server->standalone &&
1034 server->router->connection != sock)
1035 silc_server_send_new_id(server, server->router->connection,
1036 TRUE, new_server->id, SILC_ID_SERVER,
1037 SILC_ID_SERVER_LEN);
1039 if (server->server_type == SILC_ROUTER)
1040 server->stat.cell_servers++;
1045 /* Processes incoming New ID packet. New ID Payload is used to distribute
1046 information about newly registered clients and servers. */
1048 static void silc_server_new_id_real(SilcServer server,
1049 SilcSocketConnection sock,
1050 SilcPacketContext *packet,
1053 SilcBuffer buffer = packet->buffer;
1055 SilcServerEntry router;
1056 SilcSocketConnection router_sock;
1059 unsigned char *hash = NULL;
1062 SILC_LOG_DEBUG(("Processing new ID"));
1064 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1065 server->server_type == SILC_SERVER ||
1066 packet->src_id_type != SILC_ID_SERVER)
1069 idp = silc_id_payload_parse(buffer);
1073 id_type = silc_id_payload_get_type(idp);
1075 /* Normal server cannot have other normal server connections */
1076 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1079 id = silc_id_payload_get_id(idp);
1083 /* If the sender of this packet is server and we are router we need to
1084 broadcast this packet to other routers in the network. */
1085 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1086 sock->type == SILC_SOCKET_TYPE_SERVER &&
1087 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1088 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1089 silc_server_packet_send(server, server->router->connection,
1091 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1092 buffer->data, buffer->len, FALSE);
1095 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1096 id_list = server->local_list;
1098 id_list = server->global_list;
1101 router = sock->user_data;
1104 case SILC_ID_CLIENT:
1106 SilcClientEntry entry;
1108 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1109 silc_id_render(id, SILC_ID_CLIENT),
1110 sock->type == SILC_SOCKET_TYPE_SERVER ?
1111 "Server" : "Router", sock->hostname));
1113 /* As a router we keep information of all global information in our
1114 global list. Cell wide information however is kept in the local
1115 list. The client is put to global list and we will take the hash
1116 value of the Client ID and save it to the ID Cache system for fast
1117 searching in the future. */
1118 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1119 sizeof(unsigned char));
1120 memcpy(hash, ((SilcClientID *)id)->hash,
1121 sizeof(((SilcClientID *)id)->hash));
1122 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
1124 entry->nickname = NULL;
1126 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1127 server->stat.cell_clients++;
1128 server->stat.clients++;
1131 /* XXX Adding two ID's with same IP number replaces the old entry thus
1132 gives wrong route. Thus, now disabled until figured out a better way
1133 to do this or when removed the whole thing. This could be removed
1134 because entry->router->connection gives always the most optimal route
1135 for the ID anyway (unless new routes (faster perhaps) are established
1136 after receiving this ID, this we don't know however). */
1137 /* Add route cache for this ID */
1138 silc_server_route_add(silc_server_route_hash(
1139 ((SilcClientID *)id)->ip.s_addr,
1140 server->id->port), ((SilcClientID *)id)->ip.s_addr,
1146 case SILC_ID_SERVER:
1147 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1148 silc_id_render(id, SILC_ID_SERVER),
1149 sock->type == SILC_SOCKET_TYPE_SERVER ?
1150 "Server" : "Router", sock->hostname));
1152 /* As a router we keep information of all global information in our global
1153 list. Cell wide information however is kept in the local list. */
1154 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1156 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1157 server->stat.cell_servers++;
1158 server->stat.servers++;
1161 /* Add route cache for this ID */
1162 silc_server_route_add(silc_server_route_hash(
1163 ((SilcServerID *)id)->ip.s_addr,
1164 ((SilcServerID *)id)->port),
1165 ((SilcServerID *)id)->ip.s_addr,
1170 case SILC_ID_CHANNEL:
1171 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1179 silc_id_payload_free(idp);
1183 /* Processes incoming New ID packet. New ID Payload is used to distribute
1184 information about newly registered clients and servers. */
1186 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1187 SilcPacketContext *packet)
1189 silc_server_new_id_real(server, sock, packet, TRUE);
1192 /* Receoved New Id List packet, list of New ID payloads inside one
1193 packet. Process the New ID payloads one by one. */
1195 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1196 SilcPacketContext *packet)
1198 SilcPacketContext *new_id;
1200 unsigned short id_len;
1202 SILC_LOG_DEBUG(("Processing New ID List"));
1204 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1205 packet->src_id_type != SILC_ID_SERVER)
1208 /* If the sender of this packet is server and we are router we need to
1209 broadcast this packet to other routers in the network. Broadcast
1210 this list packet instead of multiple New ID packets. */
1211 if (!server->standalone && server->server_type == SILC_ROUTER &&
1212 sock->type == SILC_SOCKET_TYPE_SERVER &&
1213 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1214 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1215 silc_server_packet_send(server, server->router->connection,
1217 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1218 packet->buffer->data, packet->buffer->len, FALSE);
1221 /* Make copy of the original packet context, except for the actual
1222 data buffer, which we will here now fetch from the original buffer. */
1223 new_id = silc_packet_context_alloc();
1224 new_id->type = SILC_PACKET_NEW_ID;
1225 new_id->flags = packet->flags;
1226 new_id->src_id = packet->src_id;
1227 new_id->src_id_len = packet->src_id_len;
1228 new_id->src_id_type = packet->src_id_type;
1229 new_id->dst_id = packet->dst_id;
1230 new_id->dst_id_len = packet->dst_id_len;
1231 new_id->dst_id_type = packet->dst_id_type;
1233 idp = silc_buffer_alloc(256);
1234 new_id->buffer = idp;
1236 while (packet->buffer->len) {
1237 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1238 if ((id_len > packet->buffer->len) ||
1239 (id_len > idp->truelen))
1242 silc_buffer_pull_tail(idp, 4 + id_len);
1243 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1245 /* Process the New ID */
1246 silc_server_new_id_real(server, sock, new_id, FALSE);
1248 silc_buffer_push_tail(idp, 4 + id_len);
1249 silc_buffer_pull(packet->buffer, 4 + id_len);
1252 silc_buffer_free(idp);
1256 /* Received New Channel packet. Information about new channels in the
1257 network are distributed using this packet. Save the information about
1258 the new channel. This usually comes from router but also normal server
1259 can send this to notify channels it has when it connects to us. */
1261 void silc_server_new_channel(SilcServer server,
1262 SilcSocketConnection sock,
1263 SilcPacketContext *packet)
1266 SilcChannelID *channel_id;
1267 unsigned short channel_id_len;
1271 SILC_LOG_DEBUG(("Processing New Channel"));
1273 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1274 packet->src_id_type != SILC_ID_SERVER ||
1275 server->server_type == SILC_SERVER)
1279 ret = silc_buffer_unformat(packet->buffer,
1280 SILC_STR_UI16_STRING_ALLOC(&channel_name),
1281 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
1285 silc_free(channel_name);
1291 /* Decode the channel ID */
1292 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
1296 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1297 /* Add the server to global list as it is coming from router. It
1298 cannot be our own channel as it is coming from router. */
1300 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1301 silc_id_render(channel_id, SILC_ID_CHANNEL),
1304 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
1305 server->router->connection, NULL);
1307 server->stat.channels++;
1309 /* The channel is coming from our server, thus it is in our cell
1310 we will add it to our local list. */
1311 SilcChannelEntry channel;
1314 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1315 silc_id_render(channel_id, SILC_ID_CHANNEL),
1318 /* Check that we don't already have this channel */
1319 channel = silc_idlist_find_channel_by_name(server->local_list,
1320 channel_name, NULL);
1322 channel = silc_idlist_find_channel_by_name(server->global_list,
1323 channel_name, NULL);
1325 /* If the channel does not exist, then create it. We create the channel
1326 with the channel ID provided by the server. This creates a new
1327 key to the channel as well that we will send to the server. */
1329 channel = silc_server_create_new_channel_with_id(server, NULL,
1335 /* Send the new channel key to the server */
1336 chk = silc_channel_key_payload_encode(channel_id_len, id,
1337 strlen(channel->channel_key->
1339 channel->channel_key->cipher->name,
1340 channel->key_len / 8,
1342 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1343 chk->data, chk->len, FALSE);
1344 silc_buffer_free(chk);
1347 /* The channel exist by that name, check whether the ID's match.
1348 If they don't then we'll force the server to use the ID we have.
1349 We also create a new key for the channel. */
1351 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1352 /* They don't match, send CHANNEL_CHANGE notify to the server to
1353 force the ID change. */
1354 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1355 silc_server_send_notify_channel_change(server, sock, FALSE,
1358 SILC_ID_CHANNEL_LEN);
1361 /* Create new key for the channel and send it to the server and
1362 everybody else possibly on the channel. */
1364 silc_server_create_channel_key(server, channel, 0);
1366 /* Send to the channel */
1367 silc_server_send_channel_key(server, sock, channel, FALSE);
1369 /* Send to the server */
1370 chk = silc_channel_key_payload_encode(channel_id_len, id,
1371 strlen(channel->channel_key->
1373 channel->channel_key->cipher->name,
1374 channel->key_len / 8,
1376 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1377 chk->data, chk->len, FALSE);
1378 silc_buffer_free(chk);
1380 /* Since the channel is coming from server and we also know about it
1381 then send the JOIN notify to the server so that it see's our
1382 users on the channel "joining" the channel. */
1390 /* Received New Channel List packet, list of New Channel List payloads inside
1391 one packet. Process the New Channel payloads one by one. */
1393 void silc_server_new_channel_list(SilcServer server,
1394 SilcSocketConnection sock,
1395 SilcPacketContext *packet)
1397 SilcPacketContext *new;
1399 unsigned short len1, len2;
1401 SILC_LOG_DEBUG(("Processing New Channel List"));
1403 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1404 packet->src_id_type != SILC_ID_SERVER ||
1405 server->server_type == SILC_SERVER)
1408 /* If the sender of this packet is server and we are router we need to
1409 broadcast this packet to other routers in the network. Broadcast
1410 this list packet instead of multiple New Channel packets. */
1411 if (!server->standalone && server->server_type == SILC_ROUTER &&
1412 sock->type == SILC_SOCKET_TYPE_SERVER &&
1413 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1414 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1415 silc_server_packet_send(server, server->router->connection,
1417 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1418 packet->buffer->data, packet->buffer->len, FALSE);
1421 /* Make copy of the original packet context, except for the actual
1422 data buffer, which we will here now fetch from the original buffer. */
1423 new = silc_packet_context_alloc();
1424 new->type = SILC_PACKET_NEW_CHANNEL;
1425 new->flags = packet->flags;
1426 new->src_id = packet->src_id;
1427 new->src_id_len = packet->src_id_len;
1428 new->src_id_type = packet->src_id_type;
1429 new->dst_id = packet->dst_id;
1430 new->dst_id_len = packet->dst_id_len;
1431 new->dst_id_type = packet->dst_id_type;
1433 buffer = silc_buffer_alloc(512);
1434 new->buffer = buffer;
1436 while (packet->buffer->len) {
1437 SILC_GET16_MSB(len1, packet->buffer->data);
1438 if ((len1 > packet->buffer->len) ||
1439 (len1 > buffer->truelen))
1442 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1443 if ((len2 > packet->buffer->len) ||
1444 (len2 > buffer->truelen))
1447 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1448 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1450 /* Process the New Channel */
1451 silc_server_new_channel(server, sock, new);
1453 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1454 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1457 silc_buffer_free(buffer);