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_DEBUG(("Received bad message for channel, dropped"));
219 /* Find channel entry */
220 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
221 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
223 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
225 SILC_LOG_DEBUG(("Could not find channel"));
230 /* See that this client is on the channel. If the message is coming
231 from router we won't do the check as the message is from client that
232 we don't know about. Also, if the original sender is not client
233 (as it can be server as well) we don't do the check. */
234 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
235 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
236 packet->src_id_type == SILC_ID_CLIENT) {
237 silc_list_start(channel->user_list);
238 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
239 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
242 if (chl == SILC_LIST_END)
246 /* Distribute the packet to our local clients. This will send the
247 packet for further routing as well, if needed. */
248 silc_server_packet_relay_to_channel(server, sock, channel, sender,
250 packet->buffer->data,
251 packet->buffer->len, FALSE);
260 /* Received channel key packet. We distribute the key to all of our locally
261 connected clients on the channel. */
263 void silc_server_channel_key(SilcServer server,
264 SilcSocketConnection sock,
265 SilcPacketContext *packet)
267 SilcBuffer buffer = packet->buffer;
268 SilcChannelEntry channel;
270 if (packet->src_id_type != SILC_ID_SERVER)
273 /* Save the channel key */
274 channel = silc_server_save_channel_key(server, buffer, NULL);
278 /* Distribute the key to everybody who is on the channel. If we are router
279 we will also send it to locally connected servers. */
280 silc_server_send_channel_key(server, channel, FALSE);
283 /* Received packet to replace a ID. This checks that the requested ID
284 exists and replaces it with the new one. */
286 void silc_server_replace_id(SilcServer server,
287 SilcSocketConnection sock,
288 SilcPacketContext *packet)
290 SilcBuffer buffer = packet->buffer;
291 unsigned char *old_id = NULL, *new_id = NULL;
292 SilcIdType old_id_type, new_id_type;
293 unsigned short old_id_len, new_id_len;
294 void *id = NULL, *id2 = NULL;
296 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
297 packet->src_id_type == SILC_ID_CLIENT)
300 SILC_LOG_DEBUG(("Replacing ID"));
302 silc_buffer_unformat(buffer,
303 SILC_STR_UI_SHORT(&old_id_type),
304 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
305 SILC_STR_UI_SHORT(&new_id_type),
306 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
309 if (old_id_type != new_id_type)
312 if (old_id_len != silc_id_get_len(old_id_type) ||
313 new_id_len != silc_id_get_len(new_id_type))
316 id = silc_id_str2id(old_id, old_id_type);
320 id2 = silc_id_str2id(new_id, new_id_type);
324 /* If we are router and this packet is not already broadcast packet
325 we will broadcast it. The sending socket really cannot be router or
326 the router is buggy. If this packet is coming from router then it must
327 have the broadcast flag set already and we won't do anything. */
328 if (server->server_type == SILC_ROUTER &&
329 sock->type == SILC_SOCKET_TYPE_SERVER &&
330 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
331 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
332 silc_server_packet_send(server, server->router->connection, packet->type,
333 packet->flags | SILC_PACKET_FLAG_BROADCAST,
334 buffer->data, buffer->len, FALSE);
337 /* Replace the old ID */
338 switch(old_id_type) {
340 SILC_LOG_DEBUG(("Old Client ID id(%s)",
341 silc_id_render(id, SILC_ID_CLIENT)));
342 SILC_LOG_DEBUG(("New Client ID id(%s)",
343 silc_id_render(id2, SILC_ID_CLIENT)));
344 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
345 if (server->server_type == SILC_ROUTER)
346 silc_idlist_replace_client_id(server->global_list, id, id2);
350 SILC_LOG_DEBUG(("Old Server ID id(%s)",
351 silc_id_render(id, SILC_ID_CLIENT)));
352 SILC_LOG_DEBUG(("New Server ID id(%s)",
353 silc_id_render(id2, SILC_ID_CLIENT)));
354 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
355 if (server->server_type == SILC_ROUTER)
356 silc_idlist_replace_server_id(server->global_list, id, id2);
359 case SILC_ID_CHANNEL:
360 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
380 /* Received New Client packet and processes it. Creates Client ID for the
381 client. Client becomes registered after calling this functions. */
383 SilcClientEntry silc_server_new_client(SilcServer server,
384 SilcSocketConnection sock,
385 SilcPacketContext *packet)
387 SilcBuffer buffer = packet->buffer;
388 SilcClientEntry client;
389 SilcIDCacheEntry cache;
390 SilcClientID *client_id;
392 SilcIDListData idata;
393 char *username = NULL, *realname = NULL, *id_string;
395 SILC_LOG_DEBUG(("Creating new client"));
397 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
400 /* Take client entry */
401 client = (SilcClientEntry)sock->user_data;
402 idata = (SilcIDListData)client;
404 /* Fetch the old client cache entry so that we can update it. */
405 if (!silc_idcache_find_by_context(server->local_list->clients,
406 sock->user_data, &cache)) {
407 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
411 /* Parse incoming packet */
412 silc_buffer_unformat(buffer,
413 SILC_STR_UI16_STRING_ALLOC(&username),
414 SILC_STR_UI16_STRING_ALLOC(&realname),
417 /* Create Client ID */
418 silc_id_create_client_id(server->id, server->rng, server->md5hash,
419 username, &client_id);
421 /* Update client entry */
422 idata->registered = TRUE;
423 client->nickname = strdup(username);
424 client->username = username;
425 client->userinfo = realname;
426 client->id = client_id;
428 /* Update the cache entry */
429 cache->id = (void *)client_id;
430 cache->type = SILC_ID_CLIENT;
431 cache->data = username;
432 silc_idcache_sort_by_data(server->local_list->clients);
434 /* Notify our router about new client on the SILC network */
435 if (!server->standalone)
436 silc_server_send_new_id(server, (SilcSocketConnection)
437 server->router->connection,
438 server->server_type == SILC_ROUTER ? TRUE : FALSE,
439 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
441 /* Send the new client ID to the client. */
442 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
443 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
444 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
445 silc_buffer_format(reply,
446 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
447 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
448 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
450 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
451 reply->data, reply->len, FALSE);
452 silc_free(id_string);
453 silc_buffer_free(reply);
455 /* Send some nice info to the client */
456 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
457 ("Welcome to the SILC Network %s@%s",
458 username, sock->hostname));
459 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
460 ("Your host is %s, running version %s",
461 server->config->server_info->server_name,
463 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
464 ("Your connection is secured with %s cipher, "
465 "key length %d bits",
466 idata->send_key->cipher->name,
467 idata->send_key->cipher->key_len));
468 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
469 ("Your current nickname is %s",
473 silc_server_send_motd(server, sock);
478 /* Create new server. This processes received New Server packet and
479 saves the received Server ID. The server is our locally connected
480 server thus we save all the information and save it to local list.
481 This funtion can be used by both normal server and router server.
482 If normal server uses this it means that its router has connected
483 to the server. If router uses this it means that one of the cell's
484 servers is connected to the router. */
486 SilcServerEntry silc_server_new_server(SilcServer server,
487 SilcSocketConnection sock,
488 SilcPacketContext *packet)
490 SilcBuffer buffer = packet->buffer;
491 SilcServerEntry new_server;
492 SilcIDCacheEntry cache;
493 SilcServerID *server_id;
494 SilcIDListData idata;
495 unsigned char *server_name, *id_string;
496 unsigned short id_len;
498 SILC_LOG_DEBUG(("Creating new server"));
500 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
501 sock->type != SILC_SOCKET_TYPE_ROUTER)
504 /* Take server entry */
505 new_server = (SilcServerEntry)sock->user_data;
506 idata = (SilcIDListData)new_server;
508 /* Fetch the old server cache entry so that we can update it. */
509 if (!silc_idcache_find_by_context(server->local_list->servers,
510 sock->user_data, &cache)) {
511 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
515 /* Parse the incoming packet */
516 silc_buffer_unformat(buffer,
517 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
518 SILC_STR_UI16_STRING_ALLOC(&server_name),
521 if (id_len > buffer->len) {
522 silc_free(id_string);
523 silc_free(server_name);
528 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
529 silc_free(id_string);
531 /* Update client entry */
532 idata->registered = TRUE;
533 new_server->server_name = server_name;
534 new_server->id = server_id;
536 /* Update the cache entry */
537 cache->id = (void *)server_id;
538 cache->type = SILC_ID_SERVER;
539 cache->data = server_name;
540 silc_idcache_sort_by_data(server->local_list->servers);
542 /* Distribute the information about new server in the SILC network
543 to our router. If we are normal server we won't send anything
544 since this connection must be our router connection. */
545 if (server->server_type == SILC_ROUTER && !server->standalone &&
546 server->router->connection != sock)
547 silc_server_send_new_id(server, server->router->connection,
548 TRUE, new_server->id, SILC_ID_SERVER,
554 /* Processes incoming New ID packet. New ID Payload is used to distribute
555 information about newly registered clients and servers. */
557 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
558 SilcPacketContext *packet)
560 SilcBuffer buffer = packet->buffer;
562 SilcServerEntry router;
563 SilcSocketConnection router_sock;
566 unsigned char *hash = NULL;
569 SILC_LOG_DEBUG(("Processing new ID"));
571 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
572 server->server_type == SILC_SERVER ||
573 packet->src_id_type != SILC_ID_SERVER)
576 idp = silc_id_payload_parse(buffer);
580 id_type = silc_id_payload_get_type(idp);
582 /* Normal server cannot have other normal server connections */
583 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
586 id = silc_id_payload_get_id(idp);
590 /* If the sender of this packet is server and we are router we need to
591 broadcast this packet to other routers in the network. */
592 if (!server->standalone && server->server_type == SILC_ROUTER &&
593 sock->type == SILC_SOCKET_TYPE_SERVER &&
594 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
595 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
596 silc_server_packet_send(server, server->router->connection,
598 packet->flags | SILC_PACKET_FLAG_BROADCAST,
599 buffer->data, buffer->len, FALSE);
603 /* If the packet is originated from the one who sent it to us we know
604 that the ID belongs to our cell, unless the sender was router. */
605 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
606 tmpserver = (SilcServerEntry)sock->user_data;
608 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
609 sock->type == SILC_SOCKET_TYPE_SERVER) {
610 id_list = server->local_list;
612 router = sock->user_data;
613 /* router = server->id_entry; */
615 id_list = server->global_list;
616 router_sock = (SilcSocketConnection)server->router->connection;
617 router = server->router;
623 if (sock->type == SILC_SOCKET_TYPE_SERVER)
624 id_list = server->local_list;
626 id_list = server->global_list;
629 router = sock->user_data;
634 SilcClientEntry entry;
636 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
637 silc_id_render(id, SILC_ID_CLIENT),
638 sock->type == SILC_SOCKET_TYPE_SERVER ?
639 "Server" : "Router", sock->hostname));
641 /* As a router we keep information of all global information in our
642 global list. Cell wide information however is kept in the local
643 list. The client is put to global list and we will take the hash
644 value of the Client ID and save it to the ID Cache system for fast
645 searching in the future. */
646 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
647 sizeof(unsigned char));
648 memcpy(hash, ((SilcClientID *)id)->hash,
649 sizeof(((SilcClientID *)id)->hash));
650 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
651 router, router_sock);
652 entry->nickname = NULL;
655 /* XXX Adding two ID's with same IP number replaces the old entry thus
656 gives wrong route. Thus, now disabled until figured out a better way
657 to do this or when removed the whole thing. This could be removed
658 because entry->router->connection gives always the most optimal route
659 for the ID anyway (unless new routes (faster perhaps) are established
660 after receiving this ID, this we don't know however). */
661 /* Add route cache for this ID */
662 silc_server_route_add(silc_server_route_hash(
663 ((SilcClientID *)id)->ip.s_addr,
664 server->id->port), ((SilcClientID *)id)->ip.s_addr,
671 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
672 silc_id_render(id, SILC_ID_SERVER),
673 sock->type == SILC_SOCKET_TYPE_SERVER ?
674 "Server" : "Router", sock->hostname));
676 /* As a router we keep information of all global information in our global
677 list. Cell wide information however is kept in the local list. */
678 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
681 /* Add route cache for this ID */
682 silc_server_route_add(silc_server_route_hash(
683 ((SilcServerID *)id)->ip.s_addr,
684 ((SilcServerID *)id)->port),
685 ((SilcServerID *)id)->ip.s_addr,
690 case SILC_ID_CHANNEL:
691 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
699 silc_id_payload_free(idp);
702 /* Received Remove Channel User packet to remove a user from a channel.
703 Routers notify other routers that user has left a channel. Client must
704 not send this packet. Normal server may send this packet but must not
707 void silc_server_remove_channel_user(SilcServer server,
708 SilcSocketConnection sock,
709 SilcPacketContext *packet)
711 SilcBuffer buffer = packet->buffer;
712 unsigned char *tmp1 = NULL, *tmp2 = NULL;
713 SilcClientID *client_id = NULL;
714 SilcChannelID *channel_id = NULL;
715 SilcChannelEntry channel;
716 SilcClientEntry client;
718 SILC_LOG_DEBUG(("Removing user from channel"));
720 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
721 server->server_type == SILC_SERVER)
724 silc_buffer_unformat(buffer,
725 SILC_STR_UI16_STRING_ALLOC(&tmp1),
726 SILC_STR_UI16_STRING_ALLOC(&tmp2),
732 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
733 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
734 if (!client_id || !channel_id)
737 /* If we are router and this packet is not already broadcast packet
738 we will broadcast it. The sending socket really cannot be router or
739 the router is buggy. If this packet is coming from router then it must
740 have the broadcast flag set already and we won't do anything. */
741 if (!server->standalone && server->server_type == SILC_ROUTER &&
742 sock->type == SILC_SOCKET_TYPE_SERVER &&
743 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
744 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
745 silc_server_packet_send(server, server->router->connection, packet->type,
746 packet->flags | SILC_PACKET_FLAG_BROADCAST,
747 buffer->data, buffer->len, FALSE);
750 /* Get channel entry */
751 channel = silc_idlist_find_channel_by_id(server->local_list,
754 channel = silc_idlist_find_channel_by_id(server->global_list,
760 /* Get client entry */
761 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
763 client = silc_idlist_find_client_by_id(server->global_list,
769 /* Remove user from channel */
770 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
778 silc_free(client_id);
780 silc_free(channel_id);
783 /* Received New Channel packet. Information about new channels in the
784 network are distributed using this packet. Save the information about
787 void silc_server_new_channel(SilcServer server,
788 SilcSocketConnection sock,
789 SilcPacketContext *packet)
792 SilcChannelID *channel_id;
793 unsigned short channel_id_len;
796 SILC_LOG_DEBUG(("Processing New Channel"));
798 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
799 server->server_type == SILC_SERVER ||
800 packet->src_id_type != SILC_ID_SERVER)
804 if (!silc_buffer_unformat(packet->buffer,
805 SILC_STR_UI16_STRING_ALLOC(&channel_name),
806 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
810 if (!channel_name || !id)
813 /* Decode the channel ID */
814 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
819 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
820 silc_id_render(channel_id, SILC_ID_CHANNEL),
823 /* Add the new channel. Add it always to global list since if we receive
824 this packet then it cannot be created by ourselves but some other
825 router hence global channel. */
826 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
827 server->router->connection, NULL);
830 /* Received notify packet. Server can receive notify packets from router.
831 Server then relays the notify messages to clients if needed. */
833 void silc_server_notify(SilcServer server,
834 SilcSocketConnection sock,
835 SilcPacketContext *packet)
837 SilcNotifyPayload payload;
839 SilcArgumentPayload args;
840 SilcChannelID *channel_id;
841 SilcClientID *client_id;
842 SilcChannelEntry channel;
843 SilcClientEntry client;
845 unsigned int tmp_len;
847 SILC_LOG_DEBUG(("Start"));
849 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
850 packet->src_id_type != SILC_ID_SERVER)
853 /* XXX: For now we expect that the we are normal server and that the
854 sender is router. Server could send (protocol allows it) notify to
855 router but we don't support it yet. */
856 if (server->server_type != SILC_SERVER &&
857 sock->type != SILC_SOCKET_TYPE_ROUTER)
860 payload = silc_notify_payload_parse(packet->buffer);
864 type = silc_notify_get_type(payload);
865 args = silc_notify_get_args(payload);
870 case SILC_NOTIFY_TYPE_JOIN:
872 * Distribute the notify to local clients on the channel
874 SILC_LOG_DEBUG(("JOIN notify"));
876 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
880 /* Get channel entry */
881 channel = silc_idlist_find_channel_by_id(server->local_list,
884 silc_free(channel_id);
889 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
891 silc_free(channel_id);
894 client_id = silc_id_payload_parse_id(tmp, tmp_len);
896 /* If the the client is not in local list we check global list (ie. the
897 channel will be global channel) and if it does not exist then create
898 entry for the client. */
899 client = silc_idlist_find_client_by_id(server->local_list,
902 SilcChannelClientEntry chl;
904 client = silc_idlist_find_client_by_id(server->global_list,
907 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
908 client_id, sock->user_data, sock);
910 /* The channel is global now */
911 channel->global_users = TRUE;
913 /* Now actually JOIN the global client to the channel */
914 chl = silc_calloc(1, sizeof(*chl));
915 chl->client = client;
916 chl->channel = channel;
917 silc_list_add(channel->user_list, chl);
918 silc_list_add(client->channels, chl);
920 silc_free(client_id);
923 /* Send to channel */
924 silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
925 packet->buffer->data,
926 packet->buffer->len, FALSE);
929 case SILC_NOTIFY_TYPE_LEAVE:
931 * Distribute the notify to local clients on the channel
933 SILC_LOG_DEBUG(("LEAVE notify"));
935 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
939 /* Get channel entry */
940 channel = silc_idlist_find_channel_by_id(server->local_list,
943 silc_free(channel_id);
948 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
950 silc_free(channel_id);
953 client_id = silc_id_payload_parse_id(tmp, tmp_len);
955 /* Send to channel */
956 silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
957 packet->buffer->data,
958 packet->buffer->len, FALSE);
960 /* Get client entry */
961 client = silc_idlist_find_client_by_id(server->global_list,
964 client = silc_idlist_find_client_by_id(server->local_list,
967 silc_free(channel_id);
971 silc_free(client_id);
973 /* Remove the user from channel */
974 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
977 case SILC_NOTIFY_TYPE_SIGNOFF:
979 * Distribute the notify to local clients on the channel
981 SILC_LOG_DEBUG(("SIGNOFF notify"));
984 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
987 client_id = silc_id_payload_parse_id(tmp, tmp_len);
989 /* Get client entry */
990 client = silc_idlist_find_client_by_id(server->global_list,
993 client = silc_idlist_find_client_by_id(server->local_list,
998 silc_free(client_id);
1000 /* Remove the client from all channels */
1001 silc_server_remove_from_channels(server, NULL, client);
1003 /* Remove the client entry */
1004 silc_idlist_del_client(server->global_list, client);
1007 /* Ignore rest notify types for now */
1008 case SILC_NOTIFY_TYPE_NONE:
1009 case SILC_NOTIFY_TYPE_INVITE:
1010 case SILC_NOTIFY_TYPE_TOPIC_SET:
1011 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1012 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1013 case SILC_NOTIFY_TYPE_MOTD:
1019 silc_notify_payload_free(payload);
1022 /* Received new channel user packet. Information about new users on a
1023 channel are distributed between routers using this packet. The
1024 router receiving this will redistribute it and also sent JOIN notify
1025 to local clients on the same channel. Normal server sends JOIN notify
1026 to its local clients on the channel. */
1028 void silc_server_new_channel_user(SilcServer server,
1029 SilcSocketConnection sock,
1030 SilcPacketContext *packet)
1032 unsigned char *tmpid1, *tmpid2;
1033 SilcClientID *client_id = NULL;
1034 SilcChannelID *channel_id = NULL;
1035 unsigned short channel_id_len;
1036 unsigned short client_id_len;
1037 SilcClientEntry client;
1038 SilcChannelEntry channel;
1039 SilcChannelClientEntry chl;
1041 SilcServerEntry tmpserver, router;
1042 SilcSocketConnection router_sock;
1046 SILC_LOG_DEBUG(("Start"));
1048 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1049 server->server_type != SILC_ROUTER ||
1050 packet->src_id_type != SILC_ID_SERVER)
1054 if (!silc_buffer_unformat(packet->buffer,
1055 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1057 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1062 if (!tmpid1 || !tmpid2)
1065 /* Decode the channel ID */
1066 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
1070 /* Decode the client ID */
1071 client_id = silc_id_str2id(tmpid2, SILC_ID_CLIENT);
1076 /* If the packet is originated from the one who sent it to us we know
1077 that the ID belongs to our cell, unless the sender was router. */
1078 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
1079 tmpserver = (SilcServerEntry)sock->user_data;
1081 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
1082 sock->type == SILC_SOCKET_TYPE_SERVER) {
1083 id_list = server->local_list;
1085 router = sock->user_data;
1087 id_list = server->global_list;
1088 router_sock = (SilcSocketConnection)server->router->connection;
1089 router = server->router;
1095 router = sock->user_data;
1097 /* Find the channel */
1098 channel = silc_idlist_find_channel_by_id(server->local_list,
1101 channel = silc_idlist_find_channel_by_id(server->global_list,
1107 /* If we are router and this packet is not already broadcast packet
1108 we will broadcast it. */
1109 if (!server->standalone && server->server_type == SILC_ROUTER &&
1110 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1111 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1112 silc_server_packet_send(server, server->router->connection, packet->type,
1113 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1114 packet->buffer->data, packet->buffer->len, FALSE);
1117 /* Get client entry */
1118 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1120 client = silc_idlist_find_client_by_id(server->global_list,
1126 /* Join the client to the channel by adding it to channel's user list.
1127 Add also the channel to client entry's channels list for fast cross-
1129 chl = silc_calloc(1, sizeof(*chl));
1130 chl->client = client;
1131 chl->channel = channel;
1132 silc_list_add(channel->user_list, chl);
1133 silc_list_add(client->channels, chl);
1135 /* Send JOIN notify to local clients on the channel. As we are router
1136 it is assured that this is sent only to our local clients and locally
1137 connected servers if needed. */
1138 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1139 silc_server_send_notify_to_channel(server, channel, FALSE,
1140 SILC_NOTIFY_TYPE_JOIN,
1141 1, clidp->data, clidp->len);
1142 silc_buffer_free(clidp);
1148 silc_free(client_id);
1150 silc_free(channel_id);
1155 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1156 that certain ID should be removed. After that the ID will become invalid. */
1158 void silc_server_remove_id(SilcServer server,
1159 SilcSocketConnection sock,
1160 SilcPacketContext *packet)
1165 void *id, *id_entry;
1167 SILC_LOG_DEBUG(("Start"));
1169 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1170 server->server_type == SILC_SERVER ||
1171 packet->src_id_type != SILC_ID_SERVER)
1174 idp = silc_id_payload_parse(packet->buffer);
1178 id_type = silc_id_payload_get_type(idp);
1180 id = silc_id_payload_get_id(idp);
1184 /* If the sender of this packet is server and we are router we need to
1185 broadcast this packet to other routers in the network. */
1186 if (!server->standalone && server->server_type == SILC_ROUTER &&
1187 sock->type == SILC_SOCKET_TYPE_SERVER &&
1188 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1189 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1190 silc_server_packet_send(server, server->router->connection,
1192 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1193 packet->buffer->data, packet->buffer->len, FALSE);
1196 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1197 id_list = server->local_list;
1199 id_list = server->global_list;
1203 case SILC_ID_CLIENT:
1204 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1207 /* Remove from channels */
1208 silc_server_remove_from_channels(server, NULL, id_entry);
1210 /* Remove the client entry */
1211 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1213 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1214 silc_id_render(id, SILC_ID_CLIENT),
1215 sock->type == SILC_SOCKET_TYPE_SERVER ?
1216 "Server" : "Router", sock->hostname));
1220 case SILC_ID_SERVER:
1221 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1224 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1226 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1227 silc_id_render(id, SILC_ID_SERVER),
1228 sock->type == SILC_SOCKET_TYPE_SERVER ?
1229 "Server" : "Router", sock->hostname));
1233 case SILC_ID_CHANNEL:
1234 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1237 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1239 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1240 silc_id_render(id, SILC_ID_CHANNEL),
1241 sock->type == SILC_SOCKET_TYPE_SERVER ?
1242 "Server" : "Router", sock->hostname));
1251 silc_id_payload_free(idp);