5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 extern char *server_version;
30 /* Received notify packet. Server can receive notify packets from router.
31 Server then relays the notify messages to clients if needed. */
33 void silc_server_notify(SilcServer server,
34 SilcSocketConnection sock,
35 SilcPacketContext *packet)
37 SilcNotifyPayload payload;
39 SilcArgumentPayload args;
40 SilcChannelID *channel_id;
41 SilcClientID *client_id, *client_id2;
42 SilcChannelEntry channel;
43 SilcClientEntry client;
44 SilcChannelClientEntry chl;
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:
573 SILC_LOG_DEBUG(("CHANNEL CHANGE notify (not-impl XXX)"));
576 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
577 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
580 case SILC_NOTIFY_TYPE_KICKED:
582 * Distribute the notify to local clients on the channel
585 SILC_LOG_DEBUG(("KICKED notify"));
587 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
588 packet->dst_id_type);
592 /* Get channel entry */
593 channel = silc_idlist_find_channel_by_id(server->global_list,
596 channel = silc_idlist_find_channel_by_id(server->local_list,
599 silc_free(channel_id);
603 silc_free(channel_id);
606 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
609 client_id = silc_id_payload_parse_id(tmp, tmp_len);
613 /* Send to channel */
614 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
615 FALSE, packet->buffer->data,
616 packet->buffer->len, FALSE);
618 /* If the the client is not in local list we check global list */
619 client = silc_idlist_find_client_by_id(server->global_list,
622 client = silc_idlist_find_client_by_id(server->local_list,
625 silc_free(client_id);
630 /* Remove the client from channel */
631 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
635 case SILC_NOTIFY_TYPE_KILLED:
638 * Distribute the notify to local clients on channels
643 SILC_LOG_DEBUG(("KILLED notify"));
646 id = silc_argument_get_arg_type(args, 1, &id_len);
649 client_id = silc_id_payload_parse_id(id, id_len);
653 /* If the the client is not in local list we check global list */
654 client = silc_idlist_find_client_by_id(server->global_list,
657 client = silc_idlist_find_client_by_id(server->local_list,
660 silc_free(client_id);
664 silc_free(client_id);
666 /* If the client is one of ours, then close the connection to the
667 client now. This removes the client from all channels as well. */
668 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
669 client->connection) {
670 sock = client->connection;
671 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
672 silc_server_close_connection(server, sock);
677 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
681 /* Send the notify to local clients on the channels except to the
682 client who is killed. */
683 silc_server_send_notify_on_channels(server, client, client,
684 SILC_NOTIFY_TYPE_KILLED,
689 /* Remove the client from all channels */
690 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
696 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
698 * Save the mode of the client.
701 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
704 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
707 client_id = silc_id_payload_parse_id(tmp, tmp_len);
711 /* Get client entry */
712 client = silc_idlist_find_client_by_id(server->global_list,
715 client = silc_idlist_find_client_by_id(server->local_list,
718 silc_free(client_id);
722 silc_free(client_id);
725 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
730 SILC_GET32_MSB(client->mode, tmp);
734 case SILC_NOTIFY_TYPE_BAN:
739 SILC_LOG_DEBUG(("BAN notify"));
742 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
745 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
749 /* Get channel entry */
750 channel = silc_idlist_find_channel_by_id(server->global_list,
753 channel = silc_idlist_find_channel_by_id(server->local_list,
756 silc_free(channel_id);
760 silc_free(channel_id);
762 /* Get the new ban and add it to the ban list */
763 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
765 if (!channel->ban_list)
766 channel->ban_list = silc_calloc(tmp_len + 2,
767 sizeof(*channel->ban_list));
769 channel->ban_list = silc_realloc(channel->ban_list,
770 sizeof(*channel->ban_list) *
772 strlen(channel->ban_list) + 2));
773 strncat(channel->ban_list, tmp, tmp_len);
774 strncat(channel->ban_list, ",", 1);
777 /* Get the ban to be removed and remove it from the list */
778 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
779 if (tmp && channel->ban_list) {
780 char *start, *end, *n;
782 if (!strcmp(channel->ban_list, tmp)) {
783 silc_free(channel->ban_list);
784 channel->ban_list = NULL;
786 start = strstr(channel->ban_list, tmp);
787 if (start && strlen(start) >= tmp_len) {
788 end = start + tmp_len;
789 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
790 strncat(n, channel->ban_list, start - channel->ban_list);
791 strncat(n, end + 1, ((channel->ban_list +
792 strlen(channel->ban_list)) - end) - 1);
793 silc_free(channel->ban_list);
794 channel->ban_list = n;
801 /* Ignore rest of the notify types for now */
802 case SILC_NOTIFY_TYPE_NONE:
803 case SILC_NOTIFY_TYPE_MOTD:
810 silc_notify_payload_free(payload);
813 void silc_server_notify_list(SilcServer server,
814 SilcSocketConnection sock,
815 SilcPacketContext *packet)
817 SilcPacketContext *new;
821 SILC_LOG_DEBUG(("Processing New Notify List"));
823 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
824 packet->src_id_type != SILC_ID_SERVER)
827 /* Make copy of the original packet context, except for the actual
828 data buffer, which we will here now fetch from the original buffer. */
829 new = silc_packet_context_alloc();
830 new->type = SILC_PACKET_NOTIFY;
831 new->flags = packet->flags;
832 new->src_id = packet->src_id;
833 new->src_id_len = packet->src_id_len;
834 new->src_id_type = packet->src_id_type;
835 new->dst_id = packet->dst_id;
836 new->dst_id_len = packet->dst_id_len;
837 new->dst_id_type = packet->dst_id_type;
839 buffer = silc_buffer_alloc(1024);
840 new->buffer = buffer;
842 while (packet->buffer->len) {
843 SILC_GET16_MSB(len, packet->buffer->data + 2);
844 if (len > packet->buffer->len)
847 if (len > buffer->truelen) {
848 silc_buffer_free(buffer);
849 buffer = silc_buffer_alloc(1024 + len);
852 silc_buffer_pull_tail(buffer, len);
853 silc_buffer_put(buffer, packet->buffer->data, len);
855 /* Process the Notify */
856 silc_server_notify(server, sock, new);
858 silc_buffer_push_tail(buffer, len);
859 silc_buffer_pull(packet->buffer, len);
862 silc_buffer_free(buffer);
866 /* Received private message. This resolves the destination of the message
867 and sends the packet. This is used by both server and router. If the
868 destination is our locally connected client this sends the packet to
869 the client. This may also send the message for further routing if
870 the destination is not in our server (or router). */
872 void silc_server_private_message(SilcServer server,
873 SilcSocketConnection sock,
874 SilcPacketContext *packet)
876 SilcSocketConnection dst_sock;
877 SilcIDListData idata;
879 SILC_LOG_DEBUG(("Start"));
881 if (packet->src_id_type != SILC_ID_CLIENT ||
882 packet->dst_id_type != SILC_ID_CLIENT)
888 /* Get the route to the client */
889 dst_sock = silc_server_get_client_route(server, packet->dst_id,
890 packet->dst_id_len, NULL, &idata);
894 /* Send the private message */
895 silc_server_send_private_message(server, dst_sock, idata->send_key,
896 idata->hmac, packet);
899 /* Received private message key packet.. This packet is never for us. It is to
900 the client in the packet's destination ID. Sending of this sort of packet
901 equals sending private message, ie. it is sent point to point from
902 one client to another. */
904 void silc_server_private_message_key(SilcServer server,
905 SilcSocketConnection sock,
906 SilcPacketContext *packet)
908 SilcSocketConnection dst_sock;
909 SilcIDListData idata;
911 SILC_LOG_DEBUG(("Start"));
913 if (packet->src_id_type != SILC_ID_CLIENT ||
914 packet->dst_id_type != SILC_ID_CLIENT)
920 /* Get the route to the client */
921 dst_sock = silc_server_get_client_route(server, packet->dst_id,
922 packet->dst_id_len, NULL, &idata);
926 /* Relay the packet */
927 silc_server_relay_packet(server, dst_sock, idata->send_key,
928 idata->hmac, packet, FALSE);
931 /* Processes incoming command reply packet. The command reply packet may
932 be destined to one of our clients or it may directly for us. We will
933 call the command reply routine after processing the packet. */
935 void silc_server_command_reply(SilcServer server,
936 SilcSocketConnection sock,
937 SilcPacketContext *packet)
939 SilcBuffer buffer = packet->buffer;
940 SilcClientEntry client = NULL;
941 SilcSocketConnection dst_sock;
942 SilcIDListData idata;
943 SilcClientID *id = NULL;
945 SILC_LOG_DEBUG(("Start"));
947 /* Source must be server or router */
948 if (packet->src_id_type != SILC_ID_SERVER &&
949 sock->type != SILC_SOCKET_TYPE_ROUTER)
952 if (packet->dst_id_type == SILC_ID_CHANNEL)
955 if (packet->dst_id_type == SILC_ID_CLIENT) {
956 /* Destination must be one of ours */
957 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
960 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
962 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
968 if (packet->dst_id_type == SILC_ID_SERVER) {
969 /* For now this must be for us */
970 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
971 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
976 /* Execute command reply locally for the command */
977 silc_server_command_reply_process(server, sock, buffer);
979 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
980 /* Relay the packet to the client */
982 dst_sock = (SilcSocketConnection)client->connection;
983 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
984 + packet->dst_id_len + packet->padlen);
986 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
987 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
989 idata = (SilcIDListData)client;
992 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
995 /* Send the packet */
996 silc_server_packet_send_real(server, dst_sock, TRUE);
1002 /* Process received channel message. The message can be originated from
1003 client or server. */
1005 void silc_server_channel_message(SilcServer server,
1006 SilcSocketConnection sock,
1007 SilcPacketContext *packet)
1009 SilcChannelEntry channel = NULL;
1010 SilcChannelClientEntry chl;
1011 SilcChannelID *id = NULL;
1012 void *sender = NULL;
1014 SILC_LOG_DEBUG(("Processing channel message"));
1017 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1018 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1022 /* Find channel entry */
1023 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1026 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1028 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1030 SILC_LOG_DEBUG(("Could not find channel"));
1035 /* See that this client is on the channel. If the message is coming
1036 from router we won't do the check as the message is from client that
1037 we don't know about. Also, if the original sender is not client
1038 (as it can be server as well) we don't do the check. */
1039 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1040 packet->src_id_type);
1043 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
1044 packet->src_id_type == SILC_ID_CLIENT) {
1045 silc_list_start(channel->user_list);
1046 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1047 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1050 if (chl == SILC_LIST_END) {
1051 SILC_LOG_DEBUG(("Client not on channel"));
1056 /* If we are router and the packet came from router and private key
1057 has not been set for the channel then we must encrypt the packet
1058 as it was decrypted with the session key shared between us and the
1059 router which sent it. This is so, because cells does not share the
1061 if (server->server_type == SILC_ROUTER &&
1062 sock->type == SILC_SOCKET_TYPE_ROUTER &&
1063 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1065 unsigned int iv_len, i, data_len;
1067 iv_len = silc_cipher_get_block_len(channel->channel_key);
1068 if (channel->iv[0] == '\0')
1069 for (i = 0; i < iv_len; i++) channel->iv[i] =
1070 silc_rng_get_byte(server->rng);
1072 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1074 /* Encode new payload. This encrypts it also. */
1075 SILC_GET16_MSB(data_len, packet->buffer->data);
1076 chp = silc_channel_message_payload_encode(data_len,
1077 packet->buffer->data + 2,
1078 iv_len, channel->iv,
1079 channel->channel_key,
1080 channel->hmac, server->rng);
1081 silc_buffer_put(packet->buffer, chp->data, chp->len);
1082 silc_buffer_free(chp);
1085 /* Distribute the packet to our local clients. This will send the
1086 packet for further routing as well, if needed. */
1087 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1088 packet->src_id_type,
1089 packet->buffer->data,
1090 packet->buffer->len, FALSE);
1099 /* Received channel key packet. We distribute the key to all of our locally
1100 connected clients on the channel. */
1102 void silc_server_channel_key(SilcServer server,
1103 SilcSocketConnection sock,
1104 SilcPacketContext *packet)
1106 SilcBuffer buffer = packet->buffer;
1107 SilcChannelEntry channel;
1109 if (packet->src_id_type != SILC_ID_SERVER)
1112 /* Save the channel key */
1113 channel = silc_server_save_channel_key(server, buffer, NULL);
1117 /* Distribute the key to everybody who is on the channel. If we are router
1118 we will also send it to locally connected servers. */
1119 silc_server_send_channel_key(server, sock, channel, FALSE);
1122 /* Received New Client packet and processes it. Creates Client ID for the
1123 client. Client becomes registered after calling this functions. */
1125 SilcClientEntry silc_server_new_client(SilcServer server,
1126 SilcSocketConnection sock,
1127 SilcPacketContext *packet)
1129 SilcBuffer buffer = packet->buffer;
1130 SilcClientEntry client;
1131 SilcIDCacheEntry cache;
1132 SilcClientID *client_id;
1134 SilcIDListData idata;
1135 char *username = NULL, *realname = NULL, *id_string;
1138 SILC_LOG_DEBUG(("Creating new client"));
1140 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1143 /* Take client entry */
1144 client = (SilcClientEntry)sock->user_data;
1145 idata = (SilcIDListData)client;
1147 /* Fetch the old client cache entry so that we can update it. */
1148 if (!silc_idcache_find_by_context(server->local_list->clients,
1149 sock->user_data, &cache)) {
1150 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1154 /* Parse incoming packet */
1155 ret = silc_buffer_unformat(buffer,
1156 SILC_STR_UI16_STRING_ALLOC(&username),
1157 SILC_STR_UI16_STRING_ALLOC(&realname),
1161 silc_free(username);
1163 silc_free(realname);
1168 silc_free(username);
1170 silc_free(realname);
1171 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1172 "Incomplete client information");
1176 /* Create Client ID */
1177 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1178 username, &client_id);
1180 if (strlen(username) > 128)
1181 username[127] = '\0';
1183 /* Update client entry */
1184 idata->registered = TRUE;
1185 client->nickname = strdup(username);
1186 client->username = username;
1187 client->userinfo = realname ? realname : strdup(" ");
1188 client->id = client_id;
1190 /* Update the cache entry */
1191 cache->id = (void *)client_id;
1192 cache->type = SILC_ID_CLIENT;
1193 cache->data = username;
1194 silc_idcache_sort_by_data(server->local_list->clients);
1196 /* Notify our router about new client on the SILC network */
1197 if (!server->standalone)
1198 silc_server_send_new_id(server, (SilcSocketConnection)
1199 server->router->connection,
1200 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1201 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1203 /* Send the new client ID to the client. */
1204 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1205 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1206 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1207 silc_buffer_format(reply,
1208 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1209 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1210 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1212 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1213 reply->data, reply->len, FALSE);
1214 silc_free(id_string);
1215 silc_buffer_free(reply);
1217 /* Send some nice info to the client */
1218 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1219 ("Welcome to the SILC Network %s@%s",
1220 username, sock->hostname));
1221 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1222 ("Your host is %s, running version %s",
1223 server->config->server_info->server_name,
1225 if (server->server_type == SILC_ROUTER) {
1226 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1227 ("There are %d clients on %d servers in SILC "
1228 "Network", server->stat.clients,
1229 server->stat.servers + 1));
1230 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1231 ("There are %d clients on %d server in our cell",
1232 server->stat.cell_clients,
1233 server->stat.cell_servers + 1));
1234 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1235 ("I have %d clients, %d channels, %d servers and "
1237 server->stat.my_clients,
1238 server->stat.my_channels,
1239 server->stat.my_servers,
1240 server->stat.my_routers));
1241 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1242 ("%d server operators and %d router operators "
1244 server->stat.my_server_ops,
1245 server->stat.my_router_ops));
1247 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1248 ("I have %d clients and %d channels formed",
1249 server->stat.my_clients,
1250 server->stat.my_channels));
1251 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1252 ("%d operators online",
1253 server->stat.my_server_ops));
1255 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1256 ("Your connection is secured with %s cipher, "
1257 "key length %d bits",
1258 idata->send_key->cipher->name,
1259 idata->send_key->cipher->key_len));
1260 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1261 ("Your current nickname is %s",
1265 silc_server_send_motd(server, sock);
1270 /* Create new server. This processes received New Server packet and
1271 saves the received Server ID. The server is our locally connected
1272 server thus we save all the information and save it to local list.
1273 This funtion can be used by both normal server and router server.
1274 If normal server uses this it means that its router has connected
1275 to the server. If router uses this it means that one of the cell's
1276 servers is connected to the router. */
1278 SilcServerEntry silc_server_new_server(SilcServer server,
1279 SilcSocketConnection sock,
1280 SilcPacketContext *packet)
1282 SilcBuffer buffer = packet->buffer;
1283 SilcServerEntry new_server;
1284 SilcIDCacheEntry cache;
1285 SilcServerID *server_id;
1286 SilcIDListData idata;
1287 unsigned char *server_name, *id_string;
1288 unsigned short id_len, name_len;
1291 SILC_LOG_DEBUG(("Creating new server"));
1293 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1294 sock->type != SILC_SOCKET_TYPE_ROUTER)
1297 /* Take server entry */
1298 new_server = (SilcServerEntry)sock->user_data;
1299 idata = (SilcIDListData)new_server;
1301 /* Fetch the old server cache entry so that we can update it. */
1302 if (!silc_idcache_find_by_context(server->local_list->servers,
1303 sock->user_data, &cache)) {
1304 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1308 /* Parse the incoming packet */
1309 ret = silc_buffer_unformat(buffer,
1310 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1311 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1316 silc_free(id_string);
1318 silc_free(server_name);
1322 if (id_len > buffer->len) {
1323 silc_free(id_string);
1324 silc_free(server_name);
1329 server_name[255] = '\0';
1332 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1334 silc_free(id_string);
1335 silc_free(server_name);
1338 silc_free(id_string);
1340 /* Update client entry */
1341 idata->registered = TRUE;
1342 new_server->server_name = server_name;
1343 new_server->id = server_id;
1345 /* Update the cache entry */
1346 cache->id = (void *)server_id;
1347 cache->type = SILC_ID_SERVER;
1348 cache->data = server_name;
1349 silc_idcache_sort_by_data(server->local_list->servers);
1351 /* Distribute the information about new server in the SILC network
1352 to our router. If we are normal server we won't send anything
1353 since this connection must be our router connection. */
1354 if (server->server_type == SILC_ROUTER && !server->standalone &&
1355 server->router->connection != sock)
1356 silc_server_send_new_id(server, server->router->connection,
1357 TRUE, new_server->id, SILC_ID_SERVER,
1358 SILC_ID_SERVER_LEN);
1360 if (server->server_type == SILC_ROUTER)
1361 server->stat.cell_servers++;
1366 /* Processes incoming New ID packet. New ID Payload is used to distribute
1367 information about newly registered clients and servers. */
1369 static void silc_server_new_id_real(SilcServer server,
1370 SilcSocketConnection sock,
1371 SilcPacketContext *packet,
1374 SilcBuffer buffer = packet->buffer;
1376 SilcServerEntry router;
1377 SilcSocketConnection router_sock;
1380 unsigned char *hash = NULL;
1383 SILC_LOG_DEBUG(("Processing new ID"));
1385 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1386 server->server_type == SILC_SERVER ||
1387 packet->src_id_type != SILC_ID_SERVER)
1390 idp = silc_id_payload_parse(buffer);
1394 id_type = silc_id_payload_get_type(idp);
1396 /* Normal server cannot have other normal server connections */
1397 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1400 id = silc_id_payload_get_id(idp);
1404 /* If the sender of this packet is server and we are router we need to
1405 broadcast this packet to other routers in the network. */
1406 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1407 sock->type == SILC_SOCKET_TYPE_SERVER &&
1408 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1409 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1410 silc_server_packet_send(server, server->router->connection,
1412 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1413 buffer->data, buffer->len, FALSE);
1416 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1417 id_list = server->local_list;
1419 id_list = server->global_list;
1422 router = sock->user_data;
1425 case SILC_ID_CLIENT:
1427 SilcClientEntry entry;
1429 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1430 silc_id_render(id, SILC_ID_CLIENT),
1431 sock->type == SILC_SOCKET_TYPE_SERVER ?
1432 "Server" : "Router", sock->hostname));
1434 /* As a router we keep information of all global information in our
1435 global list. Cell wide information however is kept in the local
1436 list. The client is put to global list and we will take the hash
1437 value of the Client ID and save it to the ID Cache system for fast
1438 searching in the future. */
1439 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1440 sizeof(unsigned char));
1441 memcpy(hash, ((SilcClientID *)id)->hash,
1442 sizeof(((SilcClientID *)id)->hash));
1443 entry = silc_idlist_add_client(id_list, hash,
1444 sizeof(((SilcClientID *)id)->hash),
1445 NULL, NULL, id, router, NULL);
1446 entry->nickname = NULL;
1447 entry->data.registered = TRUE;
1449 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1450 server->stat.cell_clients++;
1451 server->stat.clients++;
1454 /* XXX Adding two ID's with same IP number replaces the old entry thus
1455 gives wrong route. Thus, now disabled until figured out a better way
1456 to do this or when removed the whole thing. This could be removed
1457 because entry->router->connection gives always the most optimal route
1458 for the ID anyway (unless new routes (faster perhaps) are established
1459 after receiving this ID, this we don't know however). */
1460 /* Add route cache for this ID */
1461 silc_server_route_add(silc_server_route_hash(
1462 ((SilcClientID *)id)->ip.s_addr,
1463 server->id->port), ((SilcClientID *)id)->ip.s_addr,
1469 case SILC_ID_SERVER:
1470 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1471 silc_id_render(id, SILC_ID_SERVER),
1472 sock->type == SILC_SOCKET_TYPE_SERVER ?
1473 "Server" : "Router", sock->hostname));
1475 /* As a router we keep information of all global information in our global
1476 list. Cell wide information however is kept in the local list. */
1477 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1479 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1480 server->stat.cell_servers++;
1481 server->stat.servers++;
1484 /* Add route cache for this ID */
1485 silc_server_route_add(silc_server_route_hash(
1486 ((SilcServerID *)id)->ip.s_addr,
1487 ((SilcServerID *)id)->port),
1488 ((SilcServerID *)id)->ip.s_addr,
1493 case SILC_ID_CHANNEL:
1494 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1502 silc_id_payload_free(idp);
1506 /* Processes incoming New ID packet. New ID Payload is used to distribute
1507 information about newly registered clients and servers. */
1509 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1510 SilcPacketContext *packet)
1512 silc_server_new_id_real(server, sock, packet, TRUE);
1515 /* Receoved New Id List packet, list of New ID payloads inside one
1516 packet. Process the New ID payloads one by one. */
1518 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1519 SilcPacketContext *packet)
1521 SilcPacketContext *new_id;
1523 unsigned short id_len;
1525 SILC_LOG_DEBUG(("Processing New ID List"));
1527 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1528 packet->src_id_type != SILC_ID_SERVER)
1531 /* If the sender of this packet is server and we are router we need to
1532 broadcast this packet to other routers in the network. Broadcast
1533 this list packet instead of multiple New ID packets. */
1534 if (!server->standalone && server->server_type == SILC_ROUTER &&
1535 sock->type == SILC_SOCKET_TYPE_SERVER &&
1536 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1537 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1538 silc_server_packet_send(server, server->router->connection,
1540 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1541 packet->buffer->data, packet->buffer->len, FALSE);
1544 /* Make copy of the original packet context, except for the actual
1545 data buffer, which we will here now fetch from the original buffer. */
1546 new_id = silc_packet_context_alloc();
1547 new_id->type = SILC_PACKET_NEW_ID;
1548 new_id->flags = packet->flags;
1549 new_id->src_id = packet->src_id;
1550 new_id->src_id_len = packet->src_id_len;
1551 new_id->src_id_type = packet->src_id_type;
1552 new_id->dst_id = packet->dst_id;
1553 new_id->dst_id_len = packet->dst_id_len;
1554 new_id->dst_id_type = packet->dst_id_type;
1556 idp = silc_buffer_alloc(256);
1557 new_id->buffer = idp;
1559 while (packet->buffer->len) {
1560 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1561 if ((id_len > packet->buffer->len) ||
1562 (id_len > idp->truelen))
1565 silc_buffer_pull_tail(idp, 4 + id_len);
1566 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1568 /* Process the New ID */
1569 silc_server_new_id_real(server, sock, new_id, FALSE);
1571 silc_buffer_push_tail(idp, 4 + id_len);
1572 silc_buffer_pull(packet->buffer, 4 + id_len);
1575 silc_buffer_free(idp);
1579 /* Received New Channel packet. Information about new channels in the
1580 network are distributed using this packet. Save the information about
1581 the new channel. This usually comes from router but also normal server
1582 can send this to notify channels it has when it connects to us. */
1584 void silc_server_new_channel(SilcServer server,
1585 SilcSocketConnection sock,
1586 SilcPacketContext *packet)
1588 SilcChannelPayload payload;
1589 SilcChannelID *channel_id;
1591 unsigned int name_len;
1593 unsigned int id_len;
1595 SILC_LOG_DEBUG(("Processing New Channel"));
1597 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1598 packet->src_id_type != SILC_ID_SERVER ||
1599 server->server_type == SILC_SERVER)
1602 /* Parse the channel payload */
1603 payload = silc_channel_payload_parse(packet->buffer);
1607 /* Get the channel ID */
1608 channel_id = silc_channel_get_id_parse(payload);
1610 silc_channel_payload_free(payload);
1614 channel_name = silc_channel_get_name(payload, &name_len);
1616 channel_name[255] = '\0';
1618 id = silc_channel_get_id(payload, &id_len);
1620 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1621 /* Add the server to global list as it is coming from router. It
1622 cannot be our own channel as it is coming from router. */
1624 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1625 silc_id_render(channel_id, SILC_ID_CHANNEL),
1628 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1629 0, channel_id, server->router->connection,
1632 server->stat.channels++;
1634 /* The channel is coming from our server, thus it is in our cell
1635 we will add it to our local list. */
1636 SilcChannelEntry channel;
1639 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1640 silc_id_render(channel_id, SILC_ID_CHANNEL),
1643 /* Check that we don't already have this channel */
1644 channel = silc_idlist_find_channel_by_name(server->local_list,
1645 channel_name, NULL);
1647 channel = silc_idlist_find_channel_by_name(server->global_list,
1648 channel_name, NULL);
1650 /* If the channel does not exist, then create it. We create the channel
1651 with the channel ID provided by the server. This creates a new
1652 key to the channel as well that we will send to the server. */
1654 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1658 silc_channel_payload_free(payload);
1659 silc_free(channel_id);
1663 /* Send the new channel key to the server */
1664 chk = silc_channel_key_payload_encode(id_len, id,
1665 strlen(channel->channel_key->
1667 channel->channel_key->cipher->name,
1668 channel->key_len / 8,
1670 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1671 chk->data, chk->len, FALSE);
1672 silc_buffer_free(chk);
1675 /* The channel exist by that name, check whether the ID's match.
1676 If they don't then we'll force the server to use the ID we have.
1677 We also create a new key for the channel. */
1679 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1680 /* They don't match, send CHANNEL_CHANGE notify to the server to
1681 force the ID change. */
1682 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1683 silc_server_send_notify_channel_change(server, sock, FALSE,
1686 SILC_ID_CHANNEL_LEN);
1689 /* Create new key for the channel and send it to the server and
1690 everybody else possibly on the channel. */
1692 silc_server_create_channel_key(server, channel, 0);
1694 /* Send to the channel */
1695 silc_server_send_channel_key(server, sock, channel, FALSE);
1697 /* Send to the server */
1698 chk = silc_channel_key_payload_encode(id_len, id,
1699 strlen(channel->channel_key->
1701 channel->channel_key->cipher->name,
1702 channel->key_len / 8,
1704 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1705 chk->data, chk->len, FALSE);
1706 silc_buffer_free(chk);
1707 silc_free(channel_id);
1709 /* Since the channel is coming from server and we also know about it
1710 then send the JOIN notify to the server so that it see's our
1711 users on the channel "joining" the channel. */
1717 /* Received New Channel List packet, list of New Channel List payloads inside
1718 one packet. Process the New Channel payloads one by one. */
1720 void silc_server_new_channel_list(SilcServer server,
1721 SilcSocketConnection sock,
1722 SilcPacketContext *packet)
1724 SilcPacketContext *new;
1726 unsigned short len1, len2;
1728 SILC_LOG_DEBUG(("Processing New Channel List"));
1730 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1731 packet->src_id_type != SILC_ID_SERVER ||
1732 server->server_type == SILC_SERVER)
1735 /* If the sender of this packet is server and we are router we need to
1736 broadcast this packet to other routers in the network. Broadcast
1737 this list packet instead of multiple New Channel packets. */
1738 if (!server->standalone && server->server_type == SILC_ROUTER &&
1739 sock->type == SILC_SOCKET_TYPE_SERVER &&
1740 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1741 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1742 silc_server_packet_send(server, server->router->connection,
1744 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1745 packet->buffer->data, packet->buffer->len, FALSE);
1748 /* Make copy of the original packet context, except for the actual
1749 data buffer, which we will here now fetch from the original buffer. */
1750 new = silc_packet_context_alloc();
1751 new->type = SILC_PACKET_NEW_CHANNEL;
1752 new->flags = packet->flags;
1753 new->src_id = packet->src_id;
1754 new->src_id_len = packet->src_id_len;
1755 new->src_id_type = packet->src_id_type;
1756 new->dst_id = packet->dst_id;
1757 new->dst_id_len = packet->dst_id_len;
1758 new->dst_id_type = packet->dst_id_type;
1760 buffer = silc_buffer_alloc(512);
1761 new->buffer = buffer;
1763 while (packet->buffer->len) {
1764 SILC_GET16_MSB(len1, packet->buffer->data);
1765 if ((len1 > packet->buffer->len) ||
1766 (len1 > buffer->truelen))
1769 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1770 if ((len2 > packet->buffer->len) ||
1771 (len2 > buffer->truelen))
1774 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1775 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1777 /* Process the New Channel */
1778 silc_server_new_channel(server, sock, new);
1780 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1781 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1784 silc_buffer_free(buffer);
1788 /* Received key agreement packet. This packet is never for us. It is to
1789 the client in the packet's destination ID. Sending of this sort of packet
1790 equals sending private message, ie. it is sent point to point from
1791 one client to another. */
1793 void silc_server_key_agreement(SilcServer server,
1794 SilcSocketConnection sock,
1795 SilcPacketContext *packet)
1797 SilcSocketConnection dst_sock;
1798 SilcIDListData idata;
1800 SILC_LOG_DEBUG(("Start"));
1802 if (packet->src_id_type != SILC_ID_CLIENT ||
1803 packet->dst_id_type != SILC_ID_CLIENT)
1806 if (!packet->dst_id)
1809 /* Get the route to the client */
1810 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1811 packet->dst_id_len, NULL, &idata);
1815 /* Relay the packet */
1816 silc_server_relay_packet(server, dst_sock, idata->send_key,
1817 idata->hmac, packet, FALSE);