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 /* Check whereto relay the received notify packet that was destined
34 silc_server_packet_process_relay_notify(SilcServer server,
35 SilcSocketConnection sock,
36 SilcPacketContext *packet)
39 SilcServerEntry router;
40 SilcSocketConnection dst_sock;
41 SilcClientEntry client;
44 SILC_LOG_DEBUG(("Start"));
46 /* Decode destination Client ID */
47 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
49 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
53 /* If the destination belongs to our server we don't have to route
54 the packet anywhere but to send it to the local destination. */
55 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
57 /* It exists, now deliver the packet to the destination */
58 dst_sock = (SilcSocketConnection)client->connection;
60 /* If we are router and the client has router then the client is in
61 our cell but not directly connected to us. */
62 if (server->server_type == SILC_ROUTER && client->router) {
63 /* We are of course in this case the client's router thus the real
64 "router" of the client is the server who owns the client. Thus
65 we will send the packet to that server. */
66 router = (SilcServerEntry)client->router;
67 idata = (SilcIDListData)router;
68 silc_server_packet_relay_notify(server, router->connection,
76 /* Seems that client really is directly connected to us */
77 idata = (SilcIDListData)client;
78 silc_server_packet_relay_notify(server, dst_sock,
85 /* Destination belongs to someone not in this server. If we are normal
86 server our action is to send the packet to our router. */
87 if (server->server_type == SILC_SERVER && !server->standalone) {
88 router = server->router;
90 /* Send to primary route */
92 dst_sock = (SilcSocketConnection)router->connection;
93 idata = (SilcIDListData)router;
94 silc_server_packet_relay_notify(server, dst_sock,
102 /* We are router and we will perform route lookup for the destination
103 and send the packet to fastest route. */
104 if (server->server_type == SILC_ROUTER && !server->standalone) {
105 /* Check first that the ID is valid */
106 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
108 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
109 router = (SilcServerEntry)dst_sock->user_data;
110 idata = (SilcIDListData)router;
112 /* Get fastest route and send packet. */
114 silc_server_packet_relay_notify(server, dst_sock,
116 idata->hmac, packet);
123 /* Received notify packet. Server can receive notify packets from router.
124 Server then relays the notify messages to clients if needed. */
126 void silc_server_notify(SilcServer server,
127 SilcSocketConnection sock,
128 SilcPacketContext *packet)
130 SilcNotifyPayload payload;
132 SilcArgumentPayload args;
133 SilcChannelID *channel_id;
134 SilcClientID *client_id, *client_id2;
135 SilcChannelEntry channel;
136 SilcClientEntry client;
137 SilcChannelClientEntry chl;
140 unsigned int tmp_len;
142 SILC_LOG_DEBUG(("Start"));
144 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
145 packet->src_id_type != SILC_ID_SERVER)
148 /* If the packet is destined directly to a client, then we don't
149 process the packet at all but just relay it to the client. */
150 if (packet->dst_id_type == SILC_ID_CLIENT) {
151 silc_server_packet_process_relay_notify(server, sock, packet);
155 /* If we are router and this packet is not already broadcast packet
156 we will broadcast it. The sending socket really cannot be router or
157 the router is buggy. If this packet is coming from router then it must
158 have the broadcast flag set already and we won't do anything. */
159 if (!server->standalone && server->server_type == SILC_ROUTER &&
160 sock->type == SILC_SOCKET_TYPE_SERVER &&
161 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
162 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
163 silc_server_packet_send(server, server->router->connection, packet->type,
164 packet->flags | SILC_PACKET_FLAG_BROADCAST,
165 packet->buffer->data, packet->buffer->len, FALSE);
168 payload = silc_notify_payload_parse(packet->buffer);
172 type = silc_notify_get_type(payload);
173 args = silc_notify_get_args(payload);
178 case SILC_NOTIFY_TYPE_JOIN:
180 * Distribute the notify to local clients on the channel
182 SILC_LOG_DEBUG(("JOIN notify"));
185 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
188 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
192 /* Get channel entry */
193 channel = silc_idlist_find_channel_by_id(server->local_list,
196 channel = silc_idlist_find_channel_by_id(server->global_list,
199 silc_free(channel_id);
203 silc_free(channel_id);
206 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
209 client_id = silc_id_payload_parse_id(tmp, tmp_len);
213 /* Send to channel */
214 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
215 FALSE, packet->buffer->data,
216 packet->buffer->len, FALSE);
218 /* If the the client is not in local list we check global list (ie. the
219 channel will be global channel) and if it does not exist then create
220 entry for the client. */
221 client = silc_idlist_find_client_by_id(server->local_list,
224 client = silc_idlist_find_client_by_id(server->global_list,
227 /* If router did not find the client the it is bogus */
228 if (server->server_type == SILC_ROUTER)
232 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
233 silc_id_dup(client_id, SILC_ID_CLIENT),
234 sock->user_data, NULL);
236 silc_free(client_id);
242 /* Do not add client to channel if it is there already */
243 if (silc_server_client_on_channel(client, channel))
246 if (server->server_type == SILC_SERVER &&
247 sock->type == SILC_SOCKET_TYPE_ROUTER)
248 /* The channel is global now */
249 channel->global_users = TRUE;
251 /* JOIN the global client to the channel (local clients (if router
252 created the channel) is joined in the pending JOIN command). */
253 chl = silc_calloc(1, sizeof(*chl));
254 chl->client = client;
255 chl->channel = channel;
256 silc_list_add(channel->user_list, chl);
257 silc_list_add(client->channels, chl);
258 silc_free(client_id);
262 case SILC_NOTIFY_TYPE_LEAVE:
264 * Distribute the notify to local clients on the channel
266 SILC_LOG_DEBUG(("LEAVE notify"));
268 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
269 packet->dst_id_type);
273 /* Get channel entry */
274 channel = silc_idlist_find_channel_by_id(server->local_list,
277 channel = silc_idlist_find_channel_by_id(server->global_list,
280 silc_free(channel_id);
286 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
288 silc_free(channel_id);
291 client_id = silc_id_payload_parse_id(tmp, tmp_len);
293 silc_free(channel_id);
297 /* Send to channel */
298 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
299 FALSE, packet->buffer->data,
300 packet->buffer->len, FALSE);
302 /* Get client entry */
303 client = silc_idlist_find_client_by_id(server->global_list,
306 client = silc_idlist_find_client_by_id(server->local_list,
309 silc_free(client_id);
310 silc_free(channel_id);
314 silc_free(client_id);
316 /* Remove the user from channel */
317 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
320 case SILC_NOTIFY_TYPE_SIGNOFF:
322 * Distribute the notify to local clients on the channel
324 SILC_LOG_DEBUG(("SIGNOFF notify"));
327 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
330 client_id = silc_id_payload_parse_id(tmp, tmp_len);
334 /* Get client entry */
335 client = silc_idlist_find_client_by_id(server->global_list,
338 client = silc_idlist_find_client_by_id(server->local_list,
341 silc_free(client_id);
345 silc_free(client_id);
347 /* Get signoff message */
348 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
352 /* Remove the client from all channels */
353 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, TRUE);
355 /* Remove the client entry */
356 if (!silc_idlist_del_client(server->global_list, client))
357 silc_idlist_del_client(server->local_list, client);
360 case SILC_NOTIFY_TYPE_TOPIC_SET:
362 * Distribute the notify to local clients on the channel
365 SILC_LOG_DEBUG(("TOPIC SET notify"));
367 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
368 packet->dst_id_type);
372 /* Get channel entry */
373 channel = silc_idlist_find_channel_by_id(server->local_list,
376 channel = silc_idlist_find_channel_by_id(server->global_list,
379 silc_free(channel_id);
385 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
387 silc_free(channel_id);
392 silc_free(channel->topic);
393 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
394 memcpy(channel->topic, tmp, tmp_len);
396 /* Send the same notify to the channel */
397 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
398 FALSE, packet->buffer->data,
399 packet->buffer->len, FALSE);
400 silc_free(channel_id);
403 case SILC_NOTIFY_TYPE_NICK_CHANGE:
406 * Distribute the notify to local clients on the channel
408 unsigned char *id, *id2;
410 SILC_LOG_DEBUG(("NICK CHANGE notify"));
412 /* Get old client ID */
413 id = silc_argument_get_arg_type(args, 1, &tmp_len);
416 client_id = silc_id_payload_parse_id(id, tmp_len);
420 /* Get new client ID */
421 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
424 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
428 SILC_LOG_DEBUG(("Old Client ID id(%s)",
429 silc_id_render(client_id, SILC_ID_CLIENT)));
430 SILC_LOG_DEBUG(("New Client ID id(%s)",
431 silc_id_render(client_id2, SILC_ID_CLIENT)));
433 /* Replace the Client ID */
434 client = silc_idlist_replace_client_id(server->global_list, client_id,
437 client = silc_idlist_replace_client_id(server->local_list, client_id,
441 /* The nickname is not valid anymore, set it NULL. This causes that
442 the nickname will be queried if someone wants to know it. */
443 if (client->nickname)
444 silc_free(client->nickname);
445 client->nickname = NULL;
447 /* Send the NICK_CHANGE notify type to local clients on the channels
448 this client is joined to. */
449 silc_server_send_notify_on_channels(server, NULL, client,
450 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
455 silc_free(client_id);
457 silc_free(client_id2);
461 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
463 * Distribute the notify to local clients on the channel
466 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
468 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
469 packet->dst_id_type);
473 /* Get channel entry */
474 channel = silc_idlist_find_channel_by_id(server->local_list,
477 channel = silc_idlist_find_channel_by_id(server->global_list,
480 silc_free(channel_id);
485 /* Send the same notify to the channel */
486 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
487 FALSE, packet->buffer->data,
488 packet->buffer->len, FALSE);
491 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
493 silc_free(channel_id);
497 SILC_GET32_MSB(mode, tmp);
500 channel->mode = mode;
501 silc_free(channel_id);
504 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
506 * Distribute the notify to local clients on the channel
509 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
511 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
512 packet->dst_id_type);
516 /* Get channel entry */
517 channel = silc_idlist_find_channel_by_id(server->local_list,
520 channel = silc_idlist_find_channel_by_id(server->global_list,
523 silc_free(channel_id);
529 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
531 silc_free(channel_id);
535 SILC_GET32_MSB(mode, tmp);
537 /* Get target client */
538 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
541 client_id = silc_id_payload_parse_id(tmp, tmp_len);
545 /* Get client entry */
546 client = silc_idlist_find_client_by_id(server->global_list,
549 client = silc_idlist_find_client_by_id(server->local_list,
552 silc_free(client_id);
556 silc_free(client_id);
558 /* Get entry to the channel user list */
559 silc_list_start(channel->user_list);
560 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
561 if (chl->client == client) {
562 /* Change the mode */
567 /* Send the same notify to the channel */
568 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
569 FALSE, packet->buffer->data,
570 packet->buffer->len, FALSE);
571 silc_free(channel_id);
574 case SILC_NOTIFY_TYPE_INVITE:
575 SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
578 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
579 SILC_LOG_DEBUG(("CHANNEL CHANGE notify (not-impl XXX)"));
582 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
583 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
586 case SILC_NOTIFY_TYPE_KICKED:
588 * Distribute the notify to local clients on the channel
591 SILC_LOG_DEBUG(("KICKED notify"));
593 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
594 packet->dst_id_type);
598 /* Get channel entry */
599 channel = silc_idlist_find_channel_by_id(server->local_list,
602 channel = silc_idlist_find_channel_by_id(server->global_list,
605 silc_free(channel_id);
609 silc_free(channel_id);
612 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
615 client_id = silc_id_payload_parse_id(tmp, tmp_len);
619 /* Send to channel */
620 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
621 FALSE, packet->buffer->data,
622 packet->buffer->len, FALSE);
624 /* If the the client is not in local list we check global list */
625 client = silc_idlist_find_client_by_id(server->local_list,
628 client = silc_idlist_find_client_by_id(server->global_list,
631 silc_free(client_id);
636 /* Remove the client from channel */
637 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
641 case SILC_NOTIFY_TYPE_KILLED:
643 * Distribute the notify to local clients on channels
646 SILC_LOG_DEBUG(("KILLED notify"));
650 /* Ignore rest of the notify types for now */
651 case SILC_NOTIFY_TYPE_NONE:
652 case SILC_NOTIFY_TYPE_MOTD:
659 silc_notify_payload_free(payload);
662 void silc_server_notify_list(SilcServer server,
663 SilcSocketConnection sock,
664 SilcPacketContext *packet)
666 SilcPacketContext *new;
670 SILC_LOG_DEBUG(("Processing New Notify List"));
672 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
673 packet->src_id_type != SILC_ID_SERVER)
676 /* Make copy of the original packet context, except for the actual
677 data buffer, which we will here now fetch from the original buffer. */
678 new = silc_packet_context_alloc();
679 new->type = SILC_PACKET_NOTIFY;
680 new->flags = packet->flags;
681 new->src_id = packet->src_id;
682 new->src_id_len = packet->src_id_len;
683 new->src_id_type = packet->src_id_type;
684 new->dst_id = packet->dst_id;
685 new->dst_id_len = packet->dst_id_len;
686 new->dst_id_type = packet->dst_id_type;
688 buffer = silc_buffer_alloc(1024);
689 new->buffer = buffer;
691 while (packet->buffer->len) {
692 SILC_GET16_MSB(len, packet->buffer->data + 2);
693 if (len > packet->buffer->len)
696 if (len > buffer->truelen) {
697 silc_buffer_free(buffer);
698 buffer = silc_buffer_alloc(1024 + len);
701 silc_buffer_pull_tail(buffer, len);
702 silc_buffer_put(buffer, packet->buffer->data, len);
704 /* Process the Notify */
705 silc_server_notify(server, sock, new);
707 silc_buffer_push_tail(buffer, len);
708 silc_buffer_pull(packet->buffer, len);
711 silc_buffer_free(buffer);
715 /* Received private message. This resolves the destination of the message
716 and sends the packet. This is used by both server and router. If the
717 destination is our locally connected client this sends the packet to
718 the client. This may also send the message for further routing if
719 the destination is not in our server (or router). */
721 void silc_server_private_message(SilcServer server,
722 SilcSocketConnection sock,
723 SilcPacketContext *packet)
726 SilcServerEntry router;
727 SilcSocketConnection dst_sock;
728 SilcClientEntry client;
729 SilcIDListData idata;
731 SILC_LOG_DEBUG(("Start"));
733 if (packet->src_id_type != SILC_ID_CLIENT ||
734 packet->dst_id_type != SILC_ID_CLIENT)
740 /* Decode destination Client ID */
741 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
743 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
747 /* If the destination belongs to our server we don't have to route
748 the message anywhere but to send it to the local destination. */
749 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
751 /* It exists, now deliver the message to the destination */
752 dst_sock = (SilcSocketConnection)client->connection;
754 /* If we are router and the client has router then the client is in
755 our cell but not directly connected to us. */
756 if (server->server_type == SILC_ROUTER && client->router) {
757 /* We are of course in this case the client's router thus the real
758 "router" of the client is the server who owns the client. Thus
759 we will send the packet to that server. */
760 router = (SilcServerEntry)client->router;
761 idata = (SilcIDListData)router;
763 silc_server_send_private_message(server, router->connection,
771 /* Seems that client really is directly connected to us */
772 idata = (SilcIDListData)client;
773 silc_server_send_private_message(server, dst_sock,
775 idata->hmac, packet);
780 /* Destination belongs to someone not in this server. If we are normal
781 server our action is to send the packet to our router. */
782 if (server->server_type == SILC_SERVER && !server->standalone) {
783 router = server->router;
785 /* Send to primary route */
787 dst_sock = (SilcSocketConnection)router->connection;
788 idata = (SilcIDListData)router;
789 silc_server_send_private_message(server, dst_sock,
791 idata->hmac, packet);
797 /* We are router and we will perform route lookup for the destination
798 and send the message to fastest route. */
799 if (server->server_type == SILC_ROUTER && !server->standalone) {
800 /* Check first that the ID is valid */
801 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
803 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
804 router = (SilcServerEntry)dst_sock->user_data;
805 idata = (SilcIDListData)router;
807 /* Get fastest route and send packet. */
809 silc_server_send_private_message(server, dst_sock,
811 idata->hmac, packet);
818 /* Received private message key packet.. This packet is never for us. It is to
819 the client in the packet's destination ID. Sending of this sort of packet
820 equals sending private message, ie. it is sent point to point from
821 one client to another. */
823 void silc_server_private_message_key(SilcServer server,
824 SilcSocketConnection sock,
825 SilcPacketContext *packet)
828 SilcServerEntry router;
829 SilcSocketConnection dst_sock;
830 SilcClientEntry client;
831 SilcIDListData idata;
833 SILC_LOG_DEBUG(("Start"));
835 if (packet->src_id_type != SILC_ID_CLIENT ||
836 packet->dst_id_type != SILC_ID_CLIENT)
842 /* Decode destination Client ID */
843 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
845 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
849 /* If the destination belongs to our server we don't have to route
850 the message anywhere but to send it to the local destination. */
851 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
853 /* It exists, now deliver the message to the destination */
854 dst_sock = (SilcSocketConnection)client->connection;
856 /* If we are router and the client has router then the client is in
857 our cell but not directly connected to us. */
858 if (server->server_type == SILC_ROUTER && client->router) {
859 /* We are of course in this case the client's router thus the real
860 "router" of the client is the server who owns the client. Thus
861 we will send the packet to that server. */
862 router = (SilcServerEntry)client->router;
863 idata = (SilcIDListData)router;
864 silc_server_send_private_message_key(server, router->connection,
872 /* Seems that client really is directly connected to us */
873 idata = (SilcIDListData)client;
874 silc_server_send_private_message_key(server, dst_sock,
876 idata->hmac, packet);
881 /* Destination belongs to someone not in this server. If we are normal
882 server our action is to send the packet to our router. */
883 if (server->server_type == SILC_SERVER && !server->standalone) {
884 router = server->router;
886 /* Send to primary route */
888 dst_sock = (SilcSocketConnection)router->connection;
889 idata = (SilcIDListData)router;
890 silc_server_send_private_message_key(server, dst_sock,
892 idata->hmac, packet);
898 /* We are router and we will perform route lookup for the destination
899 and send the packet to fastest route. */
900 if (server->server_type == SILC_ROUTER && !server->standalone) {
901 /* Check first that the ID is valid */
902 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
904 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
905 router = (SilcServerEntry)dst_sock->user_data;
906 idata = (SilcIDListData)router;
908 /* Get fastest route and send packet. */
910 silc_server_send_private_message_key(server, dst_sock,
912 idata->hmac, packet);
919 /* Processes incoming command reply packet. The command reply packet may
920 be destined to one of our clients or it may directly for us. We will
921 call the command reply routine after processing the packet. */
923 void silc_server_command_reply(SilcServer server,
924 SilcSocketConnection sock,
925 SilcPacketContext *packet)
927 SilcBuffer buffer = packet->buffer;
928 SilcClientEntry client = NULL;
929 SilcSocketConnection dst_sock;
930 SilcIDListData idata;
931 SilcClientID *id = NULL;
933 SILC_LOG_DEBUG(("Start"));
935 /* Source must be server or router */
936 if (packet->src_id_type != SILC_ID_SERVER &&
937 sock->type != SILC_SOCKET_TYPE_ROUTER)
940 if (packet->dst_id_type == SILC_ID_CHANNEL)
943 if (packet->dst_id_type == SILC_ID_CLIENT) {
944 /* Destination must be one of ours */
945 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
948 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
950 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
956 if (packet->dst_id_type == SILC_ID_SERVER) {
957 /* For now this must be for us */
958 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
959 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
964 /* Execute command reply locally for the command */
965 silc_server_command_reply_process(server, sock, buffer);
967 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
968 /* Relay the packet to the client */
970 dst_sock = (SilcSocketConnection)client->connection;
971 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
972 + packet->dst_id_len + packet->padlen);
974 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
975 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
977 idata = (SilcIDListData)client;
980 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
983 /* Send the packet */
984 silc_server_packet_send_real(server, dst_sock, TRUE);
990 /* Process received channel message. The message can be originated from
993 void silc_server_channel_message(SilcServer server,
994 SilcSocketConnection sock,
995 SilcPacketContext *packet)
997 SilcChannelEntry channel = NULL;
998 SilcChannelClientEntry chl;
999 SilcChannelID *id = NULL;
1000 void *sender = NULL;
1002 SILC_LOG_DEBUG(("Processing channel message"));
1005 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1006 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1010 /* Find channel entry */
1011 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1014 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1016 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1018 SILC_LOG_DEBUG(("Could not find channel"));
1023 /* See that this client is on the channel. If the message is coming
1024 from router we won't do the check as the message is from client that
1025 we don't know about. Also, if the original sender is not client
1026 (as it can be server as well) we don't do the check. */
1027 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1028 packet->src_id_type);
1031 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
1032 packet->src_id_type == SILC_ID_CLIENT) {
1033 silc_list_start(channel->user_list);
1034 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1035 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1038 if (chl == SILC_LIST_END) {
1039 SILC_LOG_DEBUG(("Client not on channel"));
1044 /* If we are router and the packet came from router and private key
1045 has not been set for the channel then we must encrypt the packet
1046 as it was decrypted with the session key shared between us and the
1047 router which sent it. This is so, because cells does not share the
1049 if (server->server_type == SILC_ROUTER &&
1050 sock->type == SILC_SOCKET_TYPE_ROUTER &&
1051 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1053 unsigned int iv_len, i, data_len;
1055 iv_len = silc_cipher_get_block_len(channel->channel_key);
1056 if (channel->iv[0] == '\0')
1057 for (i = 0; i < iv_len; i++) channel->iv[i] =
1058 silc_rng_get_byte(server->rng);
1060 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1062 /* Encode new payload. This encrypts it also. */
1063 SILC_GET16_MSB(data_len, packet->buffer->data);
1064 chp = silc_channel_payload_encode(data_len, packet->buffer->data + 2,
1065 iv_len, channel->iv,
1066 channel->channel_key,
1067 channel->hmac, server->rng);
1068 silc_buffer_put(packet->buffer, chp->data, chp->len);
1069 silc_buffer_free(chp);
1072 /* Distribute the packet to our local clients. This will send the
1073 packet for further routing as well, if needed. */
1074 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1075 packet->src_id_type,
1076 packet->buffer->data,
1077 packet->buffer->len, FALSE);
1086 /* Received channel key packet. We distribute the key to all of our locally
1087 connected clients on the channel. */
1089 void silc_server_channel_key(SilcServer server,
1090 SilcSocketConnection sock,
1091 SilcPacketContext *packet)
1093 SilcBuffer buffer = packet->buffer;
1094 SilcChannelEntry channel;
1096 if (packet->src_id_type != SILC_ID_SERVER)
1099 /* Save the channel key */
1100 channel = silc_server_save_channel_key(server, buffer, NULL);
1104 /* Distribute the key to everybody who is on the channel. If we are router
1105 we will also send it to locally connected servers. */
1106 silc_server_send_channel_key(server, sock, channel, FALSE);
1109 /* Received New Client packet and processes it. Creates Client ID for the
1110 client. Client becomes registered after calling this functions. */
1112 SilcClientEntry silc_server_new_client(SilcServer server,
1113 SilcSocketConnection sock,
1114 SilcPacketContext *packet)
1116 SilcBuffer buffer = packet->buffer;
1117 SilcClientEntry client;
1118 SilcIDCacheEntry cache;
1119 SilcClientID *client_id;
1121 SilcIDListData idata;
1122 char *username = NULL, *realname = NULL, *id_string;
1125 SILC_LOG_DEBUG(("Creating new client"));
1127 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1130 /* Take client entry */
1131 client = (SilcClientEntry)sock->user_data;
1132 idata = (SilcIDListData)client;
1134 /* Fetch the old client cache entry so that we can update it. */
1135 if (!silc_idcache_find_by_context(server->local_list->clients,
1136 sock->user_data, &cache)) {
1137 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1141 /* Parse incoming packet */
1142 ret = silc_buffer_unformat(buffer,
1143 SILC_STR_UI16_STRING_ALLOC(&username),
1144 SILC_STR_UI16_STRING_ALLOC(&realname),
1148 silc_free(username);
1150 silc_free(realname);
1155 silc_free(username);
1157 silc_free(realname);
1158 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1159 "Incomplete client information");
1163 /* Create Client ID */
1164 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1165 username, &client_id);
1167 if (strlen(username) > 128)
1168 username[127] = '\0';
1170 /* Update client entry */
1171 idata->registered = TRUE;
1172 client->nickname = strdup(username);
1173 client->username = username;
1174 client->userinfo = realname ? realname : strdup(" ");
1175 client->id = client_id;
1177 /* Update the cache entry */
1178 cache->id = (void *)client_id;
1179 cache->type = SILC_ID_CLIENT;
1180 cache->data = username;
1181 silc_idcache_sort_by_data(server->local_list->clients);
1183 /* Notify our router about new client on the SILC network */
1184 if (!server->standalone)
1185 silc_server_send_new_id(server, (SilcSocketConnection)
1186 server->router->connection,
1187 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1188 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1190 /* Send the new client ID to the client. */
1191 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1192 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1193 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1194 silc_buffer_format(reply,
1195 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1196 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1197 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1199 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1200 reply->data, reply->len, FALSE);
1201 silc_free(id_string);
1202 silc_buffer_free(reply);
1204 /* Send some nice info to the client */
1205 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1206 ("Welcome to the SILC Network %s@%s",
1207 username, sock->hostname));
1208 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1209 ("Your host is %s, running version %s",
1210 server->config->server_info->server_name,
1212 if (server->server_type == SILC_ROUTER) {
1213 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1214 ("There are %d clients on %d servers in SILC "
1215 "Network", server->stat.clients,
1216 server->stat.servers + 1));
1217 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1218 ("There are %d clients on %d server in our cell",
1219 server->stat.cell_clients,
1220 server->stat.cell_servers + 1));
1221 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1222 ("I have %d clients, %d channels, %d servers and "
1224 server->stat.my_clients,
1225 server->stat.my_channels,
1226 server->stat.my_servers,
1227 server->stat.my_routers));
1228 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1229 ("%d server operators and %d router operators "
1231 server->stat.my_server_ops,
1232 server->stat.my_router_ops));
1234 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1235 ("I have %d clients and %d channels formed",
1236 server->stat.my_clients,
1237 server->stat.my_channels));
1238 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1239 ("%d operators online",
1240 server->stat.my_server_ops));
1242 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1243 ("Your connection is secured with %s cipher, "
1244 "key length %d bits",
1245 idata->send_key->cipher->name,
1246 idata->send_key->cipher->key_len));
1247 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1248 ("Your current nickname is %s",
1252 silc_server_send_motd(server, sock);
1257 /* Create new server. This processes received New Server packet and
1258 saves the received Server ID. The server is our locally connected
1259 server thus we save all the information and save it to local list.
1260 This funtion can be used by both normal server and router server.
1261 If normal server uses this it means that its router has connected
1262 to the server. If router uses this it means that one of the cell's
1263 servers is connected to the router. */
1265 SilcServerEntry silc_server_new_server(SilcServer server,
1266 SilcSocketConnection sock,
1267 SilcPacketContext *packet)
1269 SilcBuffer buffer = packet->buffer;
1270 SilcServerEntry new_server;
1271 SilcIDCacheEntry cache;
1272 SilcServerID *server_id;
1273 SilcIDListData idata;
1274 unsigned char *server_name, *id_string;
1275 unsigned short id_len;
1278 SILC_LOG_DEBUG(("Creating new server"));
1280 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1281 sock->type != SILC_SOCKET_TYPE_ROUTER)
1284 /* Take server entry */
1285 new_server = (SilcServerEntry)sock->user_data;
1286 idata = (SilcIDListData)new_server;
1288 /* Fetch the old server cache entry so that we can update it. */
1289 if (!silc_idcache_find_by_context(server->local_list->servers,
1290 sock->user_data, &cache)) {
1291 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1295 /* Parse the incoming packet */
1296 ret = silc_buffer_unformat(buffer,
1297 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1298 SILC_STR_UI16_STRING_ALLOC(&server_name),
1302 silc_free(id_string);
1304 silc_free(server_name);
1308 if (id_len > buffer->len) {
1309 silc_free(id_string);
1310 silc_free(server_name);
1315 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1317 silc_free(id_string);
1318 silc_free(server_name);
1321 silc_free(id_string);
1323 /* Update client entry */
1324 idata->registered = TRUE;
1325 new_server->server_name = server_name;
1326 new_server->id = server_id;
1328 /* Update the cache entry */
1329 cache->id = (void *)server_id;
1330 cache->type = SILC_ID_SERVER;
1331 cache->data = server_name;
1332 silc_idcache_sort_by_data(server->local_list->servers);
1334 /* Distribute the information about new server in the SILC network
1335 to our router. If we are normal server we won't send anything
1336 since this connection must be our router connection. */
1337 if (server->server_type == SILC_ROUTER && !server->standalone &&
1338 server->router->connection != sock)
1339 silc_server_send_new_id(server, server->router->connection,
1340 TRUE, new_server->id, SILC_ID_SERVER,
1341 SILC_ID_SERVER_LEN);
1343 if (server->server_type == SILC_ROUTER)
1344 server->stat.cell_servers++;
1349 /* Processes incoming New ID packet. New ID Payload is used to distribute
1350 information about newly registered clients and servers. */
1352 static void silc_server_new_id_real(SilcServer server,
1353 SilcSocketConnection sock,
1354 SilcPacketContext *packet,
1357 SilcBuffer buffer = packet->buffer;
1359 SilcServerEntry router;
1360 SilcSocketConnection router_sock;
1363 unsigned char *hash = NULL;
1366 SILC_LOG_DEBUG(("Processing new ID"));
1368 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1369 server->server_type == SILC_SERVER ||
1370 packet->src_id_type != SILC_ID_SERVER)
1373 idp = silc_id_payload_parse(buffer);
1377 id_type = silc_id_payload_get_type(idp);
1379 /* Normal server cannot have other normal server connections */
1380 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1383 id = silc_id_payload_get_id(idp);
1387 /* If the sender of this packet is server and we are router we need to
1388 broadcast this packet to other routers in the network. */
1389 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1390 sock->type == SILC_SOCKET_TYPE_SERVER &&
1391 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1392 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1393 silc_server_packet_send(server, server->router->connection,
1395 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1396 buffer->data, buffer->len, FALSE);
1399 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1400 id_list = server->local_list;
1402 id_list = server->global_list;
1405 router = sock->user_data;
1408 case SILC_ID_CLIENT:
1410 SilcClientEntry entry;
1412 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1413 silc_id_render(id, SILC_ID_CLIENT),
1414 sock->type == SILC_SOCKET_TYPE_SERVER ?
1415 "Server" : "Router", sock->hostname));
1417 /* As a router we keep information of all global information in our
1418 global list. Cell wide information however is kept in the local
1419 list. The client is put to global list and we will take the hash
1420 value of the Client ID and save it to the ID Cache system for fast
1421 searching in the future. */
1422 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1423 sizeof(unsigned char));
1424 memcpy(hash, ((SilcClientID *)id)->hash,
1425 sizeof(((SilcClientID *)id)->hash));
1426 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
1428 entry->nickname = NULL;
1430 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1431 server->stat.cell_clients++;
1432 server->stat.clients++;
1435 /* XXX Adding two ID's with same IP number replaces the old entry thus
1436 gives wrong route. Thus, now disabled until figured out a better way
1437 to do this or when removed the whole thing. This could be removed
1438 because entry->router->connection gives always the most optimal route
1439 for the ID anyway (unless new routes (faster perhaps) are established
1440 after receiving this ID, this we don't know however). */
1441 /* Add route cache for this ID */
1442 silc_server_route_add(silc_server_route_hash(
1443 ((SilcClientID *)id)->ip.s_addr,
1444 server->id->port), ((SilcClientID *)id)->ip.s_addr,
1450 case SILC_ID_SERVER:
1451 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1452 silc_id_render(id, SILC_ID_SERVER),
1453 sock->type == SILC_SOCKET_TYPE_SERVER ?
1454 "Server" : "Router", sock->hostname));
1456 /* As a router we keep information of all global information in our global
1457 list. Cell wide information however is kept in the local list. */
1458 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1460 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1461 server->stat.cell_servers++;
1462 server->stat.servers++;
1465 /* Add route cache for this ID */
1466 silc_server_route_add(silc_server_route_hash(
1467 ((SilcServerID *)id)->ip.s_addr,
1468 ((SilcServerID *)id)->port),
1469 ((SilcServerID *)id)->ip.s_addr,
1474 case SILC_ID_CHANNEL:
1475 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1483 silc_id_payload_free(idp);
1487 /* Processes incoming New ID packet. New ID Payload is used to distribute
1488 information about newly registered clients and servers. */
1490 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1491 SilcPacketContext *packet)
1493 silc_server_new_id_real(server, sock, packet, TRUE);
1496 /* Receoved New Id List packet, list of New ID payloads inside one
1497 packet. Process the New ID payloads one by one. */
1499 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1500 SilcPacketContext *packet)
1502 SilcPacketContext *new_id;
1504 unsigned short id_len;
1506 SILC_LOG_DEBUG(("Processing New ID List"));
1508 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1509 packet->src_id_type != SILC_ID_SERVER)
1512 /* If the sender of this packet is server and we are router we need to
1513 broadcast this packet to other routers in the network. Broadcast
1514 this list packet instead of multiple New ID packets. */
1515 if (!server->standalone && server->server_type == SILC_ROUTER &&
1516 sock->type == SILC_SOCKET_TYPE_SERVER &&
1517 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1518 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1519 silc_server_packet_send(server, server->router->connection,
1521 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1522 packet->buffer->data, packet->buffer->len, FALSE);
1525 /* Make copy of the original packet context, except for the actual
1526 data buffer, which we will here now fetch from the original buffer. */
1527 new_id = silc_packet_context_alloc();
1528 new_id->type = SILC_PACKET_NEW_ID;
1529 new_id->flags = packet->flags;
1530 new_id->src_id = packet->src_id;
1531 new_id->src_id_len = packet->src_id_len;
1532 new_id->src_id_type = packet->src_id_type;
1533 new_id->dst_id = packet->dst_id;
1534 new_id->dst_id_len = packet->dst_id_len;
1535 new_id->dst_id_type = packet->dst_id_type;
1537 idp = silc_buffer_alloc(256);
1538 new_id->buffer = idp;
1540 while (packet->buffer->len) {
1541 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1542 if ((id_len > packet->buffer->len) ||
1543 (id_len > idp->truelen))
1546 silc_buffer_pull_tail(idp, 4 + id_len);
1547 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1549 /* Process the New ID */
1550 silc_server_new_id_real(server, sock, new_id, FALSE);
1552 silc_buffer_push_tail(idp, 4 + id_len);
1553 silc_buffer_pull(packet->buffer, 4 + id_len);
1556 silc_buffer_free(idp);
1560 /* Received New Channel packet. Information about new channels in the
1561 network are distributed using this packet. Save the information about
1562 the new channel. This usually comes from router but also normal server
1563 can send this to notify channels it has when it connects to us. */
1565 void silc_server_new_channel(SilcServer server,
1566 SilcSocketConnection sock,
1567 SilcPacketContext *packet)
1570 SilcChannelID *channel_id;
1571 unsigned short channel_id_len;
1575 SILC_LOG_DEBUG(("Processing New Channel"));
1577 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1578 packet->src_id_type != SILC_ID_SERVER ||
1579 server->server_type == SILC_SERVER)
1583 ret = silc_buffer_unformat(packet->buffer,
1584 SILC_STR_UI16_STRING_ALLOC(&channel_name),
1585 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
1589 silc_free(channel_name);
1595 /* Decode the channel ID */
1596 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
1600 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1601 /* Add the server to global list as it is coming from router. It
1602 cannot be our own channel as it is coming from router. */
1604 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1605 silc_id_render(channel_id, SILC_ID_CHANNEL),
1608 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
1609 server->router->connection, NULL, NULL);
1611 server->stat.channels++;
1613 /* The channel is coming from our server, thus it is in our cell
1614 we will add it to our local list. */
1615 SilcChannelEntry channel;
1618 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1619 silc_id_render(channel_id, SILC_ID_CHANNEL),
1622 /* Check that we don't already have this channel */
1623 channel = silc_idlist_find_channel_by_name(server->local_list,
1624 channel_name, NULL);
1626 channel = silc_idlist_find_channel_by_name(server->global_list,
1627 channel_name, NULL);
1629 /* If the channel does not exist, then create it. We create the channel
1630 with the channel ID provided by the server. This creates a new
1631 key to the channel as well that we will send to the server. */
1633 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1639 /* Send the new channel key to the server */
1640 chk = silc_channel_key_payload_encode(channel_id_len, id,
1641 strlen(channel->channel_key->
1643 channel->channel_key->cipher->name,
1644 channel->key_len / 8,
1646 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1647 chk->data, chk->len, FALSE);
1648 silc_buffer_free(chk);
1651 /* The channel exist by that name, check whether the ID's match.
1652 If they don't then we'll force the server to use the ID we have.
1653 We also create a new key for the channel. */
1655 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1656 /* They don't match, send CHANNEL_CHANGE notify to the server to
1657 force the ID change. */
1658 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1659 silc_server_send_notify_channel_change(server, sock, FALSE,
1662 SILC_ID_CHANNEL_LEN);
1665 /* Create new key for the channel and send it to the server and
1666 everybody else possibly on the channel. */
1668 silc_server_create_channel_key(server, channel, 0);
1670 /* Send to the channel */
1671 silc_server_send_channel_key(server, sock, channel, FALSE);
1673 /* Send to the server */
1674 chk = silc_channel_key_payload_encode(channel_id_len, id,
1675 strlen(channel->channel_key->
1677 channel->channel_key->cipher->name,
1678 channel->key_len / 8,
1680 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1681 chk->data, chk->len, FALSE);
1682 silc_buffer_free(chk);
1684 /* Since the channel is coming from server and we also know about it
1685 then send the JOIN notify to the server so that it see's our
1686 users on the channel "joining" the channel. */
1694 /* Received New Channel List packet, list of New Channel List payloads inside
1695 one packet. Process the New Channel payloads one by one. */
1697 void silc_server_new_channel_list(SilcServer server,
1698 SilcSocketConnection sock,
1699 SilcPacketContext *packet)
1701 SilcPacketContext *new;
1703 unsigned short len1, len2;
1705 SILC_LOG_DEBUG(("Processing New Channel List"));
1707 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1708 packet->src_id_type != SILC_ID_SERVER ||
1709 server->server_type == SILC_SERVER)
1712 /* If the sender of this packet is server and we are router we need to
1713 broadcast this packet to other routers in the network. Broadcast
1714 this list packet instead of multiple New Channel packets. */
1715 if (!server->standalone && server->server_type == SILC_ROUTER &&
1716 sock->type == SILC_SOCKET_TYPE_SERVER &&
1717 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1718 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1719 silc_server_packet_send(server, server->router->connection,
1721 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1722 packet->buffer->data, packet->buffer->len, FALSE);
1725 /* Make copy of the original packet context, except for the actual
1726 data buffer, which we will here now fetch from the original buffer. */
1727 new = silc_packet_context_alloc();
1728 new->type = SILC_PACKET_NEW_CHANNEL;
1729 new->flags = packet->flags;
1730 new->src_id = packet->src_id;
1731 new->src_id_len = packet->src_id_len;
1732 new->src_id_type = packet->src_id_type;
1733 new->dst_id = packet->dst_id;
1734 new->dst_id_len = packet->dst_id_len;
1735 new->dst_id_type = packet->dst_id_type;
1737 buffer = silc_buffer_alloc(512);
1738 new->buffer = buffer;
1740 while (packet->buffer->len) {
1741 SILC_GET16_MSB(len1, packet->buffer->data);
1742 if ((len1 > packet->buffer->len) ||
1743 (len1 > buffer->truelen))
1746 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1747 if ((len2 > packet->buffer->len) ||
1748 (len2 > buffer->truelen))
1751 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1752 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1754 /* Process the New Channel */
1755 silc_server_new_channel(server, sock, new);
1757 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1758 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1761 silc_buffer_free(buffer);
1765 /* Received key agreement packet. This packet is never for us. It is to
1766 the client in the packet's destination ID. Sending of this sort of packet
1767 equals sending private message, ie. it is sent point to point from
1768 one client to another. */
1770 void silc_server_key_agreement(SilcServer server,
1771 SilcSocketConnection sock,
1772 SilcPacketContext *packet)
1775 SilcServerEntry router;
1776 SilcSocketConnection dst_sock;
1777 SilcClientEntry client;
1778 SilcIDListData idata;
1780 SILC_LOG_DEBUG(("Start"));
1782 if (packet->src_id_type != SILC_ID_CLIENT ||
1783 packet->dst_id_type != SILC_ID_CLIENT)
1786 if (!packet->dst_id)
1789 /* Decode destination Client ID */
1790 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1792 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
1796 /* If the destination belongs to our server we don't have to route
1797 the packet anywhere but to send it to the local destination. */
1798 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1800 /* It exists, now deliver the packet to the destination */
1801 dst_sock = (SilcSocketConnection)client->connection;
1803 /* If we are router and the client has router then the client is in
1804 our cell but not directly connected to us. */
1805 if (server->server_type == SILC_ROUTER && client->router) {
1806 /* We are of course in this case the client's router thus the real
1807 "router" of the client is the server who owns the client. Thus
1808 we will send the packet to that server. */
1809 router = (SilcServerEntry)client->router;
1810 idata = (SilcIDListData)router;
1811 silc_server_send_key_agreement(server, router->connection,
1819 /* Seems that client really is directly connected to us */
1820 idata = (SilcIDListData)client;
1821 silc_server_send_key_agreement(server, dst_sock,
1823 idata->hmac, packet);
1828 /* Destination belongs to someone not in this server. If we are normal
1829 server our action is to send the packet to our router. */
1830 if (server->server_type == SILC_SERVER && !server->standalone) {
1831 router = server->router;
1833 /* Send to primary route */
1835 dst_sock = (SilcSocketConnection)router->connection;
1836 idata = (SilcIDListData)router;
1837 silc_server_send_key_agreement(server, dst_sock,
1839 idata->hmac, packet);
1845 /* We are router and we will perform route lookup for the destination
1846 and send the packet to fastest route. */
1847 if (server->server_type == SILC_ROUTER && !server->standalone) {
1848 /* Check first that the ID is valid */
1849 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
1851 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
1852 router = (SilcServerEntry)dst_sock->user_data;
1853 idata = (SilcIDListData)router;
1855 /* Get fastest route and send packet. */
1857 silc_server_send_key_agreement(server, dst_sock,
1859 idata->hmac, packet);