5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 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 private message. This resolves the destination of the message
31 and sends the packet. This is used by both server and router. If the
32 destination is our locally connected client this sends the packet to
33 the client. This may also send the message for further routing if
34 the destination is not in our server (or router). */
36 void silc_server_private_message(SilcServer server,
37 SilcSocketConnection sock,
38 SilcPacketContext *packet)
41 SilcServerEntry router;
42 SilcSocketConnection dst_sock;
43 SilcClientEntry client;
46 SILC_LOG_DEBUG(("Start"));
51 /* Decode destination Client ID */
52 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
54 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
58 /* If the destination belongs to our server we don't have to route
59 the message anywhere but to send it to the local destination. */
60 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
62 /* It exists, now deliver the message to the destination */
63 dst_sock = (SilcSocketConnection)client->connection;
65 /* If we are router and the client has router then the client is in
66 our cell but not directly connected to us. */
67 if (server->server_type == SILC_ROUTER && client->router) {
68 /* We are of course in this case the client's router thus the real
69 "router" of the client is the server who owns the client. Thus
70 we will send the packet to that server. */
71 router = (SilcServerEntry)dst_sock->user_data;
72 idata = (SilcIDListData)router;
73 //assert(client->router == server->id_entry);
75 silc_server_send_private_message(server, dst_sock,
82 /* Seems that client really is directly connected to us */
83 idata = (SilcIDListData)client;
84 silc_server_send_private_message(server, dst_sock,
90 /* Destination belongs to someone not in this server. If we are normal
91 server our action is to send the packet to our router. */
92 if (server->server_type == SILC_SERVER && !server->standalone) {
93 router = server->router;
95 /* Send to primary route */
97 dst_sock = (SilcSocketConnection)router->connection;
98 idata = (SilcIDListData)router;
99 silc_server_send_private_message(server, dst_sock,
101 idata->hmac, packet);
106 /* We are router and we will perform route lookup for the destination
107 and send the message to fastest route. */
108 if (server->server_type == SILC_ROUTER && !server->standalone) {
109 /* Check first that the ID is valid */
110 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
112 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
113 router = (SilcServerEntry)dst_sock->user_data;
114 idata = (SilcIDListData)router;
116 /* Get fastest route and send packet. */
118 silc_server_send_private_message(server, dst_sock,
120 idata->hmac, packet);
126 silc_server_send_error(server, sock,
127 "No such nickname: Private message not sent");
130 /* Processes incoming command reply packet. The command reply packet may
131 be destined to one of our clients or it may directly for us. We will
132 call the command reply routine after processing the packet. */
134 void silc_server_command_reply(SilcServer server,
135 SilcSocketConnection sock,
136 SilcPacketContext *packet)
138 SilcBuffer buffer = packet->buffer;
139 SilcClientEntry client = NULL;
140 SilcSocketConnection dst_sock;
141 SilcIDListData idata;
142 SilcClientID *id = NULL;
144 SILC_LOG_DEBUG(("Start"));
146 /* Source must be server or router */
147 if (packet->src_id_type != SILC_ID_SERVER &&
148 sock->type != SILC_SOCKET_TYPE_ROUTER)
151 if (packet->dst_id_type == SILC_ID_CHANNEL)
154 if (packet->dst_id_type == SILC_ID_CLIENT) {
155 /* Destination must be one of ours */
156 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
157 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
159 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
165 if (packet->dst_id_type == SILC_ID_SERVER) {
166 /* For now this must be for us */
167 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
168 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
173 /* Execute command reply locally for the command */
174 silc_server_command_reply_process(server, sock, buffer);
176 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
177 /* Relay the packet to the client */
179 dst_sock = (SilcSocketConnection)client->connection;
180 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
181 + packet->dst_id_len + packet->padlen);
183 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
184 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
186 idata = (SilcIDListData)client;
189 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
192 /* Send the packet */
193 silc_server_packet_send_real(server, dst_sock, TRUE);
199 /* Process received channel message. The message can be originated from
202 void silc_server_channel_message(SilcServer server,
203 SilcSocketConnection sock,
204 SilcPacketContext *packet)
206 SilcChannelEntry channel = NULL;
207 SilcChannelClientEntry chl;
208 SilcChannelID *id = NULL;
211 SILC_LOG_DEBUG(("Processing channel message"));
214 if (packet->dst_id_type != SILC_ID_CHANNEL) {
215 SILC_LOG_ERROR(("Received bad message for channel, dropped"));
216 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
220 /* Find channel entry */
221 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
222 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
224 SILC_LOG_DEBUG(("Could not find channel"));
228 /* See that this client is on the channel. If the message is coming
229 from router we won't do the check as the message is from client that
230 we don't know about. Also, if the original sender is not client
231 (as it can be server as well) we don't do the check. */
232 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
233 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
234 packet->src_id_type == SILC_ID_CLIENT) {
235 silc_list_start(channel->user_list);
236 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
237 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
240 if (chl == SILC_LIST_END)
244 /* Distribute the packet to our local clients. This will send the
245 packet for further routing as well, if needed. */
246 silc_server_packet_relay_to_channel(server, sock, channel, sender,
248 packet->buffer->data,
249 packet->buffer->len, FALSE);
258 /* Received channel key packet. We distribute the key to all of our locally
259 connected clients on the channel. */
261 void silc_server_channel_key(SilcServer server,
262 SilcSocketConnection sock,
263 SilcPacketContext *packet)
265 SilcBuffer buffer = packet->buffer;
266 SilcChannelKeyPayload payload = NULL;
267 SilcChannelID *id = NULL;
268 SilcChannelEntry channel;
269 SilcChannelClientEntry chl;
271 unsigned int tmp_len;
275 if (packet->src_id_type != SILC_ID_SERVER)
278 /* Decode channel key payload */
279 payload = silc_channel_key_payload_parse(buffer);
281 SILC_LOG_ERROR(("Bad channel key payload, dropped"));
286 tmp = silc_channel_key_get_id(payload, &tmp_len);
287 id = silc_id_payload_parse_id(tmp, tmp_len);
291 /* Get the channel entry */
292 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
294 SILC_LOG_ERROR(("Received key for non-existent channel"));
298 tmp = silc_channel_key_get_key(payload, &tmp_len);
302 cipher = silc_channel_key_get_cipher(payload, NULL);;
306 /* Remove old key if exists */
308 memset(channel->key, 0, channel->key_len / 8);
309 silc_free(channel->key);
310 silc_cipher_free(channel->channel_key);
314 /* Create new cipher */
315 if (!silc_cipher_alloc(cipher, &channel->channel_key))
319 channel->key_len = tmp_len * 8;
320 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
321 memcpy(channel->key, tmp, tmp_len);
322 channel->channel_key->cipher->set_key(channel->channel_key->context,
325 /* Distribute the key to everybody who is on the channel. If we are router
326 we will also send it to locally connected servers. */
327 silc_server_send_channel_key(server, channel, FALSE);
333 silc_channel_key_payload_free(payload);
336 /* Received packet to replace a ID. This checks that the requested ID
337 exists and replaces it with the new one. */
339 void silc_server_replace_id(SilcServer server,
340 SilcSocketConnection sock,
341 SilcPacketContext *packet)
343 SilcBuffer buffer = packet->buffer;
344 unsigned char *old_id = NULL, *new_id = NULL;
345 SilcIdType old_id_type, new_id_type;
346 unsigned short old_id_len, new_id_len;
347 void *id = NULL, *id2 = NULL;
349 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
350 packet->src_id_type == SILC_ID_CLIENT)
353 SILC_LOG_DEBUG(("Replacing ID"));
355 silc_buffer_unformat(buffer,
356 SILC_STR_UI_SHORT(&old_id_type),
357 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
358 SILC_STR_UI_SHORT(&new_id_type),
359 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
362 if (old_id_type != new_id_type)
365 if (old_id_len != silc_id_get_len(old_id_type) ||
366 new_id_len != silc_id_get_len(new_id_type))
369 id = silc_id_str2id(old_id, old_id_type);
373 id2 = silc_id_str2id(new_id, new_id_type);
377 /* If we are router and this packet is not already broadcast packet
378 we will broadcast it. The sending socket really cannot be router or
379 the router is buggy. If this packet is coming from router then it must
380 have the broadcast flag set already and we won't do anything. */
381 if (server->server_type == SILC_ROUTER &&
382 sock->type == SILC_SOCKET_TYPE_SERVER &&
383 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
384 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
385 silc_server_packet_send(server, server->router->connection, packet->type,
386 packet->flags | SILC_PACKET_FLAG_BROADCAST,
387 buffer->data, buffer->len, FALSE);
390 /* Replace the old ID */
391 switch(old_id_type) {
393 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
394 if (server->server_type == SILC_ROUTER)
395 silc_idlist_replace_client_id(server->global_list, id, id2);
399 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
400 if (server->server_type == SILC_ROUTER)
401 silc_idlist_replace_server_id(server->global_list, id, id2);
404 case SILC_ID_CHANNEL:
405 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
425 /* Received New Client packet and processes it. Creates Client ID for the
426 client. Client becomes registered after calling this functions. */
428 SilcClientEntry silc_server_new_client(SilcServer server,
429 SilcSocketConnection sock,
430 SilcPacketContext *packet)
432 SilcBuffer buffer = packet->buffer;
433 SilcClientEntry client;
434 SilcIDCacheEntry cache;
435 SilcClientID *client_id;
437 SilcIDListData idata;
438 char *username = NULL, *realname = NULL, *id_string;
440 SILC_LOG_DEBUG(("Creating new client"));
442 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
445 /* Take client entry */
446 client = (SilcClientEntry)sock->user_data;
447 idata = (SilcIDListData)client;
449 /* Fetch the old client cache entry so that we can update it. */
450 if (!silc_idcache_find_by_context(server->local_list->clients,
451 sock->user_data, &cache)) {
452 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
456 /* Parse incoming packet */
457 silc_buffer_unformat(buffer,
458 SILC_STR_UI16_STRING_ALLOC(&username),
459 SILC_STR_UI16_STRING_ALLOC(&realname),
462 /* Create Client ID */
463 silc_id_create_client_id(server->id, server->rng, server->md5hash,
464 username, &client_id);
466 /* Update client entry */
467 idata->registered = TRUE;
468 client->nickname = strdup(username);
469 client->username = username;
470 client->userinfo = realname;
471 client->id = client_id;
473 /* Update the cache entry */
474 cache->id = (void *)client_id;
475 cache->type = SILC_ID_CLIENT;
476 cache->data = username;
477 silc_idcache_sort_by_data(server->local_list->clients);
479 /* Notify our router about new client on the SILC network */
480 if (!server->standalone)
481 silc_server_send_new_id(server, (SilcSocketConnection)
482 server->router->connection,
483 server->server_type == SILC_ROUTER ? TRUE : FALSE,
484 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
486 /* Send the new client ID to the client. */
487 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
488 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
489 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
490 silc_buffer_format(reply,
491 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
492 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
493 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
495 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
496 reply->data, reply->len, FALSE);
497 silc_free(id_string);
498 silc_buffer_free(reply);
500 /* Send some nice info to the client */
501 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
502 ("Welcome to the SILC Network %s@%s",
503 username, sock->hostname));
504 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
505 ("Your host is %s, running version %s",
506 server->config->server_info->server_name,
508 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
509 ("Your connection is secured with %s cipher, "
510 "key length %d bits",
511 idata->send_key->cipher->name,
512 idata->send_key->cipher->key_len));
513 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
514 ("Your current nickname is %s",
518 silc_server_send_motd(server, sock);
523 /* Create new server. This processes received New Server packet and
524 saves the received Server ID. The server is our locally connected
525 server thus we save all the information and save it to local list.
526 This funtion can be used by both normal server and router server.
527 If normal server uses this it means that its router has connected
528 to the server. If router uses this it means that one of the cell's
529 servers is connected to the router. */
531 SilcServerEntry silc_server_new_server(SilcServer server,
532 SilcSocketConnection sock,
533 SilcPacketContext *packet)
535 SilcBuffer buffer = packet->buffer;
536 SilcServerEntry new_server;
537 SilcIDCacheEntry cache;
538 SilcServerID *server_id;
539 SilcIDListData idata;
540 unsigned char *server_name, *id_string;
541 unsigned short id_len;
543 SILC_LOG_DEBUG(("Creating new server"));
545 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
546 sock->type != SILC_SOCKET_TYPE_ROUTER)
549 /* Take server entry */
550 new_server = (SilcServerEntry)sock->user_data;
551 idata = (SilcIDListData)new_server;
553 /* Fetch the old server cache entry so that we can update it. */
554 if (!silc_idcache_find_by_context(server->local_list->servers,
555 sock->user_data, &cache)) {
556 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
560 /* Parse the incoming packet */
561 silc_buffer_unformat(buffer,
562 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
563 SILC_STR_UI16_STRING_ALLOC(&server_name),
566 if (id_len > buffer->len) {
567 silc_free(id_string);
568 silc_free(server_name);
573 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
574 silc_free(id_string);
576 /* Update client entry */
577 idata->registered = TRUE;
578 new_server->server_name = server_name;
579 new_server->id = server_id;
581 /* Update the cache entry */
582 cache->id = (void *)server_id;
583 cache->type = SILC_ID_SERVER;
584 cache->data = server_name;
585 silc_idcache_sort_by_data(server->local_list->servers);
587 /* Distribute the information about new server in the SILC network
588 to our router. If we are normal server we won't send anything
589 since this connection must be our router connection. */
590 if (server->server_type == SILC_ROUTER && !server->standalone &&
591 server->router->connection != sock)
592 silc_server_send_new_id(server, server->router->connection,
593 TRUE, new_server->id, SILC_ID_SERVER,
599 /* Processes incoming New ID packet. New ID Payload is used to distribute
600 information about newly registered clients and servers. */
602 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
603 SilcPacketContext *packet)
605 SilcBuffer buffer = packet->buffer;
607 SilcServerEntry tmpserver, router;
608 SilcSocketConnection router_sock;
611 unsigned char *hash = NULL;
614 SILC_LOG_DEBUG(("Processing new ID"));
616 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
617 server->server_type == SILC_SERVER ||
618 packet->src_id_type != SILC_ID_SERVER)
621 idp = silc_id_payload_parse(buffer);
625 id_type = silc_id_payload_get_type(idp);
627 /* Normal server cannot have other normal server connections */
628 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
631 id = silc_id_payload_get_id(idp);
635 /* If the sender of this packet is server and we are router we need to
636 broadcast this packet to other routers in the network. */
637 if (!server->standalone && server->server_type == SILC_ROUTER &&
638 sock->type == SILC_SOCKET_TYPE_SERVER &&
639 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
640 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
641 silc_server_packet_send(server, server->router->connection,
643 packet->flags | SILC_PACKET_FLAG_BROADCAST,
644 buffer->data, buffer->len, FALSE);
648 /* If the packet is originated from the one who sent it to us we know
649 that the ID belongs to our cell, unless the sender was router. */
650 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
651 tmpserver = (SilcServerEntry)sock->user_data;
653 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
654 sock->type == SILC_SOCKET_TYPE_SERVER) {
655 id_list = server->local_list;
657 router = sock->user_data;
658 /* router = server->id_entry; */
660 id_list = server->global_list;
661 router_sock = (SilcSocketConnection)server->router->connection;
662 router = server->router;
668 if (sock->type == SILC_SOCKET_TYPE_SERVER)
669 id_list = server->local_list;
671 id_list = server->global_list;
674 router = sock->user_data;
679 SilcClientEntry entry;
681 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
682 silc_id_render(id, SILC_ID_CLIENT),
683 sock->type == SILC_SOCKET_TYPE_SERVER ?
684 "Server" : "Router", sock->hostname));
686 /* As a router we keep information of all global information in our
687 global list. Cell wide information however is kept in the local
688 list. The client is put to global list and we will take the hash
689 value of the Client ID and save it to the ID Cache system for fast
690 searching in the future. */
691 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
692 sizeof(unsigned char));
693 memcpy(hash, ((SilcClientID *)id)->hash,
694 sizeof(((SilcClientID *)id)->hash));
695 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
696 router, router_sock);
697 entry->nickname = NULL;
700 /* XXX Adding two ID's with same IP number replaces the old entry thus
701 gives wrong route. Thus, now disabled until figured out a better way
702 to do this or when removed the whole thing. This could be removed
703 because entry->router->connection gives always the most optimal route
704 for the ID anyway (unless new routes (faster perhaps) are established
705 after receiving this ID, this we don't know however). */
706 /* Add route cache for this ID */
707 silc_server_route_add(silc_server_route_hash(
708 ((SilcClientID *)id)->ip.s_addr,
709 server->id->port), ((SilcClientID *)id)->ip.s_addr,
716 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
717 silc_id_render(id, SILC_ID_SERVER),
718 sock->type == SILC_SOCKET_TYPE_SERVER ?
719 "Server" : "Router", sock->hostname));
721 /* As a router we keep information of all global information in our global
722 list. Cell wide information however is kept in the local list. */
723 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
726 /* Add route cache for this ID */
727 silc_server_route_add(silc_server_route_hash(
728 ((SilcServerID *)id)->ip.s_addr,
729 ((SilcServerID *)id)->port),
730 ((SilcServerID *)id)->ip.s_addr,
735 case SILC_ID_CHANNEL:
736 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
744 silc_id_payload_free(idp);
747 /* Received Remove Channel User packet to remove a user from a channel.
748 Routers notify other routers that user has left a channel. Client must
749 not send this packet.. Normal server may send this packet but must not
752 void silc_server_remove_channel_user(SilcServer server,
753 SilcSocketConnection sock,
754 SilcPacketContext *packet)
756 SilcBuffer buffer = packet->buffer;
757 unsigned char *tmp1 = NULL, *tmp2 = NULL;
758 SilcClientID *client_id = NULL;
759 SilcChannelID *channel_id = NULL;
760 SilcChannelEntry channel;
761 SilcClientEntry client;
763 SILC_LOG_DEBUG(("Removing user from channel"));
765 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
766 server->server_type == SILC_SERVER)
769 silc_buffer_unformat(buffer,
770 SILC_STR_UI16_STRING_ALLOC(&tmp1),
771 SILC_STR_UI16_STRING_ALLOC(&tmp2),
777 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
778 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
779 if (!client_id || !channel_id)
782 /* If we are router and this packet is not already broadcast packet
783 we will broadcast it. The sending socket really cannot be router or
784 the router is buggy. If this packet is coming from router then it must
785 have the broadcast flag set already and we won't do anything. */
786 if (!server->standalone && server->server_type == SILC_ROUTER &&
787 sock->type == SILC_SOCKET_TYPE_SERVER &&
788 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
789 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
790 silc_server_packet_send(server, server->router->connection, packet->type,
791 packet->flags | SILC_PACKET_FLAG_BROADCAST,
792 buffer->data, buffer->len, FALSE);
795 /* XXX routers should check server->global_list as well */
796 /* Get channel entry */
797 channel = silc_idlist_find_channel_by_id(server->local_list,
802 /* XXX routers should check server->global_list as well */
803 /* Get client entry */
804 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
808 /* Remove from channel */
809 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
817 silc_free(client_id);
819 silc_free(channel_id);
822 /* Received New Channel packet. Information about new channels in the
823 network are distributed using this packet. Save the information about
826 void silc_server_new_channel(SilcServer server,
827 SilcSocketConnection sock,
828 SilcPacketContext *packet)
831 SilcChannelID *channel_id;
832 unsigned short channel_id_len;
835 SILC_LOG_DEBUG(("Processing New Channel"));
837 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
838 server->server_type == SILC_SERVER ||
839 packet->src_id_type != SILC_ID_SERVER)
843 if (!silc_buffer_unformat(packet->buffer,
844 SILC_STR_UI16_STRING_ALLOC(&channel_name),
845 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
849 if (!channel_name || !id)
852 /* Decode the channel ID */
853 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
858 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
859 silc_id_render(channel_id, SILC_ID_CHANNEL),
862 /* Add the new channel. Add it always to global list since if we receive
863 this packet then it cannot be created by ourselves but some other
864 router hence global channel. */
865 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
866 server->router->connection, NULL);
869 /* Received notify packet. Server can receive notify packets from router.
870 Server then relays the notify messages to clients if needed. */
872 void silc_server_notify(SilcServer server,
873 SilcSocketConnection sock,
874 SilcPacketContext *packet)
876 SilcNotifyPayload payload;
878 SilcArgumentPayload args;
879 SilcChannelID *channel_id;
880 SilcChannelEntry channel;
882 SILC_LOG_DEBUG(("Start"));
884 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
885 packet->src_id_type != SILC_ID_SERVER)
888 /* XXX: For now we expect that the we are normal server and that the
889 sender is router. Server could send (protocol allows it) notify to
890 router but we don't support it yet. */
891 if (server->server_type != SILC_SERVER &&
892 sock->type != SILC_SOCKET_TYPE_ROUTER)
895 payload = silc_notify_payload_parse(packet->buffer);
899 type = silc_notify_get_type(payload);
900 args = silc_notify_get_args(payload);
905 case SILC_NOTIFY_TYPE_JOIN:
907 * Distribute the notify to local clients on the channel
910 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
914 /* Get channel entry */
915 channel = silc_idlist_find_channel_by_id(server->local_list,
918 silc_free(channel_id);
922 /* Send to channel */
923 silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
924 packet->buffer->data,
925 packet->buffer->len, FALSE);
928 case SILC_NOTIFY_TYPE_LEAVE:
931 case SILC_NOTIFY_TYPE_SIGNOFF:
934 /* Ignore rest notify types for now */
935 case SILC_NOTIFY_TYPE_NONE:
936 case SILC_NOTIFY_TYPE_INVITE:
937 case SILC_NOTIFY_TYPE_TOPIC_SET:
938 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
939 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
940 case SILC_NOTIFY_TYPE_MOTD:
946 silc_notify_payload_free(payload);
949 /* Received new channel user packet. Information about new users on a
950 channel are distributed between routers using this packet. The
951 router receiving this will redistribute it and also sent JOIN notify
952 to local clients on the same channel. Normal server sends JOIN notify
953 to its local clients on the channel. */
955 void silc_server_new_channel_user(SilcServer server,
956 SilcSocketConnection sock,
957 SilcPacketContext *packet)
959 unsigned char *tmpid1, *tmpid2;
960 SilcClientID *client_id = NULL;
961 SilcChannelID *channel_id = NULL;
962 unsigned short channel_id_len;
963 unsigned short client_id_len;
964 SilcClientEntry client;
965 SilcChannelEntry channel;
966 SilcChannelClientEntry chl;
968 SilcServerEntry tmpserver, router;
969 SilcSocketConnection router_sock;
973 SILC_LOG_DEBUG(("Start"));
975 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
976 server->server_type != SILC_ROUTER ||
977 packet->src_id_type != SILC_ID_SERVER)
981 if (!silc_buffer_unformat(packet->buffer,
982 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
984 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
989 if (!tmpid1 || !tmpid2)
992 /* Decode the channel ID */
993 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
997 /* Decode the client ID */
998 client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
1002 /* If the packet is originated from the one who sent it to us we know
1003 that the ID belongs to our cell, unless the sender was router. */
1004 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
1005 tmpserver = (SilcServerEntry)sock->user_data;
1007 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
1008 sock->type == SILC_SOCKET_TYPE_SERVER) {
1009 id_list = server->local_list;
1011 router = sock->user_data;
1013 id_list = server->global_list;
1014 router_sock = (SilcSocketConnection)server->router->connection;
1015 router = server->router;
1019 /* Find the channel */
1020 channel = silc_idlist_find_channel_by_id(id_list, channel_id, NULL);
1022 SILC_LOG_ERROR(("Received channel user for non-existent channel"));
1026 /* If we are router and this packet is not already broadcast packet
1027 we will broadcast it. */
1028 if (!server->standalone && server->server_type == SILC_ROUTER &&
1029 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1030 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1031 silc_server_packet_send(server, server->router->connection, packet->type,
1032 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1033 packet->buffer->data, packet->buffer->len, FALSE);
1036 /* Get client entry */
1037 client = silc_idlist_find_client_by_id(id_list, client_id, NULL);
1039 /* This is new client to us, add entry to ID list */
1040 client = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1041 client_id, router, router_sock);
1046 /* Join the client to the channel by adding it to channel's user list.
1047 Add also the channel to client entry's channels list for fast cross-
1049 chl = silc_calloc(1, sizeof(*chl));
1050 chl->client = client;
1051 chl->channel = channel;
1052 silc_list_add(channel->user_list, chl);
1053 silc_list_add(client->channels, chl);
1055 /* Send JOIN notify to local clients on the channel. As we are router
1056 it is assured that this is sent only to our local clients and locally
1057 connected servers if needed. */
1058 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1059 silc_server_send_notify_to_channel(server, channel, FALSE,
1060 SILC_NOTIFY_TYPE_JOIN,
1061 1, clidp->data, clidp->len);
1062 silc_buffer_free(clidp);
1068 silc_free(client_id);
1070 silc_free(channel_id);
1075 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1076 that certain ID should be removed. After that the ID will become invalid. */
1078 void silc_server_remove_id(SilcServer server,
1079 SilcSocketConnection sock,
1080 SilcPacketContext *packet)
1085 void *id, *id_entry;
1087 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1088 server->server_type == SILC_SERVER ||
1089 packet->src_id_type != SILC_ID_SERVER)
1092 idp = silc_id_payload_parse(packet->buffer);
1096 id_type = silc_id_payload_get_type(idp);
1098 id = silc_id_payload_get_id(idp);
1102 /* If the sender of this packet is server and we are router we need to
1103 broadcast this packet to other routers in the network. */
1104 if (!server->standalone && server->server_type == SILC_ROUTER &&
1105 sock->type == SILC_SOCKET_TYPE_SERVER &&
1106 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1107 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1108 silc_server_packet_send(server, server->router->connection,
1110 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1111 packet->buffer->data, packet->buffer->len, FALSE);
1114 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1115 id_list = server->local_list;
1117 id_list = server->global_list;
1121 case SILC_ID_CLIENT:
1122 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1125 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1127 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1128 silc_id_render(id, SILC_ID_CLIENT),
1129 sock->type == SILC_SOCKET_TYPE_SERVER ?
1130 "Server" : "Router", sock->hostname));
1134 case SILC_ID_SERVER:
1135 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1138 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1140 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1141 silc_id_render(id, SILC_ID_SERVER),
1142 sock->type == SILC_SOCKET_TYPE_SERVER ?
1143 "Server" : "Router", sock->hostname));
1147 case SILC_ID_CHANNEL:
1148 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1151 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1153 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1154 silc_id_render(id, SILC_ID_CHANNEL),
1155 sock->type == SILC_SOCKET_TYPE_SERVER ?
1156 "Server" : "Router", sock->hostname));
1165 silc_id_payload_free(idp);