5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 extern char *server_version;
30 /* Received notify packet. Server can receive notify packets from router.
31 Server then relays the notify messages to clients if needed. */
33 void silc_server_notify(SilcServer server,
34 SilcSocketConnection sock,
35 SilcPacketContext *packet)
37 SilcNotifyPayload payload;
39 SilcArgumentPayload args;
40 SilcChannelID *channel_id;
41 SilcClientID *client_id, *client_id2;
42 SilcChannelEntry channel;
43 SilcClientEntry client;
44 SilcChannelClientEntry chl;
49 SILC_LOG_DEBUG(("Start"));
51 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
52 packet->src_id_type != SILC_ID_SERVER)
55 /* If we are router and this packet is not already broadcast packet
56 we will broadcast it. The sending socket really cannot be router or
57 the router is buggy. If this packet is coming from router then it must
58 have the broadcast flag set already and we won't do anything. */
59 if (!server->standalone && server->server_type == SILC_ROUTER &&
60 sock->type == SILC_SOCKET_TYPE_SERVER &&
61 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
62 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
63 silc_server_packet_send(server, server->router->connection, packet->type,
64 packet->flags | SILC_PACKET_FLAG_BROADCAST,
65 packet->buffer->data, packet->buffer->len, FALSE);
68 payload = silc_notify_payload_parse(packet->buffer);
72 type = silc_notify_get_type(payload);
73 args = silc_notify_get_args(payload);
78 case SILC_NOTIFY_TYPE_JOIN:
80 * Distribute the notify to local clients on the channel
82 SILC_LOG_DEBUG(("JOIN notify"));
85 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
88 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
92 /* Get channel entry */
93 channel = silc_idlist_find_channel_by_id(server->local_list,
96 channel = silc_idlist_find_channel_by_id(server->global_list,
99 silc_free(channel_id);
103 silc_free(channel_id);
106 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
109 client_id = silc_id_payload_parse_id(tmp, tmp_len);
113 /* Send to channel */
114 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
115 FALSE, packet->buffer->data,
116 packet->buffer->len, FALSE);
118 /* If the the client is not in local list we check global list (ie. the
119 channel will be global channel) and if it does not exist then create
120 entry for the client. */
121 client = silc_idlist_find_client_by_id(server->local_list,
124 client = silc_idlist_find_client_by_id(server->global_list,
127 /* If router did not find the client the it is bogus */
128 if (server->server_type == SILC_ROUTER)
132 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
133 silc_id_dup(client_id, SILC_ID_CLIENT),
134 sock->user_data, NULL);
136 silc_free(client_id);
142 /* Do not add client to channel if it is there already */
143 if (silc_server_client_on_channel(client, channel))
146 if (server->server_type == SILC_SERVER &&
147 sock->type == SILC_SOCKET_TYPE_ROUTER)
148 /* The channel is global now */
149 channel->global_users = TRUE;
151 /* JOIN the global client to the channel (local clients (if router
152 created the channel) is joined in the pending JOIN command). */
153 chl = silc_calloc(1, sizeof(*chl));
154 chl->client = client;
155 chl->channel = channel;
156 silc_list_add(channel->user_list, chl);
157 silc_list_add(client->channels, chl);
158 silc_free(client_id);
162 case SILC_NOTIFY_TYPE_LEAVE:
164 * Distribute the notify to local clients on the channel
166 SILC_LOG_DEBUG(("LEAVE notify"));
168 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
169 packet->dst_id_type);
173 /* Get channel entry */
174 channel = silc_idlist_find_channel_by_id(server->local_list,
177 channel = silc_idlist_find_channel_by_id(server->global_list,
180 silc_free(channel_id);
186 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
188 silc_free(channel_id);
191 client_id = silc_id_payload_parse_id(tmp, tmp_len);
193 silc_free(channel_id);
197 /* Send to channel */
198 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
199 FALSE, packet->buffer->data,
200 packet->buffer->len, FALSE);
202 /* Get client entry */
203 client = silc_idlist_find_client_by_id(server->global_list,
206 client = silc_idlist_find_client_by_id(server->local_list,
209 silc_free(client_id);
210 silc_free(channel_id);
214 silc_free(client_id);
216 /* Remove the user from channel */
217 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
220 case SILC_NOTIFY_TYPE_SIGNOFF:
222 * Distribute the notify to local clients on the channel
224 SILC_LOG_DEBUG(("SIGNOFF notify"));
227 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
230 client_id = silc_id_payload_parse_id(tmp, tmp_len);
234 /* Get client entry */
235 client = silc_idlist_find_client_by_id(server->global_list,
238 client = silc_idlist_find_client_by_id(server->local_list,
241 silc_free(client_id);
245 silc_free(client_id);
247 /* Get signoff message */
248 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
252 /* Remove the client from all channels */
253 silc_server_remove_from_channels(server, NULL, client, tmp);
255 /* Remove the client entry */
256 if (!silc_idlist_del_client(server->global_list, client))
257 silc_idlist_del_client(server->local_list, client);
260 case SILC_NOTIFY_TYPE_TOPIC_SET:
262 * Distribute the notify to local clients on the channel
265 SILC_LOG_DEBUG(("TOPIC SET notify"));
267 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
268 packet->dst_id_type);
272 /* Get channel entry */
273 channel = silc_idlist_find_channel_by_id(server->local_list,
276 channel = silc_idlist_find_channel_by_id(server->global_list,
279 silc_free(channel_id);
285 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
287 silc_free(channel_id);
292 silc_free(channel->topic);
293 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
294 memcpy(channel->topic, tmp, tmp_len);
296 /* Send the same notify to the channel */
297 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
298 FALSE, packet->buffer->data,
299 packet->buffer->len, FALSE);
300 silc_free(channel_id);
303 case SILC_NOTIFY_TYPE_NICK_CHANGE:
306 * Distribute the notify to local clients on the channel
308 unsigned char *id, *id2;
310 SILC_LOG_DEBUG(("NICK CHANGE notify"));
312 /* Get old client ID */
313 id = silc_argument_get_arg_type(args, 1, &tmp_len);
316 client_id = silc_id_payload_parse_id(id, tmp_len);
320 /* Get new client ID */
321 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
324 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
328 SILC_LOG_DEBUG(("Old Client ID id(%s)",
329 silc_id_render(client_id, SILC_ID_CLIENT)));
330 SILC_LOG_DEBUG(("New Client ID id(%s)",
331 silc_id_render(client_id2, SILC_ID_CLIENT)));
333 /* Replace the Client ID */
334 client = silc_idlist_replace_client_id(server->global_list, client_id,
337 client = silc_idlist_replace_client_id(server->local_list, client_id,
341 /* The nickname is not valid anymore, set it NULL. This causes that
342 the nickname will be queried if someone wants to know it. */
343 if (client->nickname)
344 silc_free(client->nickname);
345 client->nickname = NULL;
347 /* Send the NICK_CHANGE notify type to local clients on the channels
348 this client is joined to. */
349 silc_server_send_notify_on_channels(server, client,
350 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
355 silc_free(client_id);
357 silc_free(client_id2);
361 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
363 * Distribute the notify to local clients on the channel
366 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
368 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
369 packet->dst_id_type);
373 /* Get channel entry */
374 channel = silc_idlist_find_channel_by_id(server->local_list,
377 channel = silc_idlist_find_channel_by_id(server->global_list,
380 silc_free(channel_id);
385 /* Send the same notify to the channel */
386 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
387 FALSE, packet->buffer->data,
388 packet->buffer->len, FALSE);
391 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
393 silc_free(channel_id);
397 SILC_GET32_MSB(mode, tmp);
400 channel->mode = mode;
401 silc_free(channel_id);
404 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
406 * Distribute the notify to local clients on the channel
409 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
411 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
412 packet->dst_id_type);
416 /* Get channel entry */
417 channel = silc_idlist_find_channel_by_id(server->local_list,
420 channel = silc_idlist_find_channel_by_id(server->global_list,
423 silc_free(channel_id);
429 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
431 silc_free(channel_id);
435 SILC_GET32_MSB(mode, tmp);
437 /* Get target client */
438 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
441 client_id = silc_id_payload_parse_id(tmp, tmp_len);
445 /* Get client entry */
446 client = silc_idlist_find_client_by_id(server->global_list,
449 client = silc_idlist_find_client_by_id(server->local_list,
452 silc_free(client_id);
456 silc_free(client_id);
458 /* Get entry to the channel user list */
459 silc_list_start(channel->user_list);
460 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
461 if (chl->client == client) {
462 /* Change the mode */
467 /* Send the same notify to the channel */
468 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
469 FALSE, packet->buffer->data,
470 packet->buffer->len, FALSE);
471 silc_free(channel_id);
474 case SILC_NOTIFY_TYPE_INVITE:
475 SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
478 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
479 SILC_LOG_DEBUG(("CHANNEL CHANGE notify (not-impl XXX)"));
482 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
483 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
486 case SILC_NOTIFY_TYPE_KICKED:
488 * Distribute the notify to local clients on the channel
491 SILC_LOG_DEBUG(("KICKED notify"));
493 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
494 packet->dst_id_type);
498 /* Get channel entry */
499 channel = silc_idlist_find_channel_by_id(server->local_list,
502 channel = silc_idlist_find_channel_by_id(server->global_list,
505 silc_free(channel_id);
509 silc_free(channel_id);
512 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
515 client_id = silc_id_payload_parse_id(tmp, tmp_len);
519 /* Send to channel */
520 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
521 FALSE, packet->buffer->data,
522 packet->buffer->len, FALSE);
524 /* If the the client is not in local list we check global list */
525 client = silc_idlist_find_client_by_id(server->local_list,
528 client = silc_idlist_find_client_by_id(server->global_list,
531 silc_free(client_id);
536 /* Remove the client from channel */
537 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
541 /* Ignore rest of the notify types for now */
542 case SILC_NOTIFY_TYPE_NONE:
543 case SILC_NOTIFY_TYPE_MOTD:
550 silc_notify_payload_free(payload);
553 void silc_server_notify_list(SilcServer server,
554 SilcSocketConnection sock,
555 SilcPacketContext *packet)
557 SilcPacketContext *new;
561 SILC_LOG_DEBUG(("Processing New Notify List"));
563 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
564 packet->src_id_type != SILC_ID_SERVER)
567 /* Make copy of the original packet context, except for the actual
568 data buffer, which we will here now fetch from the original buffer. */
569 new = silc_packet_context_alloc();
570 new->type = SILC_PACKET_NOTIFY;
571 new->flags = packet->flags;
572 new->src_id = packet->src_id;
573 new->src_id_len = packet->src_id_len;
574 new->src_id_type = packet->src_id_type;
575 new->dst_id = packet->dst_id;
576 new->dst_id_len = packet->dst_id_len;
577 new->dst_id_type = packet->dst_id_type;
579 buffer = silc_buffer_alloc(1024);
580 new->buffer = buffer;
582 while (packet->buffer->len) {
583 SILC_GET16_MSB(len, packet->buffer->data + 2);
584 if (len > packet->buffer->len)
587 if (len > buffer->truelen) {
588 silc_buffer_free(buffer);
589 buffer = silc_buffer_alloc(1024 + len);
592 silc_buffer_pull_tail(buffer, len);
593 silc_buffer_put(buffer, packet->buffer->data, len);
595 /* Process the Notify */
596 silc_server_notify(server, sock, new);
598 silc_buffer_push_tail(buffer, len);
599 silc_buffer_pull(packet->buffer, len);
602 silc_buffer_free(buffer);
606 /* Received private message. This resolves the destination of the message
607 and sends the packet. This is used by both server and router. If the
608 destination is our locally connected client this sends the packet to
609 the client. This may also send the message for further routing if
610 the destination is not in our server (or router). */
612 void silc_server_private_message(SilcServer server,
613 SilcSocketConnection sock,
614 SilcPacketContext *packet)
617 SilcServerEntry router;
618 SilcSocketConnection dst_sock;
619 SilcClientEntry client;
620 SilcIDListData idata;
622 SILC_LOG_DEBUG(("Start"));
624 if (packet->src_id_type != SILC_ID_CLIENT ||
625 packet->dst_id_type != SILC_ID_CLIENT)
631 /* Decode destination Client ID */
632 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
634 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
638 /* If the destination belongs to our server we don't have to route
639 the message anywhere but to send it to the local destination. */
640 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
642 /* It exists, now deliver the message to the destination */
643 dst_sock = (SilcSocketConnection)client->connection;
645 /* If we are router and the client has router then the client is in
646 our cell but not directly connected to us. */
647 if (server->server_type == SILC_ROUTER && client->router) {
648 /* We are of course in this case the client's router thus the real
649 "router" of the client is the server who owns the client. Thus
650 we will send the packet to that server. */
651 router = (SilcServerEntry)client->router;
652 idata = (SilcIDListData)router;
654 silc_server_send_private_message(server, router->connection,
661 /* Seems that client really is directly connected to us */
662 idata = (SilcIDListData)client;
663 silc_server_send_private_message(server, dst_sock,
665 idata->hmac, packet);
669 /* Destination belongs to someone not in this server. If we are normal
670 server our action is to send the packet to our router. */
671 if (server->server_type == SILC_SERVER && !server->standalone) {
672 router = server->router;
674 /* Send to primary route */
676 dst_sock = (SilcSocketConnection)router->connection;
677 idata = (SilcIDListData)router;
678 silc_server_send_private_message(server, dst_sock,
680 idata->hmac, packet);
685 /* We are router and we will perform route lookup for the destination
686 and send the message to fastest route. */
687 if (server->server_type == SILC_ROUTER && !server->standalone) {
688 /* Check first that the ID is valid */
689 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
691 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
692 router = (SilcServerEntry)dst_sock->user_data;
693 idata = (SilcIDListData)router;
695 /* Get fastest route and send packet. */
697 silc_server_send_private_message(server, dst_sock,
699 idata->hmac, packet);
705 /* Received private message key packet.. This packet is never for us. It is to
706 the client in the packet's destination ID. Sending of this sort of packet
707 equals sending private message, ie. it is sent point to point from
708 one client to another. */
710 void silc_server_private_message_key(SilcServer server,
711 SilcSocketConnection sock,
712 SilcPacketContext *packet)
715 SilcServerEntry router;
716 SilcSocketConnection dst_sock;
717 SilcClientEntry client;
718 SilcIDListData idata;
720 SILC_LOG_DEBUG(("Start"));
722 if (packet->src_id_type != SILC_ID_CLIENT ||
723 packet->dst_id_type != SILC_ID_CLIENT)
729 /* Decode destination Client ID */
730 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
732 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
736 /* If the destination belongs to our server we don't have to route
737 the message anywhere but to send it to the local destination. */
738 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
740 /* It exists, now deliver the message to the destination */
741 dst_sock = (SilcSocketConnection)client->connection;
743 /* If we are router and the client has router then the client is in
744 our cell but not directly connected to us. */
745 if (server->server_type == SILC_ROUTER && client->router) {
746 /* We are of course in this case the client's router thus the real
747 "router" of the client is the server who owns the client. Thus
748 we will send the packet to that server. */
749 router = (SilcServerEntry)client->router;
750 idata = (SilcIDListData)router;
751 silc_server_send_private_message_key(server, router->connection,
758 /* Seems that client really is directly connected to us */
759 idata = (SilcIDListData)client;
760 silc_server_send_private_message_key(server, dst_sock,
762 idata->hmac, packet);
766 /* Destination belongs to someone not in this server. If we are normal
767 server our action is to send the packet to our router. */
768 if (server->server_type == SILC_SERVER && !server->standalone) {
769 router = server->router;
771 /* Send to primary route */
773 dst_sock = (SilcSocketConnection)router->connection;
774 idata = (SilcIDListData)router;
775 silc_server_send_private_message_key(server, dst_sock,
777 idata->hmac, packet);
782 /* We are router and we will perform route lookup for the destination
783 and send the packet to fastest route. */
784 if (server->server_type == SILC_ROUTER && !server->standalone) {
785 /* Check first that the ID is valid */
786 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
788 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
789 router = (SilcServerEntry)dst_sock->user_data;
790 idata = (SilcIDListData)router;
792 /* Get fastest route and send packet. */
794 silc_server_send_private_message_key(server, dst_sock,
796 idata->hmac, packet);
802 /* Processes incoming command reply packet. The command reply packet may
803 be destined to one of our clients or it may directly for us. We will
804 call the command reply routine after processing the packet. */
806 void silc_server_command_reply(SilcServer server,
807 SilcSocketConnection sock,
808 SilcPacketContext *packet)
810 SilcBuffer buffer = packet->buffer;
811 SilcClientEntry client = NULL;
812 SilcSocketConnection dst_sock;
813 SilcIDListData idata;
814 SilcClientID *id = NULL;
816 SILC_LOG_DEBUG(("Start"));
818 /* Source must be server or router */
819 if (packet->src_id_type != SILC_ID_SERVER &&
820 sock->type != SILC_SOCKET_TYPE_ROUTER)
823 if (packet->dst_id_type == SILC_ID_CHANNEL)
826 if (packet->dst_id_type == SILC_ID_CLIENT) {
827 /* Destination must be one of ours */
828 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
831 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
833 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
839 if (packet->dst_id_type == SILC_ID_SERVER) {
840 /* For now this must be for us */
841 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
842 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
847 /* Execute command reply locally for the command */
848 silc_server_command_reply_process(server, sock, buffer);
850 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
851 /* Relay the packet to the client */
853 dst_sock = (SilcSocketConnection)client->connection;
854 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
855 + packet->dst_id_len + packet->padlen);
857 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
858 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
860 idata = (SilcIDListData)client;
863 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
866 /* Send the packet */
867 silc_server_packet_send_real(server, dst_sock, TRUE);
873 /* Process received channel message. The message can be originated from
876 void silc_server_channel_message(SilcServer server,
877 SilcSocketConnection sock,
878 SilcPacketContext *packet)
880 SilcChannelEntry channel = NULL;
881 SilcChannelClientEntry chl;
882 SilcChannelID *id = NULL;
885 SILC_LOG_DEBUG(("Processing channel message"));
888 if (packet->dst_id_type != SILC_ID_CHANNEL) {
889 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
893 /* Find channel entry */
894 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
897 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
899 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
901 SILC_LOG_DEBUG(("Could not find channel"));
906 /* See that this client is on the channel. If the message is coming
907 from router we won't do the check as the message is from client that
908 we don't know about. Also, if the original sender is not client
909 (as it can be server as well) we don't do the check. */
910 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
911 packet->src_id_type);
914 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
915 packet->src_id_type == SILC_ID_CLIENT) {
916 silc_list_start(channel->user_list);
917 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
918 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
921 if (chl == SILC_LIST_END) {
922 SILC_LOG_DEBUG(("Client not on channel"));
927 /* If we are router and the packet came from router and private key
928 has not been set for the channel then we must encrypt the packet
929 as it was decrypted with the session key shared between us and the
930 router which sent it. This is so, because cells does not share the
932 if (server->server_type == SILC_ROUTER &&
933 sock->type == SILC_SOCKET_TYPE_ROUTER &&
934 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
936 unsigned int iv_len, i, data_len;
938 iv_len = silc_cipher_get_block_len(channel->channel_key);
939 if (channel->iv[0] == '\0')
940 for (i = 0; i < iv_len; i++) channel->iv[i] =
941 silc_rng_get_byte(server->rng);
943 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
945 /* Encode new payload. This encrypts it also. */
946 SILC_GET16_MSB(data_len, packet->buffer->data);
947 chp = silc_channel_payload_encode(data_len, packet->buffer->data + 2,
949 channel->channel_key,
950 channel->hmac, server->rng);
951 silc_buffer_put(packet->buffer, chp->data, chp->len);
952 silc_buffer_free(chp);
955 /* Distribute the packet to our local clients. This will send the
956 packet for further routing as well, if needed. */
957 silc_server_packet_relay_to_channel(server, sock, channel, sender,
959 packet->buffer->data,
960 packet->buffer->len, FALSE);
969 /* Received channel key packet. We distribute the key to all of our locally
970 connected clients on the channel. */
972 void silc_server_channel_key(SilcServer server,
973 SilcSocketConnection sock,
974 SilcPacketContext *packet)
976 SilcBuffer buffer = packet->buffer;
977 SilcChannelEntry channel;
979 if (packet->src_id_type != SILC_ID_SERVER)
982 /* Save the channel key */
983 channel = silc_server_save_channel_key(server, buffer, NULL);
987 /* Distribute the key to everybody who is on the channel. If we are router
988 we will also send it to locally connected servers. */
989 silc_server_send_channel_key(server, sock, channel, FALSE);
992 /* Received New Client packet and processes it. Creates Client ID for the
993 client. Client becomes registered after calling this functions. */
995 SilcClientEntry silc_server_new_client(SilcServer server,
996 SilcSocketConnection sock,
997 SilcPacketContext *packet)
999 SilcBuffer buffer = packet->buffer;
1000 SilcClientEntry client;
1001 SilcIDCacheEntry cache;
1002 SilcClientID *client_id;
1004 SilcIDListData idata;
1005 char *username = NULL, *realname = NULL, *id_string;
1008 SILC_LOG_DEBUG(("Creating new client"));
1010 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1013 /* Take client entry */
1014 client = (SilcClientEntry)sock->user_data;
1015 idata = (SilcIDListData)client;
1017 /* Fetch the old client cache entry so that we can update it. */
1018 if (!silc_idcache_find_by_context(server->local_list->clients,
1019 sock->user_data, &cache)) {
1020 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1024 /* Parse incoming packet */
1025 ret = silc_buffer_unformat(buffer,
1026 SILC_STR_UI16_STRING_ALLOC(&username),
1027 SILC_STR_UI16_STRING_ALLOC(&realname),
1031 silc_free(username);
1033 silc_free(realname);
1038 silc_free(username);
1040 silc_free(realname);
1041 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1042 "Incomplete client information");
1046 /* Create Client ID */
1047 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1048 username, &client_id);
1050 if (strlen(username) > 128)
1051 username[127] = '\0';
1053 /* Update client entry */
1054 idata->registered = TRUE;
1055 client->nickname = strdup(username);
1056 client->username = username;
1057 client->userinfo = realname ? realname : strdup(" ");
1058 client->id = client_id;
1060 /* Update the cache entry */
1061 cache->id = (void *)client_id;
1062 cache->type = SILC_ID_CLIENT;
1063 cache->data = username;
1064 silc_idcache_sort_by_data(server->local_list->clients);
1066 /* Notify our router about new client on the SILC network */
1067 if (!server->standalone)
1068 silc_server_send_new_id(server, (SilcSocketConnection)
1069 server->router->connection,
1070 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1071 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1073 /* Send the new client ID to the client. */
1074 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1075 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1076 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1077 silc_buffer_format(reply,
1078 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1079 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1080 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1082 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1083 reply->data, reply->len, FALSE);
1084 silc_free(id_string);
1085 silc_buffer_free(reply);
1087 /* Send some nice info to the client */
1088 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1089 ("Welcome to the SILC Network %s@%s",
1090 username, sock->hostname));
1091 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1092 ("Your host is %s, running version %s",
1093 server->config->server_info->server_name,
1095 if (server->server_type == SILC_ROUTER) {
1096 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1097 ("There are %d clients on %d servers in SILC "
1098 "Network", server->stat.clients,
1099 server->stat.servers + 1));
1100 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1101 ("There are %d clients on %d server in our cell",
1102 server->stat.cell_clients,
1103 server->stat.cell_servers + 1));
1104 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1105 ("I have %d clients, %d channels, %d servers and "
1107 server->stat.my_clients,
1108 server->stat.my_channels,
1109 server->stat.my_servers,
1110 server->stat.my_routers));
1111 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1112 ("%d server operators and %d router operators "
1114 server->stat.my_server_ops,
1115 server->stat.my_router_ops));
1117 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1118 ("I have %d clients and %d channels formed",
1119 server->stat.my_clients,
1120 server->stat.my_channels));
1121 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1122 ("%d operators online",
1123 server->stat.my_server_ops));
1125 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1126 ("Your connection is secured with %s cipher, "
1127 "key length %d bits",
1128 idata->send_key->cipher->name,
1129 idata->send_key->cipher->key_len));
1130 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1131 ("Your current nickname is %s",
1135 silc_server_send_motd(server, sock);
1140 /* Create new server. This processes received New Server packet and
1141 saves the received Server ID. The server is our locally connected
1142 server thus we save all the information and save it to local list.
1143 This funtion can be used by both normal server and router server.
1144 If normal server uses this it means that its router has connected
1145 to the server. If router uses this it means that one of the cell's
1146 servers is connected to the router. */
1148 SilcServerEntry silc_server_new_server(SilcServer server,
1149 SilcSocketConnection sock,
1150 SilcPacketContext *packet)
1152 SilcBuffer buffer = packet->buffer;
1153 SilcServerEntry new_server;
1154 SilcIDCacheEntry cache;
1155 SilcServerID *server_id;
1156 SilcIDListData idata;
1157 unsigned char *server_name, *id_string;
1158 unsigned short id_len;
1161 SILC_LOG_DEBUG(("Creating new server"));
1163 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1164 sock->type != SILC_SOCKET_TYPE_ROUTER)
1167 /* Take server entry */
1168 new_server = (SilcServerEntry)sock->user_data;
1169 idata = (SilcIDListData)new_server;
1171 /* Fetch the old server cache entry so that we can update it. */
1172 if (!silc_idcache_find_by_context(server->local_list->servers,
1173 sock->user_data, &cache)) {
1174 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1178 /* Parse the incoming packet */
1179 ret = silc_buffer_unformat(buffer,
1180 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1181 SILC_STR_UI16_STRING_ALLOC(&server_name),
1185 silc_free(id_string);
1187 silc_free(server_name);
1191 if (id_len > buffer->len) {
1192 silc_free(id_string);
1193 silc_free(server_name);
1198 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1200 silc_free(id_string);
1201 silc_free(server_name);
1204 silc_free(id_string);
1206 /* Update client entry */
1207 idata->registered = TRUE;
1208 new_server->server_name = server_name;
1209 new_server->id = server_id;
1211 /* Update the cache entry */
1212 cache->id = (void *)server_id;
1213 cache->type = SILC_ID_SERVER;
1214 cache->data = server_name;
1215 silc_idcache_sort_by_data(server->local_list->servers);
1217 /* Distribute the information about new server in the SILC network
1218 to our router. If we are normal server we won't send anything
1219 since this connection must be our router connection. */
1220 if (server->server_type == SILC_ROUTER && !server->standalone &&
1221 server->router->connection != sock)
1222 silc_server_send_new_id(server, server->router->connection,
1223 TRUE, new_server->id, SILC_ID_SERVER,
1224 SILC_ID_SERVER_LEN);
1226 if (server->server_type == SILC_ROUTER)
1227 server->stat.cell_servers++;
1232 /* Processes incoming New ID packet. New ID Payload is used to distribute
1233 information about newly registered clients and servers. */
1235 static void silc_server_new_id_real(SilcServer server,
1236 SilcSocketConnection sock,
1237 SilcPacketContext *packet,
1240 SilcBuffer buffer = packet->buffer;
1242 SilcServerEntry router;
1243 SilcSocketConnection router_sock;
1246 unsigned char *hash = NULL;
1249 SILC_LOG_DEBUG(("Processing new ID"));
1251 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1252 server->server_type == SILC_SERVER ||
1253 packet->src_id_type != SILC_ID_SERVER)
1256 idp = silc_id_payload_parse(buffer);
1260 id_type = silc_id_payload_get_type(idp);
1262 /* Normal server cannot have other normal server connections */
1263 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1266 id = silc_id_payload_get_id(idp);
1270 /* If the sender of this packet is server and we are router we need to
1271 broadcast this packet to other routers in the network. */
1272 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1273 sock->type == SILC_SOCKET_TYPE_SERVER &&
1274 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1275 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1276 silc_server_packet_send(server, server->router->connection,
1278 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1279 buffer->data, buffer->len, FALSE);
1282 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1283 id_list = server->local_list;
1285 id_list = server->global_list;
1288 router = sock->user_data;
1291 case SILC_ID_CLIENT:
1293 SilcClientEntry entry;
1295 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1296 silc_id_render(id, SILC_ID_CLIENT),
1297 sock->type == SILC_SOCKET_TYPE_SERVER ?
1298 "Server" : "Router", sock->hostname));
1300 /* As a router we keep information of all global information in our
1301 global list. Cell wide information however is kept in the local
1302 list. The client is put to global list and we will take the hash
1303 value of the Client ID and save it to the ID Cache system for fast
1304 searching in the future. */
1305 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1306 sizeof(unsigned char));
1307 memcpy(hash, ((SilcClientID *)id)->hash,
1308 sizeof(((SilcClientID *)id)->hash));
1309 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
1311 entry->nickname = NULL;
1313 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1314 server->stat.cell_clients++;
1315 server->stat.clients++;
1318 /* XXX Adding two ID's with same IP number replaces the old entry thus
1319 gives wrong route. Thus, now disabled until figured out a better way
1320 to do this or when removed the whole thing. This could be removed
1321 because entry->router->connection gives always the most optimal route
1322 for the ID anyway (unless new routes (faster perhaps) are established
1323 after receiving this ID, this we don't know however). */
1324 /* Add route cache for this ID */
1325 silc_server_route_add(silc_server_route_hash(
1326 ((SilcClientID *)id)->ip.s_addr,
1327 server->id->port), ((SilcClientID *)id)->ip.s_addr,
1333 case SILC_ID_SERVER:
1334 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1335 silc_id_render(id, SILC_ID_SERVER),
1336 sock->type == SILC_SOCKET_TYPE_SERVER ?
1337 "Server" : "Router", sock->hostname));
1339 /* As a router we keep information of all global information in our global
1340 list. Cell wide information however is kept in the local list. */
1341 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1343 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1344 server->stat.cell_servers++;
1345 server->stat.servers++;
1348 /* Add route cache for this ID */
1349 silc_server_route_add(silc_server_route_hash(
1350 ((SilcServerID *)id)->ip.s_addr,
1351 ((SilcServerID *)id)->port),
1352 ((SilcServerID *)id)->ip.s_addr,
1357 case SILC_ID_CHANNEL:
1358 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1366 silc_id_payload_free(idp);
1370 /* Processes incoming New ID packet. New ID Payload is used to distribute
1371 information about newly registered clients and servers. */
1373 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1374 SilcPacketContext *packet)
1376 silc_server_new_id_real(server, sock, packet, TRUE);
1379 /* Receoved New Id List packet, list of New ID payloads inside one
1380 packet. Process the New ID payloads one by one. */
1382 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1383 SilcPacketContext *packet)
1385 SilcPacketContext *new_id;
1387 unsigned short id_len;
1389 SILC_LOG_DEBUG(("Processing New ID List"));
1391 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1392 packet->src_id_type != SILC_ID_SERVER)
1395 /* If the sender of this packet is server and we are router we need to
1396 broadcast this packet to other routers in the network. Broadcast
1397 this list packet instead of multiple New ID packets. */
1398 if (!server->standalone && server->server_type == SILC_ROUTER &&
1399 sock->type == SILC_SOCKET_TYPE_SERVER &&
1400 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1401 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1402 silc_server_packet_send(server, server->router->connection,
1404 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1405 packet->buffer->data, packet->buffer->len, FALSE);
1408 /* Make copy of the original packet context, except for the actual
1409 data buffer, which we will here now fetch from the original buffer. */
1410 new_id = silc_packet_context_alloc();
1411 new_id->type = SILC_PACKET_NEW_ID;
1412 new_id->flags = packet->flags;
1413 new_id->src_id = packet->src_id;
1414 new_id->src_id_len = packet->src_id_len;
1415 new_id->src_id_type = packet->src_id_type;
1416 new_id->dst_id = packet->dst_id;
1417 new_id->dst_id_len = packet->dst_id_len;
1418 new_id->dst_id_type = packet->dst_id_type;
1420 idp = silc_buffer_alloc(256);
1421 new_id->buffer = idp;
1423 while (packet->buffer->len) {
1424 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1425 if ((id_len > packet->buffer->len) ||
1426 (id_len > idp->truelen))
1429 silc_buffer_pull_tail(idp, 4 + id_len);
1430 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1432 /* Process the New ID */
1433 silc_server_new_id_real(server, sock, new_id, FALSE);
1435 silc_buffer_push_tail(idp, 4 + id_len);
1436 silc_buffer_pull(packet->buffer, 4 + id_len);
1439 silc_buffer_free(idp);
1443 /* Received New Channel packet. Information about new channels in the
1444 network are distributed using this packet. Save the information about
1445 the new channel. This usually comes from router but also normal server
1446 can send this to notify channels it has when it connects to us. */
1448 void silc_server_new_channel(SilcServer server,
1449 SilcSocketConnection sock,
1450 SilcPacketContext *packet)
1453 SilcChannelID *channel_id;
1454 unsigned short channel_id_len;
1458 SILC_LOG_DEBUG(("Processing New Channel"));
1460 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1461 packet->src_id_type != SILC_ID_SERVER ||
1462 server->server_type == SILC_SERVER)
1466 ret = silc_buffer_unformat(packet->buffer,
1467 SILC_STR_UI16_STRING_ALLOC(&channel_name),
1468 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
1472 silc_free(channel_name);
1478 /* Decode the channel ID */
1479 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
1483 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1484 /* Add the server to global list as it is coming from router. It
1485 cannot be our own channel as it is coming from router. */
1487 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1488 silc_id_render(channel_id, SILC_ID_CHANNEL),
1491 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
1492 server->router->connection, NULL, NULL);
1494 server->stat.channels++;
1496 /* The channel is coming from our server, thus it is in our cell
1497 we will add it to our local list. */
1498 SilcChannelEntry channel;
1501 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1502 silc_id_render(channel_id, SILC_ID_CHANNEL),
1505 /* Check that we don't already have this channel */
1506 channel = silc_idlist_find_channel_by_name(server->local_list,
1507 channel_name, NULL);
1509 channel = silc_idlist_find_channel_by_name(server->global_list,
1510 channel_name, NULL);
1512 /* If the channel does not exist, then create it. We create the channel
1513 with the channel ID provided by the server. This creates a new
1514 key to the channel as well that we will send to the server. */
1516 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1522 /* Send the new channel key to the server */
1523 chk = silc_channel_key_payload_encode(channel_id_len, id,
1524 strlen(channel->channel_key->
1526 channel->channel_key->cipher->name,
1527 channel->key_len / 8,
1529 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1530 chk->data, chk->len, FALSE);
1531 silc_buffer_free(chk);
1534 /* The channel exist by that name, check whether the ID's match.
1535 If they don't then we'll force the server to use the ID we have.
1536 We also create a new key for the channel. */
1538 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1539 /* They don't match, send CHANNEL_CHANGE notify to the server to
1540 force the ID change. */
1541 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1542 silc_server_send_notify_channel_change(server, sock, FALSE,
1545 SILC_ID_CHANNEL_LEN);
1548 /* Create new key for the channel and send it to the server and
1549 everybody else possibly on the channel. */
1551 silc_server_create_channel_key(server, channel, 0);
1553 /* Send to the channel */
1554 silc_server_send_channel_key(server, sock, channel, FALSE);
1556 /* Send to the server */
1557 chk = silc_channel_key_payload_encode(channel_id_len, id,
1558 strlen(channel->channel_key->
1560 channel->channel_key->cipher->name,
1561 channel->key_len / 8,
1563 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1564 chk->data, chk->len, FALSE);
1565 silc_buffer_free(chk);
1567 /* Since the channel is coming from server and we also know about it
1568 then send the JOIN notify to the server so that it see's our
1569 users on the channel "joining" the channel. */
1577 /* Received New Channel List packet, list of New Channel List payloads inside
1578 one packet. Process the New Channel payloads one by one. */
1580 void silc_server_new_channel_list(SilcServer server,
1581 SilcSocketConnection sock,
1582 SilcPacketContext *packet)
1584 SilcPacketContext *new;
1586 unsigned short len1, len2;
1588 SILC_LOG_DEBUG(("Processing New Channel List"));
1590 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1591 packet->src_id_type != SILC_ID_SERVER ||
1592 server->server_type == SILC_SERVER)
1595 /* If the sender of this packet is server and we are router we need to
1596 broadcast this packet to other routers in the network. Broadcast
1597 this list packet instead of multiple New Channel packets. */
1598 if (!server->standalone && server->server_type == SILC_ROUTER &&
1599 sock->type == SILC_SOCKET_TYPE_SERVER &&
1600 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1601 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1602 silc_server_packet_send(server, server->router->connection,
1604 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1605 packet->buffer->data, packet->buffer->len, FALSE);
1608 /* Make copy of the original packet context, except for the actual
1609 data buffer, which we will here now fetch from the original buffer. */
1610 new = silc_packet_context_alloc();
1611 new->type = SILC_PACKET_NEW_CHANNEL;
1612 new->flags = packet->flags;
1613 new->src_id = packet->src_id;
1614 new->src_id_len = packet->src_id_len;
1615 new->src_id_type = packet->src_id_type;
1616 new->dst_id = packet->dst_id;
1617 new->dst_id_len = packet->dst_id_len;
1618 new->dst_id_type = packet->dst_id_type;
1620 buffer = silc_buffer_alloc(512);
1621 new->buffer = buffer;
1623 while (packet->buffer->len) {
1624 SILC_GET16_MSB(len1, packet->buffer->data);
1625 if ((len1 > packet->buffer->len) ||
1626 (len1 > buffer->truelen))
1629 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1630 if ((len2 > packet->buffer->len) ||
1631 (len2 > buffer->truelen))
1634 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1635 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1637 /* Process the New Channel */
1638 silc_server_new_channel(server, sock, new);
1640 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1641 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1644 silc_buffer_free(buffer);
1648 /* Received key agreement packet. This packet is never for us. It is to
1649 the client in the packet's destination ID. Sending of this sort of packet
1650 equals sending private message, ie. it is sent point to point from
1651 one client to another. */
1653 void silc_server_key_agreement(SilcServer server,
1654 SilcSocketConnection sock,
1655 SilcPacketContext *packet)
1658 SilcServerEntry router;
1659 SilcSocketConnection dst_sock;
1660 SilcClientEntry client;
1661 SilcIDListData idata;
1663 SILC_LOG_DEBUG(("Start"));
1665 if (packet->src_id_type != SILC_ID_CLIENT ||
1666 packet->dst_id_type != SILC_ID_CLIENT)
1669 if (!packet->dst_id)
1672 /* Decode destination Client ID */
1673 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1675 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
1679 /* If the destination belongs to our server we don't have to route
1680 the message anywhere but to send it to the local destination. */
1681 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1683 /* It exists, now deliver the message to the destination */
1684 dst_sock = (SilcSocketConnection)client->connection;
1686 /* If we are router and the client has router then the client is in
1687 our cell but not directly connected to us. */
1688 if (server->server_type == SILC_ROUTER && client->router) {
1689 /* We are of course in this case the client's router thus the real
1690 "router" of the client is the server who owns the client. Thus
1691 we will send the packet to that server. */
1692 router = (SilcServerEntry)client->router;
1693 idata = (SilcIDListData)router;
1694 silc_server_send_key_agreement(server, router->connection,
1701 /* Seems that client really is directly connected to us */
1702 idata = (SilcIDListData)client;
1703 silc_server_send_key_agreement(server, dst_sock,
1705 idata->hmac, packet);
1709 /* Destination belongs to someone not in this server. If we are normal
1710 server our action is to send the packet to our router. */
1711 if (server->server_type == SILC_SERVER && !server->standalone) {
1712 router = server->router;
1714 /* Send to primary route */
1716 dst_sock = (SilcSocketConnection)router->connection;
1717 idata = (SilcIDListData)router;
1718 silc_server_send_key_agreement(server, dst_sock,
1720 idata->hmac, packet);
1725 /* We are router and we will perform route lookup for the destination
1726 and send the packet to fastest route. */
1727 if (server->server_type == SILC_ROUTER && !server->standalone) {
1728 /* Check first that the ID is valid */
1729 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
1731 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
1732 router = (SilcServerEntry)dst_sock->user_data;
1733 idata = (SilcIDListData)router;
1735 /* Get fastest route and send packet. */
1737 silc_server_send_key_agreement(server, dst_sock,
1739 idata->hmac, packet);