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, *channel_id2;
41 SilcClientID *client_id, *client_id2;
42 SilcChannelEntry channel;
43 SilcClientEntry client;
44 SilcChannelClientEntry chl;
45 SilcIDCacheEntry cache;
50 SILC_LOG_DEBUG(("Start"));
52 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
53 packet->src_id_type != SILC_ID_SERVER)
59 /* If the packet is destined directly to a client then relay the packet
60 before processing it. */
61 if (packet->dst_id_type == SILC_ID_CLIENT) {
63 SilcSocketConnection dst_sock;
65 /* Get the route to the client */
66 dst_sock = silc_server_get_client_route(server, packet->dst_id,
67 packet->dst_id_len, NULL, &idata);
69 /* Relay the packet */
70 silc_server_relay_packet(server, dst_sock, idata->send_key,
71 idata->hmac, packet, TRUE);
74 /* If we are router and this packet is not already broadcast packet
75 we will broadcast it. The sending socket really cannot be router or
76 the router is buggy. If this packet is coming from router then it must
77 have the broadcast flag set already and we won't do anything. */
78 if (!server->standalone && server->server_type == SILC_ROUTER &&
79 sock->type == SILC_SOCKET_TYPE_SERVER &&
80 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
81 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
82 silc_server_packet_send(server, server->router->connection, packet->type,
83 packet->flags | SILC_PACKET_FLAG_BROADCAST,
84 packet->buffer->data, packet->buffer->len, FALSE);
87 payload = silc_notify_payload_parse(packet->buffer);
91 type = silc_notify_get_type(payload);
92 args = silc_notify_get_args(payload);
97 case SILC_NOTIFY_TYPE_JOIN:
99 * Distribute the notify to local clients on the channel
101 SILC_LOG_DEBUG(("JOIN notify"));
104 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
107 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
111 /* Get channel entry */
112 channel = silc_idlist_find_channel_by_id(server->global_list,
115 channel = silc_idlist_find_channel_by_id(server->local_list,
118 silc_free(channel_id);
122 silc_free(channel_id);
125 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
128 client_id = silc_id_payload_parse_id(tmp, tmp_len);
132 /* Send to channel */
133 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
134 FALSE, packet->buffer->data,
135 packet->buffer->len, FALSE);
137 /* If the the client is not in local list we check global list (ie. the
138 channel will be global channel) and if it does not exist then create
139 entry for the client. */
140 client = silc_idlist_find_client_by_id(server->global_list,
143 client = silc_idlist_find_client_by_id(server->local_list,
146 /* If router did not find the client the it is bogus */
147 if (server->server_type == SILC_ROUTER)
151 silc_idlist_add_client(server->global_list, NULL, 0, NULL, NULL,
152 silc_id_dup(client_id, SILC_ID_CLIENT),
153 sock->user_data, NULL);
155 silc_free(client_id);
159 client->data.registered = TRUE;
163 /* Do not add client to channel if it is there already */
164 if (silc_server_client_on_channel(client, channel))
167 if (server->server_type == SILC_SERVER &&
168 sock->type == SILC_SOCKET_TYPE_ROUTER)
169 /* The channel is global now */
170 channel->global_users = TRUE;
172 /* JOIN the global client to the channel (local clients (if router
173 created the channel) is joined in the pending JOIN command). */
174 chl = silc_calloc(1, sizeof(*chl));
175 chl->client = client;
176 chl->channel = channel;
177 silc_list_add(channel->user_list, chl);
178 silc_list_add(client->channels, chl);
179 silc_free(client_id);
183 case SILC_NOTIFY_TYPE_LEAVE:
185 * Distribute the notify to local clients on the channel
187 SILC_LOG_DEBUG(("LEAVE notify"));
189 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
190 packet->dst_id_type);
194 /* Get channel entry */
195 channel = silc_idlist_find_channel_by_id(server->global_list,
198 channel = silc_idlist_find_channel_by_id(server->local_list,
201 silc_free(channel_id);
207 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
209 silc_free(channel_id);
212 client_id = silc_id_payload_parse_id(tmp, tmp_len);
214 silc_free(channel_id);
218 /* Send to channel */
219 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
220 FALSE, packet->buffer->data,
221 packet->buffer->len, FALSE);
223 /* Get client entry */
224 client = silc_idlist_find_client_by_id(server->global_list,
227 client = silc_idlist_find_client_by_id(server->local_list,
230 silc_free(client_id);
231 silc_free(channel_id);
235 silc_free(client_id);
237 /* Remove the user from channel */
238 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
241 case SILC_NOTIFY_TYPE_SIGNOFF:
243 * Distribute the notify to local clients on the channel
245 SILC_LOG_DEBUG(("SIGNOFF notify"));
248 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
251 client_id = silc_id_payload_parse_id(tmp, tmp_len);
255 /* Get client entry */
256 client = silc_idlist_find_client_by_id(server->global_list,
259 client = silc_idlist_find_client_by_id(server->local_list,
262 silc_free(client_id);
266 silc_free(client_id);
268 /* Get signoff message */
269 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
273 /* Remove the client from all channels */
274 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, TRUE);
276 client->data.registered = FALSE;
277 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
280 /* Remove the client entry */
281 if (!silc_idlist_del_client(server->global_list, client))
282 silc_idlist_del_client(server->local_list, client);
286 case SILC_NOTIFY_TYPE_TOPIC_SET:
288 * Distribute the notify to local clients on the channel
291 SILC_LOG_DEBUG(("TOPIC SET notify"));
293 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
294 packet->dst_id_type);
298 /* Get channel entry */
299 channel = silc_idlist_find_channel_by_id(server->global_list,
302 channel = silc_idlist_find_channel_by_id(server->local_list,
305 silc_free(channel_id);
311 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
313 silc_free(channel_id);
318 silc_free(channel->topic);
319 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
320 memcpy(channel->topic, tmp, tmp_len);
322 /* Send the same notify to the channel */
323 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
324 FALSE, packet->buffer->data,
325 packet->buffer->len, FALSE);
326 silc_free(channel_id);
329 case SILC_NOTIFY_TYPE_NICK_CHANGE:
332 * Distribute the notify to local clients on the channel
334 unsigned char *id, *id2;
336 SILC_LOG_DEBUG(("NICK CHANGE notify"));
338 /* Get old client ID */
339 id = silc_argument_get_arg_type(args, 1, &tmp_len);
342 client_id = silc_id_payload_parse_id(id, tmp_len);
346 /* Get new client ID */
347 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
350 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
354 SILC_LOG_DEBUG(("Old Client ID id(%s)",
355 silc_id_render(client_id, SILC_ID_CLIENT)));
356 SILC_LOG_DEBUG(("New Client ID id(%s)",
357 silc_id_render(client_id2, SILC_ID_CLIENT)));
359 /* Replace the Client ID */
360 client = silc_idlist_replace_client_id(server->global_list, client_id,
363 client = silc_idlist_replace_client_id(server->local_list, client_id,
367 /* The nickname is not valid anymore, set it NULL. This causes that
368 the nickname will be queried if someone wants to know it. */
369 if (client->nickname)
370 silc_free(client->nickname);
371 client->nickname = NULL;
373 /* Send the NICK_CHANGE notify type to local clients on the channels
374 this client is joined to. */
375 silc_server_send_notify_on_channels(server, NULL, client,
376 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
381 silc_free(client_id);
383 silc_free(client_id2);
387 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
389 * Distribute the notify to local clients on the channel
392 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
394 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
395 packet->dst_id_type);
399 /* Get channel entry */
400 channel = silc_idlist_find_channel_by_id(server->global_list,
403 channel = silc_idlist_find_channel_by_id(server->local_list,
406 silc_free(channel_id);
411 /* Send the same notify to the channel */
412 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
413 FALSE, packet->buffer->data,
414 packet->buffer->len, FALSE);
417 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
419 silc_free(channel_id);
423 SILC_GET32_MSB(mode, tmp);
426 channel->mode = mode;
427 silc_free(channel_id);
430 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
432 * Distribute the notify to local clients on the channel
435 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
437 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
438 packet->dst_id_type);
442 /* Get channel entry */
443 channel = silc_idlist_find_channel_by_id(server->global_list,
446 channel = silc_idlist_find_channel_by_id(server->local_list,
449 silc_free(channel_id);
455 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
457 silc_free(channel_id);
461 SILC_GET32_MSB(mode, tmp);
463 /* Get target client */
464 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
467 client_id = silc_id_payload_parse_id(tmp, tmp_len);
471 /* Get client entry */
472 client = silc_idlist_find_client_by_id(server->global_list,
475 client = silc_idlist_find_client_by_id(server->local_list,
478 silc_free(client_id);
482 silc_free(client_id);
484 /* Get entry to the channel user list */
485 silc_list_start(channel->user_list);
486 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
487 if (chl->client == client) {
488 /* Change the mode */
493 /* Send the same notify to the channel */
494 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
495 FALSE, packet->buffer->data,
496 packet->buffer->len, FALSE);
497 silc_free(channel_id);
500 case SILC_NOTIFY_TYPE_INVITE:
502 if (packet->dst_id_type == SILC_ID_CLIENT)
505 SILC_LOG_DEBUG(("INVITE notify"));
508 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
511 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
515 /* Get channel entry */
516 channel = silc_idlist_find_channel_by_id(server->global_list,
519 channel = silc_idlist_find_channel_by_id(server->local_list,
522 silc_free(channel_id);
526 silc_free(channel_id);
528 /* Get the added invite */
529 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
531 if (!channel->invite_list)
532 channel->invite_list = silc_calloc(tmp_len + 2,
533 sizeof(*channel->invite_list));
535 channel->invite_list = silc_realloc(channel->invite_list,
536 sizeof(*channel->invite_list) *
538 strlen(channel->invite_list) +
540 if (tmp[tmp_len - 1] == ',')
541 tmp[tmp_len - 1] = '\0';
543 strncat(channel->invite_list, tmp, tmp_len);
544 strncat(channel->invite_list, ",", 1);
547 /* Get the deleted invite */
548 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
549 if (tmp && channel->invite_list) {
550 char *start, *end, *n;
552 if (!strncmp(channel->invite_list, tmp,
553 strlen(channel->invite_list) - 1)) {
554 silc_free(channel->invite_list);
555 channel->invite_list = NULL;
557 start = strstr(channel->invite_list, tmp);
558 if (start && strlen(start) >= tmp_len) {
559 end = start + tmp_len;
560 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
561 strncat(n, channel->invite_list, start - channel->invite_list);
562 strncat(n, end + 1, ((channel->invite_list +
563 strlen(channel->invite_list)) - end) - 1);
564 silc_free(channel->invite_list);
565 channel->invite_list = n;
572 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
574 * Distribute to the local clients on the channel and change the
578 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
580 /* Get the old Channel ID */
581 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
584 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
588 /* Get the channel entry */
589 channel = silc_idlist_find_channel_by_id(server->global_list,
592 channel = silc_idlist_find_channel_by_id(server->local_list,
595 silc_free(channel_id);
600 /* Send the notify to the channel */
601 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
602 FALSE, packet->buffer->data,
603 packet->buffer->len, FALSE);
605 /* Get the new Channel ID */
606 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
609 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
613 /* Replace the Channel ID */
614 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
616 silc_idlist_replace_channel_id(server->local_list, channel_id,
619 silc_free(channel_id);
620 silc_free(channel_id2);
624 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
625 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
628 case SILC_NOTIFY_TYPE_KICKED:
630 * Distribute the notify to local clients on the channel
633 SILC_LOG_DEBUG(("KICKED notify"));
635 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
636 packet->dst_id_type);
640 /* Get channel entry */
641 channel = silc_idlist_find_channel_by_id(server->global_list,
644 channel = silc_idlist_find_channel_by_id(server->local_list,
647 silc_free(channel_id);
651 silc_free(channel_id);
654 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
657 client_id = silc_id_payload_parse_id(tmp, tmp_len);
661 /* Send to channel */
662 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
663 FALSE, packet->buffer->data,
664 packet->buffer->len, FALSE);
666 /* If the the client is not in local list we check global list */
667 client = silc_idlist_find_client_by_id(server->global_list,
670 client = silc_idlist_find_client_by_id(server->local_list,
673 silc_free(client_id);
678 /* Remove the client from channel */
679 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
683 case SILC_NOTIFY_TYPE_KILLED:
686 * Distribute the notify to local clients on channels
691 SILC_LOG_DEBUG(("KILLED notify"));
694 id = silc_argument_get_arg_type(args, 1, &id_len);
697 client_id = silc_id_payload_parse_id(id, id_len);
701 /* If the the client is not in local list we check global list */
702 client = silc_idlist_find_client_by_id(server->global_list,
705 client = silc_idlist_find_client_by_id(server->local_list,
708 silc_free(client_id);
712 silc_free(client_id);
714 /* If the client is one of ours, then close the connection to the
715 client now. This removes the client from all channels as well. */
716 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
717 client->connection) {
718 sock = client->connection;
719 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
720 silc_server_close_connection(server, sock);
725 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
729 /* Send the notify to local clients on the channels except to the
730 client who is killed. */
731 silc_server_send_notify_on_channels(server, client, client,
732 SILC_NOTIFY_TYPE_KILLED,
737 /* Remove the client from all channels */
738 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
744 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
746 * Save the mode of the client.
749 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
752 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
755 client_id = silc_id_payload_parse_id(tmp, tmp_len);
759 /* Get client entry */
760 client = silc_idlist_find_client_by_id(server->global_list,
763 client = silc_idlist_find_client_by_id(server->local_list,
766 silc_free(client_id);
770 silc_free(client_id);
773 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
778 SILC_GET32_MSB(client->mode, tmp);
782 case SILC_NOTIFY_TYPE_BAN:
787 SILC_LOG_DEBUG(("BAN notify"));
790 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
793 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
797 /* Get channel entry */
798 channel = silc_idlist_find_channel_by_id(server->global_list,
801 channel = silc_idlist_find_channel_by_id(server->local_list,
804 silc_free(channel_id);
808 silc_free(channel_id);
810 /* Get the new ban and add it to the ban list */
811 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
813 if (!channel->ban_list)
814 channel->ban_list = silc_calloc(tmp_len + 2,
815 sizeof(*channel->ban_list));
817 channel->ban_list = silc_realloc(channel->ban_list,
818 sizeof(*channel->ban_list) *
820 strlen(channel->ban_list) + 2));
821 strncat(channel->ban_list, tmp, tmp_len);
822 strncat(channel->ban_list, ",", 1);
825 /* Get the ban to be removed and remove it from the list */
826 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
827 if (tmp && channel->ban_list) {
828 char *start, *end, *n;
830 if (!strcmp(channel->ban_list, tmp)) {
831 silc_free(channel->ban_list);
832 channel->ban_list = NULL;
834 start = strstr(channel->ban_list, tmp);
835 if (start && strlen(start) >= tmp_len) {
836 end = start + tmp_len;
837 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
838 strncat(n, channel->ban_list, start - channel->ban_list);
839 strncat(n, end + 1, ((channel->ban_list +
840 strlen(channel->ban_list)) - end) - 1);
841 silc_free(channel->ban_list);
842 channel->ban_list = n;
849 /* Ignore rest of the notify types for now */
850 case SILC_NOTIFY_TYPE_NONE:
851 case SILC_NOTIFY_TYPE_MOTD:
858 silc_notify_payload_free(payload);
861 void silc_server_notify_list(SilcServer server,
862 SilcSocketConnection sock,
863 SilcPacketContext *packet)
865 SilcPacketContext *new;
869 SILC_LOG_DEBUG(("Processing New Notify List"));
871 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
872 packet->src_id_type != SILC_ID_SERVER)
875 /* Make copy of the original packet context, except for the actual
876 data buffer, which we will here now fetch from the original buffer. */
877 new = silc_packet_context_alloc();
878 new->type = SILC_PACKET_NOTIFY;
879 new->flags = packet->flags;
880 new->src_id = packet->src_id;
881 new->src_id_len = packet->src_id_len;
882 new->src_id_type = packet->src_id_type;
883 new->dst_id = packet->dst_id;
884 new->dst_id_len = packet->dst_id_len;
885 new->dst_id_type = packet->dst_id_type;
887 buffer = silc_buffer_alloc(1024);
888 new->buffer = buffer;
890 while (packet->buffer->len) {
891 SILC_GET16_MSB(len, packet->buffer->data + 2);
892 if (len > packet->buffer->len)
895 if (len > buffer->truelen) {
896 silc_buffer_free(buffer);
897 buffer = silc_buffer_alloc(1024 + len);
900 silc_buffer_pull_tail(buffer, len);
901 silc_buffer_put(buffer, packet->buffer->data, len);
903 /* Process the Notify */
904 silc_server_notify(server, sock, new);
906 silc_buffer_push_tail(buffer, len);
907 silc_buffer_pull(packet->buffer, len);
910 silc_buffer_free(buffer);
914 /* Received private message. This resolves the destination of the message
915 and sends the packet. This is used by both server and router. If the
916 destination is our locally connected client this sends the packet to
917 the client. This may also send the message for further routing if
918 the destination is not in our server (or router). */
920 void silc_server_private_message(SilcServer server,
921 SilcSocketConnection sock,
922 SilcPacketContext *packet)
924 SilcSocketConnection dst_sock;
925 SilcIDListData idata;
927 SILC_LOG_DEBUG(("Start"));
929 if (packet->src_id_type != SILC_ID_CLIENT ||
930 packet->dst_id_type != SILC_ID_CLIENT)
936 /* Get the route to the client */
937 dst_sock = silc_server_get_client_route(server, packet->dst_id,
938 packet->dst_id_len, NULL, &idata);
942 /* Send the private message */
943 silc_server_send_private_message(server, dst_sock, idata->send_key,
944 idata->hmac, packet);
947 /* Received private message key packet.. This packet is never for us. It is to
948 the client in the packet's destination ID. Sending of this sort of packet
949 equals sending private message, ie. it is sent point to point from
950 one client to another. */
952 void silc_server_private_message_key(SilcServer server,
953 SilcSocketConnection sock,
954 SilcPacketContext *packet)
956 SilcSocketConnection dst_sock;
957 SilcIDListData idata;
959 SILC_LOG_DEBUG(("Start"));
961 if (packet->src_id_type != SILC_ID_CLIENT ||
962 packet->dst_id_type != SILC_ID_CLIENT)
968 /* Get the route to the client */
969 dst_sock = silc_server_get_client_route(server, packet->dst_id,
970 packet->dst_id_len, NULL, &idata);
974 /* Relay the packet */
975 silc_server_relay_packet(server, dst_sock, idata->send_key,
976 idata->hmac, packet, FALSE);
979 /* Processes incoming command reply packet. The command reply packet may
980 be destined to one of our clients or it may directly for us. We will
981 call the command reply routine after processing the packet. */
983 void silc_server_command_reply(SilcServer server,
984 SilcSocketConnection sock,
985 SilcPacketContext *packet)
987 SilcBuffer buffer = packet->buffer;
988 SilcClientEntry client = NULL;
989 SilcSocketConnection dst_sock;
990 SilcIDListData idata;
991 SilcClientID *id = NULL;
993 SILC_LOG_DEBUG(("Start"));
995 /* Source must be server or router */
996 if (packet->src_id_type != SILC_ID_SERVER &&
997 sock->type != SILC_SOCKET_TYPE_ROUTER)
1000 if (packet->dst_id_type == SILC_ID_CHANNEL)
1003 if (packet->dst_id_type == SILC_ID_CLIENT) {
1004 /* Destination must be one of ours */
1005 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1008 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1010 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1016 if (packet->dst_id_type == SILC_ID_SERVER) {
1017 /* For now this must be for us */
1018 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
1019 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1024 /* Execute command reply locally for the command */
1025 silc_server_command_reply_process(server, sock, buffer);
1027 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1028 /* Relay the packet to the client */
1030 dst_sock = (SilcSocketConnection)client->connection;
1031 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1032 + packet->dst_id_len + packet->padlen);
1034 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1035 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1037 idata = (SilcIDListData)client;
1039 /* Encrypt packet */
1040 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
1043 /* Send the packet */
1044 silc_server_packet_send_real(server, dst_sock, TRUE);
1050 /* Process received channel message. The message can be originated from
1051 client or server. */
1053 void silc_server_channel_message(SilcServer server,
1054 SilcSocketConnection sock,
1055 SilcPacketContext *packet)
1057 SilcChannelEntry channel = NULL;
1058 SilcChannelClientEntry chl;
1059 SilcChannelID *id = NULL;
1060 void *sender = NULL;
1062 SILC_LOG_DEBUG(("Processing channel message"));
1065 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1066 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1070 /* Find channel entry */
1071 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1074 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1076 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1078 SILC_LOG_DEBUG(("Could not find channel"));
1083 /* See that this client is on the channel. If the message is coming
1084 from router we won't do the check as the message is from client that
1085 we don't know about. Also, if the original sender is not client
1086 (as it can be server as well) we don't do the check. */
1087 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1088 packet->src_id_type);
1091 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
1092 packet->src_id_type == SILC_ID_CLIENT) {
1093 silc_list_start(channel->user_list);
1094 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1095 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1098 if (chl == SILC_LIST_END) {
1099 SILC_LOG_DEBUG(("Client not on channel"));
1104 /* If we are router and the packet came from router and private key
1105 has not been set for the channel then we must encrypt the packet
1106 as it was decrypted with the session key shared between us and the
1107 router which sent it. This is so, because cells does not share the
1109 if (server->server_type == SILC_ROUTER &&
1110 sock->type == SILC_SOCKET_TYPE_ROUTER &&
1111 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1113 unsigned int iv_len, i, data_len;
1115 iv_len = silc_cipher_get_block_len(channel->channel_key);
1116 if (channel->iv[0] == '\0')
1117 for (i = 0; i < iv_len; i++) channel->iv[i] =
1118 silc_rng_get_byte(server->rng);
1120 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1122 /* Encode new payload. This encrypts it also. */
1123 SILC_GET16_MSB(data_len, packet->buffer->data);
1124 chp = silc_channel_message_payload_encode(data_len,
1125 packet->buffer->data + 2,
1126 iv_len, channel->iv,
1127 channel->channel_key,
1128 channel->hmac, server->rng);
1129 silc_buffer_put(packet->buffer, chp->data, chp->len);
1130 silc_buffer_free(chp);
1133 /* Distribute the packet to our local clients. This will send the
1134 packet for further routing as well, if needed. */
1135 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1136 packet->src_id_type,
1137 packet->buffer->data,
1138 packet->buffer->len, FALSE);
1147 /* Received channel key packet. We distribute the key to all of our locally
1148 connected clients on the channel. */
1150 void silc_server_channel_key(SilcServer server,
1151 SilcSocketConnection sock,
1152 SilcPacketContext *packet)
1154 SilcBuffer buffer = packet->buffer;
1155 SilcChannelEntry channel;
1157 if (packet->src_id_type != SILC_ID_SERVER)
1160 /* Save the channel key */
1161 channel = silc_server_save_channel_key(server, buffer, NULL);
1165 /* Distribute the key to everybody who is on the channel. If we are router
1166 we will also send it to locally connected servers. */
1167 silc_server_send_channel_key(server, sock, channel, FALSE);
1170 /* Received New Client packet and processes it. Creates Client ID for the
1171 client. Client becomes registered after calling this functions. */
1173 SilcClientEntry silc_server_new_client(SilcServer server,
1174 SilcSocketConnection sock,
1175 SilcPacketContext *packet)
1177 SilcBuffer buffer = packet->buffer;
1178 SilcClientEntry client;
1179 SilcIDCacheEntry cache;
1180 SilcClientID *client_id;
1182 SilcIDListData idata;
1183 char *username = NULL, *realname = NULL, *id_string;
1186 SILC_LOG_DEBUG(("Creating new client"));
1188 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1191 /* Take client entry */
1192 client = (SilcClientEntry)sock->user_data;
1193 idata = (SilcIDListData)client;
1195 /* Fetch the old client cache entry so that we can update it. */
1196 if (!silc_idcache_find_by_context(server->local_list->clients,
1197 sock->user_data, &cache)) {
1198 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1202 /* Parse incoming packet */
1203 ret = silc_buffer_unformat(buffer,
1204 SILC_STR_UI16_STRING_ALLOC(&username),
1205 SILC_STR_UI16_STRING_ALLOC(&realname),
1209 silc_free(username);
1211 silc_free(realname);
1216 silc_free(username);
1218 silc_free(realname);
1219 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1220 "Incomplete client information");
1224 /* Create Client ID */
1225 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1226 username, &client_id);
1228 if (strlen(username) > 128)
1229 username[127] = '\0';
1231 /* Update client entry */
1232 idata->registered = TRUE;
1233 client->nickname = strdup(username);
1234 client->username = username;
1235 client->userinfo = realname ? realname : strdup(" ");
1236 client->id = client_id;
1238 /* Update the cache entry */
1239 cache->id = (void *)client_id;
1240 cache->type = SILC_ID_CLIENT;
1241 cache->data = username;
1242 silc_idcache_sort_by_data(server->local_list->clients);
1244 /* Notify our router about new client on the SILC network */
1245 if (!server->standalone)
1246 silc_server_send_new_id(server, (SilcSocketConnection)
1247 server->router->connection,
1248 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1249 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1251 /* Send the new client ID to the client. */
1252 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1253 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1254 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1255 silc_buffer_format(reply,
1256 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1257 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1258 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1260 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1261 reply->data, reply->len, FALSE);
1262 silc_free(id_string);
1263 silc_buffer_free(reply);
1265 /* Send some nice info to the client */
1266 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1267 ("Welcome to the SILC Network %s@%s",
1268 username, sock->hostname));
1269 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1270 ("Your host is %s, running version %s",
1271 server->config->server_info->server_name,
1273 if (server->server_type == SILC_ROUTER) {
1274 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1275 ("There are %d clients on %d servers in SILC "
1276 "Network", server->stat.clients,
1277 server->stat.servers + 1));
1278 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1279 ("There are %d clients on %d server in our cell",
1280 server->stat.cell_clients,
1281 server->stat.cell_servers + 1));
1282 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1283 ("I have %d clients, %d channels, %d servers and "
1285 server->stat.my_clients,
1286 server->stat.my_channels,
1287 server->stat.my_servers,
1288 server->stat.my_routers));
1289 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1290 ("%d server operators and %d router operators "
1292 server->stat.my_server_ops,
1293 server->stat.my_router_ops));
1295 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1296 ("I have %d clients and %d channels formed",
1297 server->stat.my_clients,
1298 server->stat.my_channels));
1299 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1300 ("%d operators online",
1301 server->stat.my_server_ops));
1303 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1304 ("Your connection is secured with %s cipher, "
1305 "key length %d bits",
1306 idata->send_key->cipher->name,
1307 idata->send_key->cipher->key_len));
1308 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1309 ("Your current nickname is %s",
1313 silc_server_send_motd(server, sock);
1318 /* Create new server. This processes received New Server packet and
1319 saves the received Server ID. The server is our locally connected
1320 server thus we save all the information and save it to local list.
1321 This funtion can be used by both normal server and router server.
1322 If normal server uses this it means that its router has connected
1323 to the server. If router uses this it means that one of the cell's
1324 servers is connected to the router. */
1326 SilcServerEntry silc_server_new_server(SilcServer server,
1327 SilcSocketConnection sock,
1328 SilcPacketContext *packet)
1330 SilcBuffer buffer = packet->buffer;
1331 SilcServerEntry new_server;
1332 SilcIDCacheEntry cache;
1333 SilcServerID *server_id;
1334 SilcIDListData idata;
1335 unsigned char *server_name, *id_string;
1336 unsigned short id_len, name_len;
1339 SILC_LOG_DEBUG(("Creating new server"));
1341 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1342 sock->type != SILC_SOCKET_TYPE_ROUTER)
1345 /* Take server entry */
1346 new_server = (SilcServerEntry)sock->user_data;
1347 idata = (SilcIDListData)new_server;
1349 /* Fetch the old server cache entry so that we can update it. */
1350 if (!silc_idcache_find_by_context(server->local_list->servers,
1351 sock->user_data, &cache)) {
1352 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1356 /* Parse the incoming packet */
1357 ret = silc_buffer_unformat(buffer,
1358 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1359 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1364 silc_free(id_string);
1366 silc_free(server_name);
1370 if (id_len > buffer->len) {
1371 silc_free(id_string);
1372 silc_free(server_name);
1377 server_name[255] = '\0';
1380 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1382 silc_free(id_string);
1383 silc_free(server_name);
1386 silc_free(id_string);
1388 /* Update client entry */
1389 idata->registered = TRUE;
1390 new_server->server_name = server_name;
1391 new_server->id = server_id;
1393 /* Update the cache entry */
1394 cache->id = (void *)server_id;
1395 cache->type = SILC_ID_SERVER;
1396 cache->data = server_name;
1397 silc_idcache_sort_by_data(server->local_list->servers);
1399 /* Distribute the information about new server in the SILC network
1400 to our router. If we are normal server we won't send anything
1401 since this connection must be our router connection. */
1402 if (server->server_type == SILC_ROUTER && !server->standalone &&
1403 server->router->connection != sock)
1404 silc_server_send_new_id(server, server->router->connection,
1405 TRUE, new_server->id, SILC_ID_SERVER,
1406 SILC_ID_SERVER_LEN);
1408 if (server->server_type == SILC_ROUTER)
1409 server->stat.cell_servers++;
1414 /* Processes incoming New ID packet. New ID Payload is used to distribute
1415 information about newly registered clients and servers. */
1417 static void silc_server_new_id_real(SilcServer server,
1418 SilcSocketConnection sock,
1419 SilcPacketContext *packet,
1422 SilcBuffer buffer = packet->buffer;
1424 SilcServerEntry router;
1425 SilcSocketConnection router_sock;
1428 unsigned char *hash = NULL;
1431 SILC_LOG_DEBUG(("Processing new ID"));
1433 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1434 server->server_type == SILC_SERVER ||
1435 packet->src_id_type != SILC_ID_SERVER)
1438 idp = silc_id_payload_parse(buffer);
1442 id_type = silc_id_payload_get_type(idp);
1444 /* Normal server cannot have other normal server connections */
1445 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1448 id = silc_id_payload_get_id(idp);
1452 /* If the sender of this packet is server and we are router we need to
1453 broadcast this packet to other routers in the network. */
1454 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1455 sock->type == SILC_SOCKET_TYPE_SERVER &&
1456 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1457 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1458 silc_server_packet_send(server, server->router->connection,
1460 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1461 buffer->data, buffer->len, FALSE);
1464 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1465 id_list = server->local_list;
1467 id_list = server->global_list;
1470 router = sock->user_data;
1473 case SILC_ID_CLIENT:
1475 SilcClientEntry entry;
1477 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1478 silc_id_render(id, SILC_ID_CLIENT),
1479 sock->type == SILC_SOCKET_TYPE_SERVER ?
1480 "Server" : "Router", sock->hostname));
1482 /* As a router we keep information of all global information in our
1483 global list. Cell wide information however is kept in the local
1484 list. The client is put to global list and we will take the hash
1485 value of the Client ID and save it to the ID Cache system for fast
1486 searching in the future. */
1487 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1488 sizeof(unsigned char));
1489 memcpy(hash, ((SilcClientID *)id)->hash,
1490 sizeof(((SilcClientID *)id)->hash));
1491 entry = silc_idlist_add_client(id_list, hash,
1492 sizeof(((SilcClientID *)id)->hash),
1493 NULL, NULL, id, router, NULL);
1494 entry->nickname = NULL;
1495 entry->data.registered = TRUE;
1497 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1498 server->stat.cell_clients++;
1499 server->stat.clients++;
1503 case SILC_ID_SERVER:
1504 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1505 silc_id_render(id, SILC_ID_SERVER),
1506 sock->type == SILC_SOCKET_TYPE_SERVER ?
1507 "Server" : "Router", sock->hostname));
1509 /* As a router we keep information of all global information in our global
1510 list. Cell wide information however is kept in the local list. */
1511 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1513 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1514 server->stat.cell_servers++;
1515 server->stat.servers++;
1518 case SILC_ID_CHANNEL:
1519 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1527 silc_id_payload_free(idp);
1531 /* Processes incoming New ID packet. New ID Payload is used to distribute
1532 information about newly registered clients and servers. */
1534 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1535 SilcPacketContext *packet)
1537 silc_server_new_id_real(server, sock, packet, TRUE);
1540 /* Receoved New Id List packet, list of New ID payloads inside one
1541 packet. Process the New ID payloads one by one. */
1543 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1544 SilcPacketContext *packet)
1546 SilcPacketContext *new_id;
1548 unsigned short id_len;
1550 SILC_LOG_DEBUG(("Processing New ID List"));
1552 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1553 packet->src_id_type != SILC_ID_SERVER)
1556 /* If the sender of this packet is server and we are router we need to
1557 broadcast this packet to other routers in the network. Broadcast
1558 this list packet instead of multiple New ID packets. */
1559 if (!server->standalone && server->server_type == SILC_ROUTER &&
1560 sock->type == SILC_SOCKET_TYPE_SERVER &&
1561 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1562 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1563 silc_server_packet_send(server, server->router->connection,
1565 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1566 packet->buffer->data, packet->buffer->len, FALSE);
1569 /* Make copy of the original packet context, except for the actual
1570 data buffer, which we will here now fetch from the original buffer. */
1571 new_id = silc_packet_context_alloc();
1572 new_id->type = SILC_PACKET_NEW_ID;
1573 new_id->flags = packet->flags;
1574 new_id->src_id = packet->src_id;
1575 new_id->src_id_len = packet->src_id_len;
1576 new_id->src_id_type = packet->src_id_type;
1577 new_id->dst_id = packet->dst_id;
1578 new_id->dst_id_len = packet->dst_id_len;
1579 new_id->dst_id_type = packet->dst_id_type;
1581 idp = silc_buffer_alloc(256);
1582 new_id->buffer = idp;
1584 while (packet->buffer->len) {
1585 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1586 if ((id_len > packet->buffer->len) ||
1587 (id_len > idp->truelen))
1590 silc_buffer_pull_tail(idp, 4 + id_len);
1591 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1593 /* Process the New ID */
1594 silc_server_new_id_real(server, sock, new_id, FALSE);
1596 silc_buffer_push_tail(idp, 4 + id_len);
1597 silc_buffer_pull(packet->buffer, 4 + id_len);
1600 silc_buffer_free(idp);
1604 /* Received New Channel packet. Information about new channels in the
1605 network are distributed using this packet. Save the information about
1606 the new channel. This usually comes from router but also normal server
1607 can send this to notify channels it has when it connects to us. */
1609 void silc_server_new_channel(SilcServer server,
1610 SilcSocketConnection sock,
1611 SilcPacketContext *packet)
1613 SilcChannelPayload payload;
1614 SilcChannelID *channel_id;
1616 unsigned int name_len;
1618 unsigned int id_len;
1620 SILC_LOG_DEBUG(("Processing New Channel"));
1622 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1623 packet->src_id_type != SILC_ID_SERVER ||
1624 server->server_type == SILC_SERVER)
1627 /* Parse the channel payload */
1628 payload = silc_channel_payload_parse(packet->buffer);
1632 /* Get the channel ID */
1633 channel_id = silc_channel_get_id_parse(payload);
1635 silc_channel_payload_free(payload);
1639 channel_name = silc_channel_get_name(payload, &name_len);
1641 channel_name[255] = '\0';
1643 id = silc_channel_get_id(payload, &id_len);
1645 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1646 /* Add the server to global list as it is coming from router. It
1647 cannot be our own channel as it is coming from router. */
1649 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1650 silc_id_render(channel_id, SILC_ID_CHANNEL),
1653 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1654 0, channel_id, server->router->connection,
1657 server->stat.channels++;
1659 /* The channel is coming from our server, thus it is in our cell
1660 we will add it to our local list. */
1661 SilcChannelEntry channel;
1664 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1665 silc_id_render(channel_id, SILC_ID_CHANNEL),
1668 /* Check that we don't already have this channel */
1669 channel = silc_idlist_find_channel_by_name(server->local_list,
1670 channel_name, NULL);
1672 channel = silc_idlist_find_channel_by_name(server->global_list,
1673 channel_name, NULL);
1675 /* If the channel does not exist, then create it. We create the channel
1676 with the channel ID provided by the server. This creates a new
1677 key to the channel as well that we will send to the server. */
1679 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1683 silc_channel_payload_free(payload);
1684 silc_free(channel_id);
1688 /* Send the new channel key to the server */
1689 chk = silc_channel_key_payload_encode(id_len, id,
1690 strlen(channel->channel_key->
1692 channel->channel_key->cipher->name,
1693 channel->key_len / 8,
1695 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1696 chk->data, chk->len, FALSE);
1697 silc_buffer_free(chk);
1700 /* The channel exist by that name, check whether the ID's match.
1701 If they don't then we'll force the server to use the ID we have.
1702 We also create a new key for the channel. */
1704 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1705 /* They don't match, send CHANNEL_CHANGE notify to the server to
1706 force the ID change. */
1707 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1708 silc_server_send_notify_channel_change(server, sock, FALSE,
1711 SILC_ID_CHANNEL_LEN);
1714 /* Create new key for the channel and send it to the server and
1715 everybody else possibly on the channel. */
1717 silc_server_create_channel_key(server, channel, 0);
1719 /* Send to the channel */
1720 silc_server_send_channel_key(server, sock, channel, FALSE);
1722 /* Send to the server */
1723 chk = silc_channel_key_payload_encode(id_len, id,
1724 strlen(channel->channel_key->
1726 channel->channel_key->cipher->name,
1727 channel->key_len / 8,
1729 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1730 chk->data, chk->len, FALSE);
1731 silc_buffer_free(chk);
1732 silc_free(channel_id);
1734 /* Since the channel is coming from server and we also know about it
1735 then send the JOIN notify to the server so that it see's our
1736 users on the channel "joining" the channel. */
1742 /* Received New Channel List packet, list of New Channel List payloads inside
1743 one packet. Process the New Channel payloads one by one. */
1745 void silc_server_new_channel_list(SilcServer server,
1746 SilcSocketConnection sock,
1747 SilcPacketContext *packet)
1749 SilcPacketContext *new;
1751 unsigned short len1, len2;
1753 SILC_LOG_DEBUG(("Processing New Channel List"));
1755 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1756 packet->src_id_type != SILC_ID_SERVER ||
1757 server->server_type == SILC_SERVER)
1760 /* If the sender of this packet is server and we are router we need to
1761 broadcast this packet to other routers in the network. Broadcast
1762 this list packet instead of multiple New Channel packets. */
1763 if (!server->standalone && server->server_type == SILC_ROUTER &&
1764 sock->type == SILC_SOCKET_TYPE_SERVER &&
1765 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1766 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1767 silc_server_packet_send(server, server->router->connection,
1769 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1770 packet->buffer->data, packet->buffer->len, FALSE);
1773 /* Make copy of the original packet context, except for the actual
1774 data buffer, which we will here now fetch from the original buffer. */
1775 new = silc_packet_context_alloc();
1776 new->type = SILC_PACKET_NEW_CHANNEL;
1777 new->flags = packet->flags;
1778 new->src_id = packet->src_id;
1779 new->src_id_len = packet->src_id_len;
1780 new->src_id_type = packet->src_id_type;
1781 new->dst_id = packet->dst_id;
1782 new->dst_id_len = packet->dst_id_len;
1783 new->dst_id_type = packet->dst_id_type;
1785 buffer = silc_buffer_alloc(512);
1786 new->buffer = buffer;
1788 while (packet->buffer->len) {
1789 SILC_GET16_MSB(len1, packet->buffer->data);
1790 if ((len1 > packet->buffer->len) ||
1791 (len1 > buffer->truelen))
1794 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1795 if ((len2 > packet->buffer->len) ||
1796 (len2 > buffer->truelen))
1799 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1800 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1802 /* Process the New Channel */
1803 silc_server_new_channel(server, sock, new);
1805 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1806 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1809 silc_buffer_free(buffer);
1813 /* Received key agreement packet. This packet is never for us. It is to
1814 the client in the packet's destination ID. Sending of this sort of packet
1815 equals sending private message, ie. it is sent point to point from
1816 one client to another. */
1818 void silc_server_key_agreement(SilcServer server,
1819 SilcSocketConnection sock,
1820 SilcPacketContext *packet)
1822 SilcSocketConnection dst_sock;
1823 SilcIDListData idata;
1825 SILC_LOG_DEBUG(("Start"));
1827 if (packet->src_id_type != SILC_ID_CLIENT ||
1828 packet->dst_id_type != SILC_ID_CLIENT)
1831 if (!packet->dst_id)
1834 /* Get the route to the client */
1835 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1836 packet->dst_id_len, NULL, &idata);
1840 /* Relay the packet */
1841 silc_server_relay_packet(server, dst_sock, idata->send_key,
1842 idata->hmac, packet, FALSE);