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 /* Remove the client from all channels */
244 silc_server_remove_from_channels(server, NULL, client);
246 /* Remove the client entry */
247 if (!silc_idlist_del_client(server->global_list, client))
248 silc_idlist_del_client(server->local_list, client);
251 case SILC_NOTIFY_TYPE_TOPIC_SET:
253 * Distribute the notify to local clients on the channel
256 SILC_LOG_DEBUG(("TOPIC SET notify"));
258 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
259 packet->dst_id_type);
263 /* Get channel entry */
264 channel = silc_idlist_find_channel_by_id(server->local_list,
267 channel = silc_idlist_find_channel_by_id(server->global_list,
270 silc_free(channel_id);
276 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
278 silc_free(channel_id);
283 silc_free(channel->topic);
284 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
285 memcpy(channel->topic, tmp, tmp_len);
287 /* Send the same notify to the channel */
288 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
289 FALSE, packet->buffer->data,
290 packet->buffer->len, FALSE);
291 silc_free(channel_id);
294 case SILC_NOTIFY_TYPE_NICK_CHANGE:
297 * Distribute the notify to local clients on the channel
299 unsigned char *id, *id2;
301 SILC_LOG_DEBUG(("NICK CHANGE notify"));
303 /* Get old client ID */
304 id = silc_argument_get_arg_type(args, 1, &tmp_len);
307 client_id = silc_id_payload_parse_id(id, tmp_len);
311 /* Get new client ID */
312 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
315 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
319 SILC_LOG_DEBUG(("Old Client ID id(%s)",
320 silc_id_render(client_id, SILC_ID_CLIENT)));
321 SILC_LOG_DEBUG(("New Client ID id(%s)",
322 silc_id_render(client_id2, SILC_ID_CLIENT)));
324 /* Replace the Client ID */
325 client = silc_idlist_replace_client_id(server->global_list, client_id,
328 client = silc_idlist_replace_client_id(server->local_list, client_id,
332 /* The nickname is not valid anymore, set it NULL. This causes that
333 the nickname will be queried if someone wants to know it. */
334 if (client->nickname)
335 silc_free(client->nickname);
336 client->nickname = NULL;
338 /* Send the NICK_CHANGE notify type to local clients on the channels
339 this client is joined to. */
340 silc_server_send_notify_on_channels(server, client,
341 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
346 silc_free(client_id);
348 silc_free(client_id2);
352 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
354 * Distribute the notify to local clients on the channel
357 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
359 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
360 packet->dst_id_type);
364 /* Get channel entry */
365 channel = silc_idlist_find_channel_by_id(server->local_list,
368 channel = silc_idlist_find_channel_by_id(server->global_list,
371 silc_free(channel_id);
376 /* Send the same notify to the channel */
377 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
378 FALSE, packet->buffer->data,
379 packet->buffer->len, FALSE);
382 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
384 silc_free(channel_id);
388 SILC_GET32_MSB(mode, tmp);
391 channel->mode = mode;
392 silc_free(channel_id);
395 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
397 * Distribute the notify to local clients on the channel
400 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
402 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
403 packet->dst_id_type);
407 /* Get channel entry */
408 channel = silc_idlist_find_channel_by_id(server->local_list,
411 channel = silc_idlist_find_channel_by_id(server->global_list,
414 silc_free(channel_id);
420 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
422 silc_free(channel_id);
426 SILC_GET32_MSB(mode, tmp);
428 /* Get target client */
429 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
432 client_id = silc_id_payload_parse_id(tmp, tmp_len);
436 /* Get client entry */
437 client = silc_idlist_find_client_by_id(server->global_list,
440 client = silc_idlist_find_client_by_id(server->local_list,
443 silc_free(client_id);
447 silc_free(client_id);
449 /* Get entry to the channel user list */
450 silc_list_start(channel->user_list);
451 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
452 if (chl->client == client) {
453 /* Change the mode */
458 /* Send the same notify to the channel */
459 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
460 FALSE, packet->buffer->data,
461 packet->buffer->len, FALSE);
462 silc_free(channel_id);
465 case SILC_NOTIFY_TYPE_INVITE:
466 SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
469 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
470 SILC_LOG_DEBUG(("CHANNEL CHANGE notify (not-impl XXX)"));
473 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
474 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
477 /* Ignore rest of the notify types for now */
478 case SILC_NOTIFY_TYPE_NONE:
479 case SILC_NOTIFY_TYPE_MOTD:
486 silc_notify_payload_free(payload);
489 void silc_server_notify_list(SilcServer server,
490 SilcSocketConnection sock,
491 SilcPacketContext *packet)
493 SilcPacketContext *new;
497 SILC_LOG_DEBUG(("Processing New Notify List"));
499 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
500 packet->src_id_type != SILC_ID_SERVER)
503 /* Make copy of the original packet context, except for the actual
504 data buffer, which we will here now fetch from the original buffer. */
505 new = silc_packet_context_alloc();
506 new->type = SILC_PACKET_NOTIFY;
507 new->flags = packet->flags;
508 new->src_id = packet->src_id;
509 new->src_id_len = packet->src_id_len;
510 new->src_id_type = packet->src_id_type;
511 new->dst_id = packet->dst_id;
512 new->dst_id_len = packet->dst_id_len;
513 new->dst_id_type = packet->dst_id_type;
515 buffer = silc_buffer_alloc(1024);
516 new->buffer = buffer;
518 while (packet->buffer->len) {
519 SILC_GET16_MSB(len, packet->buffer->data + 2);
520 if (len > packet->buffer->len)
523 if (len > buffer->truelen) {
524 silc_buffer_free(buffer);
525 buffer = silc_buffer_alloc(1024 + len);
528 silc_buffer_pull_tail(buffer, len);
529 silc_buffer_put(buffer, packet->buffer->data, len);
531 /* Process the Notify */
532 silc_server_notify(server, sock, new);
534 silc_buffer_push_tail(buffer, len);
535 silc_buffer_pull(packet->buffer, len);
538 silc_buffer_free(buffer);
542 /* Received private message. This resolves the destination of the message
543 and sends the packet. This is used by both server and router. If the
544 destination is our locally connected client this sends the packet to
545 the client. This may also send the message for further routing if
546 the destination is not in our server (or router). */
548 void silc_server_private_message(SilcServer server,
549 SilcSocketConnection sock,
550 SilcPacketContext *packet)
553 SilcServerEntry router;
554 SilcSocketConnection dst_sock;
555 SilcClientEntry client;
556 SilcIDListData idata;
558 SILC_LOG_DEBUG(("Start"));
563 /* Decode destination Client ID */
564 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
566 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
570 /* If the destination belongs to our server we don't have to route
571 the message anywhere but to send it to the local destination. */
572 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
574 /* It exists, now deliver the message to the destination */
575 dst_sock = (SilcSocketConnection)client->connection;
577 /* If we are router and the client has router then the client is in
578 our cell but not directly connected to us. */
579 if (server->server_type == SILC_ROUTER && client->router) {
580 /* We are of course in this case the client's router thus the real
581 "router" of the client is the server who owns the client. Thus
582 we will send the packet to that server. */
583 router = (SilcServerEntry)client->router;
584 idata = (SilcIDListData)router;
586 silc_server_send_private_message(server, router->connection,
593 /* Seems that client really is directly connected to us */
594 idata = (SilcIDListData)client;
595 silc_server_send_private_message(server, dst_sock,
597 idata->hmac, packet);
601 /* Destination belongs to someone not in this server. If we are normal
602 server our action is to send the packet to our router. */
603 if (server->server_type == SILC_SERVER && !server->standalone) {
604 router = server->router;
606 /* Send to primary route */
608 dst_sock = (SilcSocketConnection)router->connection;
609 idata = (SilcIDListData)router;
610 silc_server_send_private_message(server, dst_sock,
612 idata->hmac, packet);
617 /* We are router and we will perform route lookup for the destination
618 and send the message to fastest route. */
619 if (server->server_type == SILC_ROUTER && !server->standalone) {
620 /* Check first that the ID is valid */
621 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
623 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
624 router = (SilcServerEntry)dst_sock->user_data;
625 idata = (SilcIDListData)router;
627 /* Get fastest route and send packet. */
629 silc_server_send_private_message(server, dst_sock,
631 idata->hmac, packet);
637 silc_server_send_error(server, sock,
638 "No such nickname: Private message not sent");
641 /* Processes incoming command reply packet. The command reply packet may
642 be destined to one of our clients or it may directly for us. We will
643 call the command reply routine after processing the packet. */
645 void silc_server_command_reply(SilcServer server,
646 SilcSocketConnection sock,
647 SilcPacketContext *packet)
649 SilcBuffer buffer = packet->buffer;
650 SilcClientEntry client = NULL;
651 SilcSocketConnection dst_sock;
652 SilcIDListData idata;
653 SilcClientID *id = NULL;
655 SILC_LOG_DEBUG(("Start"));
657 /* Source must be server or router */
658 if (packet->src_id_type != SILC_ID_SERVER &&
659 sock->type != SILC_SOCKET_TYPE_ROUTER)
662 if (packet->dst_id_type == SILC_ID_CHANNEL)
665 if (packet->dst_id_type == SILC_ID_CLIENT) {
666 /* Destination must be one of ours */
667 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
670 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
672 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
678 if (packet->dst_id_type == SILC_ID_SERVER) {
679 /* For now this must be for us */
680 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
681 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
686 /* Execute command reply locally for the command */
687 silc_server_command_reply_process(server, sock, buffer);
689 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
690 /* Relay the packet to the client */
692 dst_sock = (SilcSocketConnection)client->connection;
693 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
694 + packet->dst_id_len + packet->padlen);
696 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
697 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
699 idata = (SilcIDListData)client;
702 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
705 /* Send the packet */
706 silc_server_packet_send_real(server, dst_sock, TRUE);
712 /* Process received channel message. The message can be originated from
715 void silc_server_channel_message(SilcServer server,
716 SilcSocketConnection sock,
717 SilcPacketContext *packet)
719 SilcChannelEntry channel = NULL;
720 SilcChannelClientEntry chl;
721 SilcChannelID *id = NULL;
724 SILC_LOG_DEBUG(("Processing channel message"));
727 if (packet->dst_id_type != SILC_ID_CHANNEL) {
728 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
732 /* Find channel entry */
733 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
736 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
738 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
740 SILC_LOG_DEBUG(("Could not find channel"));
745 /* See that this client is on the channel. If the message is coming
746 from router we won't do the check as the message is from client that
747 we don't know about. Also, if the original sender is not client
748 (as it can be server as well) we don't do the check. */
749 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
750 packet->src_id_type);
753 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
754 packet->src_id_type == SILC_ID_CLIENT) {
755 silc_list_start(channel->user_list);
756 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
757 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
760 if (chl == SILC_LIST_END) {
761 SILC_LOG_DEBUG(("Client not on channel"));
766 /* Distribute the packet to our local clients. This will send the
767 packet for further routing as well, if needed. */
768 silc_server_packet_relay_to_channel(server, sock, channel, sender,
770 packet->buffer->data,
771 packet->buffer->len, FALSE);
780 /* Received channel key packet. We distribute the key to all of our locally
781 connected clients on the channel. */
783 void silc_server_channel_key(SilcServer server,
784 SilcSocketConnection sock,
785 SilcPacketContext *packet)
787 SilcBuffer buffer = packet->buffer;
788 SilcChannelEntry channel;
790 if (packet->src_id_type != SILC_ID_SERVER)
793 /* Save the channel key */
794 channel = silc_server_save_channel_key(server, buffer, NULL);
798 /* Distribute the key to everybody who is on the channel. If we are router
799 we will also send it to locally connected servers. */
800 silc_server_send_channel_key(server, sock, channel, FALSE);
803 /* Received New Client packet and processes it. Creates Client ID for the
804 client. Client becomes registered after calling this functions. */
806 SilcClientEntry silc_server_new_client(SilcServer server,
807 SilcSocketConnection sock,
808 SilcPacketContext *packet)
810 SilcBuffer buffer = packet->buffer;
811 SilcClientEntry client;
812 SilcIDCacheEntry cache;
813 SilcClientID *client_id;
815 SilcIDListData idata;
816 char *username = NULL, *realname = NULL, *id_string;
819 SILC_LOG_DEBUG(("Creating new client"));
821 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
824 /* Take client entry */
825 client = (SilcClientEntry)sock->user_data;
826 idata = (SilcIDListData)client;
828 /* Fetch the old client cache entry so that we can update it. */
829 if (!silc_idcache_find_by_context(server->local_list->clients,
830 sock->user_data, &cache)) {
831 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
835 /* Parse incoming packet */
836 ret = silc_buffer_unformat(buffer,
837 SILC_STR_UI16_STRING_ALLOC(&username),
838 SILC_STR_UI16_STRING_ALLOC(&realname),
852 silc_server_disconnect_remote(server, sock, "Server closed connection: "
853 "Incomplete client information");
857 /* Create Client ID */
858 silc_id_create_client_id(server->id, server->rng, server->md5hash,
859 username, &client_id);
861 /* Update client entry */
862 idata->registered = TRUE;
863 client->nickname = strdup(username);
864 client->username = username;
865 client->userinfo = realname ? realname : strdup("");
866 client->id = client_id;
868 /* Update the cache entry */
869 cache->id = (void *)client_id;
870 cache->type = SILC_ID_CLIENT;
871 cache->data = username;
872 silc_idcache_sort_by_data(server->local_list->clients);
874 /* Notify our router about new client on the SILC network */
875 if (!server->standalone)
876 silc_server_send_new_id(server, (SilcSocketConnection)
877 server->router->connection,
878 server->server_type == SILC_ROUTER ? TRUE : FALSE,
879 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
881 /* Send the new client ID to the client. */
882 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
883 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
884 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
885 silc_buffer_format(reply,
886 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
887 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
888 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
890 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
891 reply->data, reply->len, FALSE);
892 silc_free(id_string);
893 silc_buffer_free(reply);
895 /* Send some nice info to the client */
896 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
897 ("Welcome to the SILC Network %s@%s",
898 username, sock->hostname));
899 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
900 ("Your host is %s, running version %s",
901 server->config->server_info->server_name,
903 if (server->server_type == SILC_ROUTER) {
904 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
905 ("There are %d clients on %d servers in SILC "
906 "Network", server->stat.clients,
907 server->stat.servers + 1));
908 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
909 ("There are %d clients on %d server in our cell",
910 server->stat.cell_clients,
911 server->stat.cell_servers + 1));
912 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
913 ("I have %d clients, %d channels, %d servers and "
915 server->stat.my_clients,
916 server->stat.my_channels,
917 server->stat.my_servers,
918 server->stat.my_routers));
919 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
920 ("%d server operators and %d router operators "
922 server->stat.my_server_ops,
923 server->stat.my_router_ops));
925 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
926 ("I have %d clients and %d channels formed",
927 server->stat.my_clients,
928 server->stat.my_channels));
929 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
930 ("%d operators online",
931 server->stat.my_server_ops));
933 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
934 ("Your connection is secured with %s cipher, "
935 "key length %d bits",
936 idata->send_key->cipher->name,
937 idata->send_key->cipher->key_len));
938 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
939 ("Your current nickname is %s",
943 silc_server_send_motd(server, sock);
948 /* Create new server. This processes received New Server packet and
949 saves the received Server ID. The server is our locally connected
950 server thus we save all the information and save it to local list.
951 This funtion can be used by both normal server and router server.
952 If normal server uses this it means that its router has connected
953 to the server. If router uses this it means that one of the cell's
954 servers is connected to the router. */
956 SilcServerEntry silc_server_new_server(SilcServer server,
957 SilcSocketConnection sock,
958 SilcPacketContext *packet)
960 SilcBuffer buffer = packet->buffer;
961 SilcServerEntry new_server;
962 SilcIDCacheEntry cache;
963 SilcServerID *server_id;
964 SilcIDListData idata;
965 unsigned char *server_name, *id_string;
966 unsigned short id_len;
969 SILC_LOG_DEBUG(("Creating new server"));
971 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
972 sock->type != SILC_SOCKET_TYPE_ROUTER)
975 /* Take server entry */
976 new_server = (SilcServerEntry)sock->user_data;
977 idata = (SilcIDListData)new_server;
979 /* Fetch the old server cache entry so that we can update it. */
980 if (!silc_idcache_find_by_context(server->local_list->servers,
981 sock->user_data, &cache)) {
982 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
986 /* Parse the incoming packet */
987 ret = silc_buffer_unformat(buffer,
988 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
989 SILC_STR_UI16_STRING_ALLOC(&server_name),
993 silc_free(id_string);
995 silc_free(server_name);
999 if (id_len > buffer->len) {
1000 silc_free(id_string);
1001 silc_free(server_name);
1006 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1008 silc_free(id_string);
1009 silc_free(server_name);
1012 silc_free(id_string);
1014 /* Update client entry */
1015 idata->registered = TRUE;
1016 new_server->server_name = server_name;
1017 new_server->id = server_id;
1019 /* Update the cache entry */
1020 cache->id = (void *)server_id;
1021 cache->type = SILC_ID_SERVER;
1022 cache->data = server_name;
1023 silc_idcache_sort_by_data(server->local_list->servers);
1025 /* Distribute the information about new server in the SILC network
1026 to our router. If we are normal server we won't send anything
1027 since this connection must be our router connection. */
1028 if (server->server_type == SILC_ROUTER && !server->standalone &&
1029 server->router->connection != sock)
1030 silc_server_send_new_id(server, server->router->connection,
1031 TRUE, new_server->id, SILC_ID_SERVER,
1032 SILC_ID_SERVER_LEN);
1034 if (server->server_type == SILC_ROUTER)
1035 server->stat.cell_servers++;
1040 /* Processes incoming New ID packet. New ID Payload is used to distribute
1041 information about newly registered clients and servers. */
1043 static void silc_server_new_id_real(SilcServer server,
1044 SilcSocketConnection sock,
1045 SilcPacketContext *packet,
1048 SilcBuffer buffer = packet->buffer;
1050 SilcServerEntry router;
1051 SilcSocketConnection router_sock;
1054 unsigned char *hash = NULL;
1057 SILC_LOG_DEBUG(("Processing new ID"));
1059 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1060 server->server_type == SILC_SERVER ||
1061 packet->src_id_type != SILC_ID_SERVER)
1064 idp = silc_id_payload_parse(buffer);
1068 id_type = silc_id_payload_get_type(idp);
1070 /* Normal server cannot have other normal server connections */
1071 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1074 id = silc_id_payload_get_id(idp);
1078 /* If the sender of this packet is server and we are router we need to
1079 broadcast this packet to other routers in the network. */
1080 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1081 sock->type == SILC_SOCKET_TYPE_SERVER &&
1082 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1083 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1084 silc_server_packet_send(server, server->router->connection,
1086 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1087 buffer->data, buffer->len, FALSE);
1090 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1091 id_list = server->local_list;
1093 id_list = server->global_list;
1096 router = sock->user_data;
1099 case SILC_ID_CLIENT:
1101 SilcClientEntry entry;
1103 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1104 silc_id_render(id, SILC_ID_CLIENT),
1105 sock->type == SILC_SOCKET_TYPE_SERVER ?
1106 "Server" : "Router", sock->hostname));
1108 /* As a router we keep information of all global information in our
1109 global list. Cell wide information however is kept in the local
1110 list. The client is put to global list and we will take the hash
1111 value of the Client ID and save it to the ID Cache system for fast
1112 searching in the future. */
1113 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1114 sizeof(unsigned char));
1115 memcpy(hash, ((SilcClientID *)id)->hash,
1116 sizeof(((SilcClientID *)id)->hash));
1117 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
1119 entry->nickname = NULL;
1121 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1122 server->stat.cell_clients++;
1123 server->stat.clients++;
1126 /* XXX Adding two ID's with same IP number replaces the old entry thus
1127 gives wrong route. Thus, now disabled until figured out a better way
1128 to do this or when removed the whole thing. This could be removed
1129 because entry->router->connection gives always the most optimal route
1130 for the ID anyway (unless new routes (faster perhaps) are established
1131 after receiving this ID, this we don't know however). */
1132 /* Add route cache for this ID */
1133 silc_server_route_add(silc_server_route_hash(
1134 ((SilcClientID *)id)->ip.s_addr,
1135 server->id->port), ((SilcClientID *)id)->ip.s_addr,
1141 case SILC_ID_SERVER:
1142 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1143 silc_id_render(id, SILC_ID_SERVER),
1144 sock->type == SILC_SOCKET_TYPE_SERVER ?
1145 "Server" : "Router", sock->hostname));
1147 /* As a router we keep information of all global information in our global
1148 list. Cell wide information however is kept in the local list. */
1149 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1151 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1152 server->stat.cell_servers++;
1153 server->stat.servers++;
1156 /* Add route cache for this ID */
1157 silc_server_route_add(silc_server_route_hash(
1158 ((SilcServerID *)id)->ip.s_addr,
1159 ((SilcServerID *)id)->port),
1160 ((SilcServerID *)id)->ip.s_addr,
1165 case SILC_ID_CHANNEL:
1166 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1174 silc_id_payload_free(idp);
1178 /* Processes incoming New ID packet. New ID Payload is used to distribute
1179 information about newly registered clients and servers. */
1181 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1182 SilcPacketContext *packet)
1184 silc_server_new_id_real(server, sock, packet, TRUE);
1187 /* Receoved New Id List packet, list of New ID payloads inside one
1188 packet. Process the New ID payloads one by one. */
1190 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1191 SilcPacketContext *packet)
1193 SilcPacketContext *new_id;
1195 unsigned short id_len;
1197 SILC_LOG_DEBUG(("Processing New ID List"));
1199 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1200 packet->src_id_type != SILC_ID_SERVER)
1203 /* If the sender of this packet is server and we are router we need to
1204 broadcast this packet to other routers in the network. Broadcast
1205 this list packet instead of multiple New ID packets. */
1206 if (!server->standalone && server->server_type == SILC_ROUTER &&
1207 sock->type == SILC_SOCKET_TYPE_SERVER &&
1208 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1209 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1210 silc_server_packet_send(server, server->router->connection,
1212 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1213 packet->buffer->data, packet->buffer->len, FALSE);
1216 /* Make copy of the original packet context, except for the actual
1217 data buffer, which we will here now fetch from the original buffer. */
1218 new_id = silc_packet_context_alloc();
1219 new_id->type = SILC_PACKET_NEW_ID;
1220 new_id->flags = packet->flags;
1221 new_id->src_id = packet->src_id;
1222 new_id->src_id_len = packet->src_id_len;
1223 new_id->src_id_type = packet->src_id_type;
1224 new_id->dst_id = packet->dst_id;
1225 new_id->dst_id_len = packet->dst_id_len;
1226 new_id->dst_id_type = packet->dst_id_type;
1228 idp = silc_buffer_alloc(256);
1229 new_id->buffer = idp;
1231 while (packet->buffer->len) {
1232 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1233 if ((id_len > packet->buffer->len) ||
1234 (id_len > idp->truelen))
1237 silc_buffer_pull_tail(idp, 4 + id_len);
1238 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1240 /* Process the New ID */
1241 silc_server_new_id_real(server, sock, new_id, FALSE);
1243 silc_buffer_push_tail(idp, 4 + id_len);
1244 silc_buffer_pull(packet->buffer, 4 + id_len);
1247 silc_buffer_free(idp);
1251 /* Received New Channel packet. Information about new channels in the
1252 network are distributed using this packet. Save the information about
1253 the new channel. This usually comes from router but also normal server
1254 can send this to notify channels it has when it connects to us. */
1256 void silc_server_new_channel(SilcServer server,
1257 SilcSocketConnection sock,
1258 SilcPacketContext *packet)
1261 SilcChannelID *channel_id;
1262 unsigned short channel_id_len;
1266 SILC_LOG_DEBUG(("Processing New Channel"));
1268 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1269 packet->src_id_type != SILC_ID_SERVER ||
1270 server->server_type == SILC_SERVER)
1274 ret = silc_buffer_unformat(packet->buffer,
1275 SILC_STR_UI16_STRING_ALLOC(&channel_name),
1276 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
1280 silc_free(channel_name);
1286 /* Decode the channel ID */
1287 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
1291 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1292 /* Add the server to global list as it is coming from router. It
1293 cannot be our own channel as it is coming from router. */
1295 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1296 silc_id_render(channel_id, SILC_ID_CHANNEL),
1299 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
1300 server->router->connection, NULL);
1302 server->stat.channels++;
1304 /* The channel is coming from our server, thus it is in our cell
1305 we will add it to our local list. */
1306 SilcChannelEntry channel;
1309 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1310 silc_id_render(channel_id, SILC_ID_CHANNEL),
1313 /* Check that we don't already have this channel */
1314 channel = silc_idlist_find_channel_by_name(server->local_list,
1315 channel_name, NULL);
1317 channel = silc_idlist_find_channel_by_name(server->global_list,
1318 channel_name, NULL);
1320 /* If the channel does not exist, then create it. We create the channel
1321 with the channel ID provided by the server. This creates a new
1322 key to the channel as well that we will send to the server. */
1324 channel = silc_server_create_new_channel_with_id(server, NULL,
1330 /* Send the new channel key to the server */
1331 chk = silc_channel_key_payload_encode(channel_id_len, id,
1332 strlen(channel->channel_key->
1334 channel->channel_key->cipher->name,
1335 channel->key_len / 8,
1337 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1338 chk->data, chk->len, FALSE);
1339 silc_buffer_free(chk);
1342 /* The channel exist by that name, check whether the ID's match.
1343 If they don't then we'll force the server to use the ID we have.
1344 We also create a new key for the channel. */
1346 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1347 /* They don't match, send CHANNEL_CHANGE notify to the server to
1348 force the ID change. */
1349 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1350 silc_server_send_notify_channel_change(server, sock, FALSE,
1353 SILC_ID_CHANNEL_LEN);
1356 /* Create new key for the channel and send it to the server and
1357 everybody else possibly on the channel. */
1359 silc_server_create_channel_key(server, channel, 0);
1361 /* Send to the channel */
1362 silc_server_send_channel_key(server, sock, channel, FALSE);
1364 /* Send to the server */
1365 chk = silc_channel_key_payload_encode(channel_id_len, id,
1366 strlen(channel->channel_key->
1368 channel->channel_key->cipher->name,
1369 channel->key_len / 8,
1371 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1372 chk->data, chk->len, FALSE);
1373 silc_buffer_free(chk);
1375 /* Since the channel is coming from server and we also know about it
1376 then send the JOIN notify to the server so that it see's our
1377 users on the channel "joining" the channel. */
1385 /* Received New Channel List packet, list of New Channel List payloads inside
1386 one packet. Process the New Channel payloads one by one. */
1388 void silc_server_new_channel_list(SilcServer server,
1389 SilcSocketConnection sock,
1390 SilcPacketContext *packet)
1392 SilcPacketContext *new;
1394 unsigned short len1, len2;
1396 SILC_LOG_DEBUG(("Processing New Channel List"));
1398 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1399 packet->src_id_type != SILC_ID_SERVER ||
1400 server->server_type == SILC_SERVER)
1403 /* If the sender of this packet is server and we are router we need to
1404 broadcast this packet to other routers in the network. Broadcast
1405 this list packet instead of multiple New Channel packets. */
1406 if (!server->standalone && server->server_type == SILC_ROUTER &&
1407 sock->type == SILC_SOCKET_TYPE_SERVER &&
1408 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1409 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1410 silc_server_packet_send(server, server->router->connection,
1412 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1413 packet->buffer->data, packet->buffer->len, FALSE);
1416 /* Make copy of the original packet context, except for the actual
1417 data buffer, which we will here now fetch from the original buffer. */
1418 new = silc_packet_context_alloc();
1419 new->type = SILC_PACKET_NEW_CHANNEL;
1420 new->flags = packet->flags;
1421 new->src_id = packet->src_id;
1422 new->src_id_len = packet->src_id_len;
1423 new->src_id_type = packet->src_id_type;
1424 new->dst_id = packet->dst_id;
1425 new->dst_id_len = packet->dst_id_len;
1426 new->dst_id_type = packet->dst_id_type;
1428 buffer = silc_buffer_alloc(512);
1429 new->buffer = buffer;
1431 while (packet->buffer->len) {
1432 SILC_GET16_MSB(len1, packet->buffer->data);
1433 if ((len1 > packet->buffer->len) ||
1434 (len1 > buffer->truelen))
1437 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1438 if ((len2 > packet->buffer->len) ||
1439 (len2 > buffer->truelen))
1442 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1443 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1445 /* Process the New Channel */
1446 silc_server_new_channel(server, sock, new);
1448 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1449 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1452 silc_buffer_free(buffer);