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 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, packet->dst_id_len, 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)client->router;
72 idata = (SilcIDListData)router;
74 silc_server_send_private_message(server, router->connection,
81 /* Seems that client really is directly connected to us */
82 idata = (SilcIDListData)client;
83 silc_server_send_private_message(server, dst_sock,
89 /* Destination belongs to someone not in this server. If we are normal
90 server our action is to send the packet to our router. */
91 if (server->server_type == SILC_SERVER && !server->standalone) {
92 router = server->router;
94 /* Send to primary route */
96 dst_sock = (SilcSocketConnection)router->connection;
97 idata = (SilcIDListData)router;
98 silc_server_send_private_message(server, dst_sock,
100 idata->hmac, packet);
105 /* We are router and we will perform route lookup for the destination
106 and send the message to fastest route. */
107 if (server->server_type == SILC_ROUTER && !server->standalone) {
108 /* Check first that the ID is valid */
109 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
111 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
112 router = (SilcServerEntry)dst_sock->user_data;
113 idata = (SilcIDListData)router;
115 /* Get fastest route and send packet. */
117 silc_server_send_private_message(server, dst_sock,
119 idata->hmac, packet);
125 silc_server_send_error(server, sock,
126 "No such nickname: Private message not sent");
129 /* Processes incoming command reply packet. The command reply packet may
130 be destined to one of our clients or it may directly for us. We will
131 call the command reply routine after processing the packet. */
133 void silc_server_command_reply(SilcServer server,
134 SilcSocketConnection sock,
135 SilcPacketContext *packet)
137 SilcBuffer buffer = packet->buffer;
138 SilcClientEntry client = NULL;
139 SilcSocketConnection dst_sock;
140 SilcIDListData idata;
141 SilcClientID *id = NULL;
143 SILC_LOG_DEBUG(("Start"));
145 /* Source must be server or router */
146 if (packet->src_id_type != SILC_ID_SERVER &&
147 sock->type != SILC_SOCKET_TYPE_ROUTER)
150 if (packet->dst_id_type == SILC_ID_CHANNEL)
153 if (packet->dst_id_type == SILC_ID_CLIENT) {
154 /* Destination must be one of ours */
155 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
158 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
160 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
166 if (packet->dst_id_type == SILC_ID_SERVER) {
167 /* For now this must be for us */
168 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
169 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
174 /* Execute command reply locally for the command */
175 silc_server_command_reply_process(server, sock, buffer);
177 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
178 /* Relay the packet to the client */
180 dst_sock = (SilcSocketConnection)client->connection;
181 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
182 + packet->dst_id_len + packet->padlen);
184 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
185 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
187 idata = (SilcIDListData)client;
190 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
193 /* Send the packet */
194 silc_server_packet_send_real(server, dst_sock, TRUE);
200 /* Process received channel message. The message can be originated from
203 void silc_server_channel_message(SilcServer server,
204 SilcSocketConnection sock,
205 SilcPacketContext *packet)
207 SilcChannelEntry channel = NULL;
208 SilcChannelClientEntry chl;
209 SilcChannelID *id = NULL;
212 SILC_LOG_DEBUG(("Processing channel message"));
215 if (packet->dst_id_type != SILC_ID_CHANNEL) {
216 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
220 /* Find channel entry */
221 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
224 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
226 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
228 SILC_LOG_DEBUG(("Could not find channel"));
233 /* See that this client is on the channel. If the message is coming
234 from router we won't do the check as the message is from client that
235 we don't know about. Also, if the original sender is not client
236 (as it can be server as well) we don't do the check. */
237 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
238 packet->src_id_type);
241 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
242 packet->src_id_type == SILC_ID_CLIENT) {
243 silc_list_start(channel->user_list);
244 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
245 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
248 if (chl == SILC_LIST_END)
252 /* Distribute the packet to our local clients. This will send the
253 packet for further routing as well, if needed. */
254 silc_server_packet_relay_to_channel(server, sock, channel, sender,
256 packet->buffer->data,
257 packet->buffer->len, FALSE);
266 /* Received channel key packet. We distribute the key to all of our locally
267 connected clients on the channel. */
269 void silc_server_channel_key(SilcServer server,
270 SilcSocketConnection sock,
271 SilcPacketContext *packet)
273 SilcBuffer buffer = packet->buffer;
274 SilcChannelEntry channel;
276 if (packet->src_id_type != SILC_ID_SERVER)
279 /* Save the channel key */
280 channel = silc_server_save_channel_key(server, buffer, NULL);
284 /* Distribute the key to everybody who is on the channel. If we are router
285 we will also send it to locally connected servers. */
286 silc_server_send_channel_key(server, sock, channel, FALSE);
289 /* Received packet to replace a ID. This checks that the requested ID
290 exists and replaces it with the new one. */
292 void silc_server_replace_id(SilcServer server,
293 SilcSocketConnection sock,
294 SilcPacketContext *packet)
296 SilcBuffer buffer = packet->buffer;
297 unsigned char *old_id = NULL, *new_id = NULL;
298 SilcIdType old_id_type, new_id_type;
299 unsigned short old_id_len, new_id_len;
300 void *id = NULL, *id2 = NULL;
303 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
304 packet->src_id_type == SILC_ID_CLIENT)
307 SILC_LOG_DEBUG(("Replacing ID"));
309 ret = silc_buffer_unformat(buffer,
310 SILC_STR_UI_SHORT(&old_id_type),
311 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
312 SILC_STR_UI_SHORT(&new_id_type),
313 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
318 if (old_id_type != new_id_type)
321 if (old_id_len != silc_id_get_len(old_id_type) ||
322 new_id_len != silc_id_get_len(new_id_type))
325 id = silc_id_str2id(old_id, old_id_len, old_id_type);
329 id2 = silc_id_str2id(new_id, new_id_len, new_id_type);
333 /* If we are router and this packet is not already broadcast packet
334 we will broadcast it. The sending socket really cannot be router or
335 the router is buggy. If this packet is coming from router then it must
336 have the broadcast flag set already and we won't do anything. */
337 if (!server->standalone && server->server_type == SILC_ROUTER &&
338 sock->type == SILC_SOCKET_TYPE_SERVER &&
339 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
340 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
341 silc_server_packet_send(server, server->router->connection, packet->type,
342 packet->flags | SILC_PACKET_FLAG_BROADCAST,
343 buffer->data, buffer->len, FALSE);
346 /* Replace the old ID */
347 switch(old_id_type) {
350 SilcBuffer nidp, oidp;
351 SilcClientEntry client = NULL;
353 SILC_LOG_DEBUG(("Old Client ID id(%s)",
354 silc_id_render(id, SILC_ID_CLIENT)));
355 SILC_LOG_DEBUG(("New Client ID id(%s)",
356 silc_id_render(id2, SILC_ID_CLIENT)));
358 if ((client = silc_idlist_replace_client_id(server->local_list,
360 if (server->server_type == SILC_ROUTER)
361 client = silc_idlist_replace_client_id(server->global_list, id, id2);
364 oidp = silc_id_payload_encode(id, SILC_ID_CLIENT);
365 nidp = silc_id_payload_encode(id2, SILC_ID_CLIENT);
367 /* The nickname is not valid anymore, set it NULL. This causes that
368 the nickname will be queried if someone wants to know it. */
369 if (client->nickname)
370 silc_free(client->nickname);
371 client->nickname = NULL;
373 /* Send the NICK_CHANGE notify type to local clients on the channels
374 this client is joined to. */
375 silc_server_send_notify_on_channels(server, client,
376 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
377 oidp->data, oidp->len,
378 nidp->data, nidp->len);
380 silc_buffer_free(nidp);
381 silc_buffer_free(oidp);
387 SILC_LOG_DEBUG(("Old Server ID id(%s)",
388 silc_id_render(id, SILC_ID_SERVER)));
389 SILC_LOG_DEBUG(("New Server ID id(%s)",
390 silc_id_render(id2, SILC_ID_SERVER)));
391 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
392 if (server->server_type == SILC_ROUTER)
393 silc_idlist_replace_server_id(server->global_list, id, id2);
396 case SILC_ID_CHANNEL:
397 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
398 silc_id_render(id, SILC_ID_CHANNEL)));
399 SILC_LOG_DEBUG(("New Channel ID id(%s)",
400 silc_id_render(id2, SILC_ID_CHANNEL)));
401 if (silc_idlist_replace_channel_id(server->local_list, id, id2) == NULL)
402 silc_idlist_replace_channel_id(server->global_list, id, id2);
420 /* Received New Client packet and processes it. Creates Client ID for the
421 client. Client becomes registered after calling this functions. */
423 SilcClientEntry silc_server_new_client(SilcServer server,
424 SilcSocketConnection sock,
425 SilcPacketContext *packet)
427 SilcBuffer buffer = packet->buffer;
428 SilcClientEntry client;
429 SilcIDCacheEntry cache;
430 SilcClientID *client_id;
432 SilcIDListData idata;
433 char *username = NULL, *realname = NULL, *id_string;
436 SILC_LOG_DEBUG(("Creating new client"));
438 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
441 /* Take client entry */
442 client = (SilcClientEntry)sock->user_data;
443 idata = (SilcIDListData)client;
445 /* Fetch the old client cache entry so that we can update it. */
446 if (!silc_idcache_find_by_context(server->local_list->clients,
447 sock->user_data, &cache)) {
448 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
452 /* Parse incoming packet */
453 ret = silc_buffer_unformat(buffer,
454 SILC_STR_UI16_STRING_ALLOC(&username),
455 SILC_STR_UI16_STRING_ALLOC(&realname),
465 /* Create Client ID */
466 silc_id_create_client_id(server->id, server->rng, server->md5hash,
467 username, &client_id);
469 /* Update client entry */
470 idata->registered = TRUE;
471 client->nickname = strdup(username);
472 client->username = username;
473 client->userinfo = realname;
474 client->id = client_id;
476 /* Update the cache entry */
477 cache->id = (void *)client_id;
478 cache->type = SILC_ID_CLIENT;
479 cache->data = username;
480 silc_idcache_sort_by_data(server->local_list->clients);
482 /* Notify our router about new client on the SILC network */
483 if (!server->standalone)
484 silc_server_send_new_id(server, (SilcSocketConnection)
485 server->router->connection,
486 server->server_type == SILC_ROUTER ? TRUE : FALSE,
487 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
489 /* Send the new client ID to the client. */
490 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
491 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
492 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
493 silc_buffer_format(reply,
494 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
495 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
496 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
498 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
499 reply->data, reply->len, FALSE);
500 silc_free(id_string);
501 silc_buffer_free(reply);
503 /* Send some nice info to the client */
504 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
505 ("Welcome to the SILC Network %s@%s",
506 username, sock->hostname));
507 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
508 ("Your host is %s, running version %s",
509 server->config->server_info->server_name,
511 if (server->server_type == SILC_ROUTER) {
512 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
513 ("There are %d clients on %d servers in SILC "
514 "Network", server->stat.clients,
515 server->stat.servers + 1));
516 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
517 ("There are %d clients on %d server in our cell",
518 server->stat.cell_clients,
519 server->stat.cell_servers + 1));
520 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
521 ("I have %d clients, %d channels, %d servers and "
523 server->stat.my_clients,
524 server->stat.my_channels,
525 server->stat.my_servers,
526 server->stat.my_routers));
527 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
528 ("%d server operators and %d router operators "
530 server->stat.my_server_ops,
531 server->stat.my_router_ops));
533 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
534 ("I have %d clients and %d channels formed",
535 server->stat.my_clients,
536 server->stat.my_channels));
537 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
538 ("%d operators online",
539 server->stat.my_server_ops));
541 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
542 ("Your connection is secured with %s cipher, "
543 "key length %d bits",
544 idata->send_key->cipher->name,
545 idata->send_key->cipher->key_len));
546 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
547 ("Your current nickname is %s",
551 silc_server_send_motd(server, sock);
556 /* Create new server. This processes received New Server packet and
557 saves the received Server ID. The server is our locally connected
558 server thus we save all the information and save it to local list.
559 This funtion can be used by both normal server and router server.
560 If normal server uses this it means that its router has connected
561 to the server. If router uses this it means that one of the cell's
562 servers is connected to the router. */
564 SilcServerEntry silc_server_new_server(SilcServer server,
565 SilcSocketConnection sock,
566 SilcPacketContext *packet)
568 SilcBuffer buffer = packet->buffer;
569 SilcServerEntry new_server;
570 SilcIDCacheEntry cache;
571 SilcServerID *server_id;
572 SilcIDListData idata;
573 unsigned char *server_name, *id_string;
574 unsigned short id_len;
577 SILC_LOG_DEBUG(("Creating new server"));
579 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
580 sock->type != SILC_SOCKET_TYPE_ROUTER)
583 /* Take server entry */
584 new_server = (SilcServerEntry)sock->user_data;
585 idata = (SilcIDListData)new_server;
587 /* Fetch the old server cache entry so that we can update it. */
588 if (!silc_idcache_find_by_context(server->local_list->servers,
589 sock->user_data, &cache)) {
590 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
594 /* Parse the incoming packet */
595 ret = silc_buffer_unformat(buffer,
596 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
597 SILC_STR_UI16_STRING_ALLOC(&server_name),
601 silc_free(id_string);
603 silc_free(server_name);
607 if (id_len > buffer->len) {
608 silc_free(id_string);
609 silc_free(server_name);
614 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
616 silc_free(id_string);
617 silc_free(server_name);
620 silc_free(id_string);
622 /* Update client entry */
623 idata->registered = TRUE;
624 new_server->server_name = server_name;
625 new_server->id = server_id;
627 /* Update the cache entry */
628 cache->id = (void *)server_id;
629 cache->type = SILC_ID_SERVER;
630 cache->data = server_name;
631 silc_idcache_sort_by_data(server->local_list->servers);
633 /* Distribute the information about new server in the SILC network
634 to our router. If we are normal server we won't send anything
635 since this connection must be our router connection. */
636 if (server->server_type == SILC_ROUTER && !server->standalone &&
637 server->router->connection != sock)
638 silc_server_send_new_id(server, server->router->connection,
639 TRUE, new_server->id, SILC_ID_SERVER,
642 if (server->server_type == SILC_ROUTER)
643 server->stat.cell_servers++;
648 /* Processes incoming New ID packet. New ID Payload is used to distribute
649 information about newly registered clients and servers. */
651 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
652 SilcPacketContext *packet)
654 SilcBuffer buffer = packet->buffer;
656 SilcServerEntry router;
657 SilcSocketConnection router_sock;
660 unsigned char *hash = NULL;
663 SILC_LOG_DEBUG(("Processing new ID"));
665 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
666 server->server_type == SILC_SERVER ||
667 packet->src_id_type != SILC_ID_SERVER)
670 idp = silc_id_payload_parse(buffer);
674 id_type = silc_id_payload_get_type(idp);
676 /* Normal server cannot have other normal server connections */
677 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
680 id = silc_id_payload_get_id(idp);
684 /* If the sender of this packet is server and we are router we need to
685 broadcast this packet to other routers in the network. */
686 if (!server->standalone && server->server_type == SILC_ROUTER &&
687 sock->type == SILC_SOCKET_TYPE_SERVER &&
688 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
689 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
690 silc_server_packet_send(server, server->router->connection,
692 packet->flags | SILC_PACKET_FLAG_BROADCAST,
693 buffer->data, buffer->len, FALSE);
696 if (sock->type == SILC_SOCKET_TYPE_SERVER)
697 id_list = server->local_list;
699 id_list = server->global_list;
702 router = sock->user_data;
707 SilcClientEntry entry;
709 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
710 silc_id_render(id, SILC_ID_CLIENT),
711 sock->type == SILC_SOCKET_TYPE_SERVER ?
712 "Server" : "Router", sock->hostname));
714 /* As a router we keep information of all global information in our
715 global list. Cell wide information however is kept in the local
716 list. The client is put to global list and we will take the hash
717 value of the Client ID and save it to the ID Cache system for fast
718 searching in the future. */
719 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
720 sizeof(unsigned char));
721 memcpy(hash, ((SilcClientID *)id)->hash,
722 sizeof(((SilcClientID *)id)->hash));
723 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
725 entry->nickname = NULL;
727 if (sock->type == SILC_SOCKET_TYPE_SERVER)
728 server->stat.cell_clients++;
729 server->stat.clients++;
732 /* XXX Adding two ID's with same IP number replaces the old entry thus
733 gives wrong route. Thus, now disabled until figured out a better way
734 to do this or when removed the whole thing. This could be removed
735 because entry->router->connection gives always the most optimal route
736 for the ID anyway (unless new routes (faster perhaps) are established
737 after receiving this ID, this we don't know however). */
738 /* Add route cache for this ID */
739 silc_server_route_add(silc_server_route_hash(
740 ((SilcClientID *)id)->ip.s_addr,
741 server->id->port), ((SilcClientID *)id)->ip.s_addr,
748 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
749 silc_id_render(id, SILC_ID_SERVER),
750 sock->type == SILC_SOCKET_TYPE_SERVER ?
751 "Server" : "Router", sock->hostname));
753 /* As a router we keep information of all global information in our global
754 list. Cell wide information however is kept in the local list. */
755 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
757 if (sock->type == SILC_SOCKET_TYPE_SERVER)
758 server->stat.cell_servers++;
759 server->stat.servers++;
762 /* Add route cache for this ID */
763 silc_server_route_add(silc_server_route_hash(
764 ((SilcServerID *)id)->ip.s_addr,
765 ((SilcServerID *)id)->port),
766 ((SilcServerID *)id)->ip.s_addr,
771 case SILC_ID_CHANNEL:
772 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
780 silc_id_payload_free(idp);
783 /* Receoved New Id List packet, list of New ID payloads inside one
784 packet. Process the New ID payloads one by one. */
786 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
787 SilcPacketContext *packet)
789 SilcPacketContext *new_id;
791 unsigned short id_len;
793 SILC_LOG_DEBUG(("Processing New ID List"));
795 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
796 packet->src_id_type != SILC_ID_SERVER)
799 /* Make copy of the original packet context, except for the actual
800 data buffer, which we will here now fetch from the original buffer. */
801 new_id = silc_packet_context_alloc();
802 new_id->type = SILC_PACKET_NEW_ID;
803 new_id->flags = packet->flags;
804 new_id->src_id = packet->src_id;
805 new_id->src_id_len = packet->src_id_len;
806 new_id->src_id_type = packet->src_id_type;
807 new_id->dst_id = packet->dst_id;
808 new_id->dst_id_len = packet->dst_id_len;
809 new_id->dst_id_type = packet->dst_id_type;
811 idp = silc_buffer_alloc(256);
812 new_id->buffer = idp;
814 while (packet->buffer->len) {
815 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
816 if ((id_len > packet->buffer->len) ||
817 (id_len > idp->truelen))
820 silc_buffer_pull_tail(idp, 4 + id_len);
821 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
823 /* Process the New ID */
824 silc_server_new_id(server, sock, new_id);
826 silc_buffer_push_tail(idp, 4 + id_len);
827 silc_buffer_pull(packet->buffer, 4 + id_len);
830 silc_buffer_free(idp);
834 /* Received New Channel packet. Information about new channels in the
835 network are distributed using this packet. Save the information about
836 the new channel. This usually comes from router but also normal server
837 can send this to notify channels it has when it connects to us. */
839 void silc_server_new_channel(SilcServer server,
840 SilcSocketConnection sock,
841 SilcPacketContext *packet)
844 SilcChannelID *channel_id;
845 unsigned short channel_id_len;
849 SILC_LOG_DEBUG(("Processing New Channel"));
851 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
852 packet->src_id_type != SILC_ID_SERVER ||
853 server->server_type == SILC_SERVER)
857 ret = silc_buffer_unformat(packet->buffer,
858 SILC_STR_UI16_STRING_ALLOC(&channel_name),
859 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
863 silc_free(channel_name);
869 /* Decode the channel ID */
870 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
874 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
875 /* Add the server to global list as it is coming from router. It
876 cannot be our own channel as it is coming from router. */
878 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
879 silc_id_render(channel_id, SILC_ID_CHANNEL),
882 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
883 server->router->connection, NULL);
885 server->stat.channels++;
887 /* The channel is coming from our server, thus it is in our cell
888 we will add it to our local list. */
889 SilcChannelEntry channel;
892 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
893 silc_id_render(channel_id, SILC_ID_CHANNEL),
896 /* Check that we don't already have this channel */
897 channel = silc_idlist_find_channel_by_name(server->local_list,
900 channel = silc_idlist_find_channel_by_name(server->global_list,
903 /* If the channel does not exist, then create it. We create the channel
904 with the channel ID provided by the server. This creates a new
905 key to the channel as well that we will send to the server. */
907 channel = silc_server_create_new_channel_with_id(server, NULL,
913 /* Send the new channel key to the server */
914 chk = silc_channel_key_payload_encode(channel_id_len, id,
915 strlen(channel->channel_key->
917 channel->channel_key->cipher->name,
918 channel->key_len / 8,
920 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
921 chk->data, chk->len, FALSE);
922 silc_buffer_free(chk);
925 /* The channel exist by that name, check whether the ID's match.
926 If they don't then we'll force the server to use the ID we have.
927 We also create a new key for the channel. */
929 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
930 /* They don't match, send Replace ID packet to the server to
931 force the ID change. */
932 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
933 silc_server_send_replace_id(server, sock, FALSE,
934 channel_id, SILC_ID_CHANNEL,
936 channel->id, SILC_ID_CHANNEL,
937 SILC_ID_CHANNEL_LEN);
940 /* Create new key for the channel and send it to the server and
941 everybody else possibly on the channel. */
943 silc_server_create_channel_key(server, channel, 0);
945 /* Send to the channel */
946 silc_server_send_channel_key(server, sock, channel, FALSE);
948 /* Send to the server */
949 chk = silc_channel_key_payload_encode(channel_id_len, id,
950 strlen(channel->channel_key->
952 channel->channel_key->cipher->name,
953 channel->key_len / 8,
955 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
956 chk->data, chk->len, FALSE);
957 silc_buffer_free(chk);
964 /* Received New Channel List packet, list of New Channel List payloads inside
965 one packet. Process the New Channel payloads one by one. */
967 void silc_server_new_channel_list(SilcServer server,
968 SilcSocketConnection sock,
969 SilcPacketContext *packet)
971 SilcPacketContext *new;
973 unsigned short len1, len2;
975 SILC_LOG_DEBUG(("Processing New Channel List"));
977 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
978 packet->src_id_type != SILC_ID_SERVER ||
979 server->server_type == SILC_SERVER)
982 /* Make copy of the original packet context, except for the actual
983 data buffer, which we will here now fetch from the original buffer. */
984 new = silc_packet_context_alloc();
985 new->type = SILC_PACKET_NEW_CHANNEL;
986 new->flags = packet->flags;
987 new->src_id = packet->src_id;
988 new->src_id_len = packet->src_id_len;
989 new->src_id_type = packet->src_id_type;
990 new->dst_id = packet->dst_id;
991 new->dst_id_len = packet->dst_id_len;
992 new->dst_id_type = packet->dst_id_type;
994 buffer = silc_buffer_alloc(512);
995 new->buffer = buffer;
997 while (packet->buffer->len) {
998 SILC_GET16_MSB(len1, packet->buffer->data);
999 if ((len1 > packet->buffer->len) ||
1000 (len1 > buffer->truelen))
1003 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1004 if ((len2 > packet->buffer->len) ||
1005 (len2 > buffer->truelen))
1008 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1009 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1011 /* Process the New Channel */
1012 silc_server_new_channel(server, sock, new);
1014 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1015 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1018 silc_buffer_free(buffer);
1022 /* Received Remove Channel User packet to remove a user from a channel.
1023 Routers notify other routers that user has left a channel. Client must
1024 not send this packet. Normal server may send this packet but must not
1027 void silc_server_remove_channel_user(SilcServer server,
1028 SilcSocketConnection sock,
1029 SilcPacketContext *packet)
1031 SilcBuffer buffer = packet->buffer;
1032 unsigned char *tmp1 = NULL, *tmp2 = NULL;
1033 unsigned short tmp1_len, tmp2_len;
1034 SilcClientID *client_id = NULL;
1035 SilcChannelID *channel_id = NULL;
1036 SilcChannelEntry channel;
1037 SilcClientEntry client;
1040 SILC_LOG_DEBUG(("Removing user from channel"));
1042 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1043 packet->src_id_type != SILC_ID_SERVER ||
1044 server->server_type == SILC_SERVER)
1047 ret = silc_buffer_unformat(buffer,
1048 SILC_STR_UI16_NSTRING_ALLOC(&tmp1, &tmp1_len),
1049 SILC_STR_UI16_NSTRING_ALLOC(&tmp2, &tmp2_len),
1054 client_id = silc_id_str2id(tmp1, tmp1_len, SILC_ID_CLIENT);
1055 channel_id = silc_id_str2id(tmp2, tmp2_len, SILC_ID_CHANNEL);
1056 if (!client_id || !channel_id)
1059 /* If we are router and this packet is not already broadcast packet
1060 we will broadcast it. The sending socket really cannot be router or
1061 the router is buggy. If this packet is coming from router then it must
1062 have the broadcast flag set already and we won't do anything. */
1063 if (!server->standalone && server->server_type == SILC_ROUTER &&
1064 sock->type == SILC_SOCKET_TYPE_SERVER &&
1065 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1066 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
1067 silc_server_packet_send(server, server->router->connection, packet->type,
1068 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1069 buffer->data, buffer->len, FALSE);
1072 /* Get channel entry */
1073 channel = silc_idlist_find_channel_by_id(server->local_list,
1076 channel = silc_idlist_find_channel_by_id(server->global_list,
1082 /* Get client entry */
1083 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1085 client = silc_idlist_find_client_by_id(server->global_list,
1091 /* Remove user from channel */
1092 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
1100 silc_free(client_id);
1102 silc_free(channel_id);
1105 /* Received New Channel User List packet, list of New Channel User payloads
1106 inside one packet. Process the payloads one by one. */
1108 void silc_server_new_channel_user_list(SilcServer server,
1109 SilcSocketConnection sock,
1110 SilcPacketContext *packet)
1112 SilcPacketContext *new;
1114 unsigned short len1, len2;
1116 SILC_LOG_DEBUG(("Processing New Channel User List"));
1118 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1119 packet->src_id_type != SILC_ID_SERVER ||
1120 server->server_type == SILC_SERVER)
1123 /* Make copy of the original packet context, except for the actual
1124 data buffer, which we will here now fetch from the original buffer. */
1125 new = silc_packet_context_alloc();
1126 new->type = SILC_PACKET_NEW_CHANNEL_USER;
1127 new->flags = packet->flags;
1128 new->src_id = packet->src_id;
1129 new->src_id_len = packet->src_id_len;
1130 new->src_id_type = packet->src_id_type;
1131 new->dst_id = packet->dst_id;
1132 new->dst_id_len = packet->dst_id_len;
1133 new->dst_id_type = packet->dst_id_type;
1135 buffer = silc_buffer_alloc(256);
1136 new->buffer = buffer;
1138 while (packet->buffer->len) {
1139 SILC_GET16_MSB(len1, packet->buffer->data);
1140 if ((len1 > packet->buffer->len) ||
1141 (len1 > buffer->truelen))
1144 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1145 if ((len2 > packet->buffer->len) ||
1146 (len2 > buffer->truelen))
1149 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1150 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1152 /* Process the New Channel User */
1153 silc_server_new_channel_user(server, sock, new);
1155 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1156 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1159 silc_buffer_free(buffer);
1163 /* Received notify packet. Server can receive notify packets from router.
1164 Server then relays the notify messages to clients if needed. */
1166 void silc_server_notify(SilcServer server,
1167 SilcSocketConnection sock,
1168 SilcPacketContext *packet)
1170 SilcNotifyPayload payload;
1171 SilcNotifyType type;
1172 SilcArgumentPayload args;
1173 SilcChannelID *channel_id;
1174 SilcClientID *client_id, *client_id2;
1175 SilcChannelEntry channel;
1176 SilcClientEntry client;
1178 unsigned int tmp_len;
1180 SILC_LOG_DEBUG(("Start"));
1182 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1183 packet->src_id_type != SILC_ID_SERVER)
1186 /* XXX: For now we expect that the we are normal server and that the
1187 sender is router. Server could send (protocol allows it) notify to
1188 router but we don't support it yet. */
1189 if (server->server_type != SILC_SERVER &&
1190 sock->type != SILC_SOCKET_TYPE_ROUTER)
1193 payload = silc_notify_payload_parse(packet->buffer);
1197 type = silc_notify_get_type(payload);
1198 args = silc_notify_get_args(payload);
1203 case SILC_NOTIFY_TYPE_JOIN:
1205 * Distribute the notify to local clients on the channel
1207 SILC_LOG_DEBUG(("JOIN notify"));
1209 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1210 packet->dst_id_type);
1214 /* Get channel entry */
1215 channel = silc_idlist_find_channel_by_id(server->local_list,
1218 silc_free(channel_id);
1223 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1225 silc_free(channel_id);
1228 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1230 silc_free(channel_id);
1234 /* Send to channel */
1235 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
1236 FALSE, packet->buffer->data,
1237 packet->buffer->len, FALSE);
1239 /* If the the client is not in local list we check global list (ie. the
1240 channel will be global channel) and if it does not exist then create
1241 entry for the client. */
1242 client = silc_idlist_find_client_by_id(server->local_list,
1245 SilcChannelClientEntry chl;
1247 client = silc_idlist_find_client_by_id(server->global_list,
1250 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
1251 client_id, sock->user_data, NULL);
1253 silc_free(channel_id);
1254 silc_free(client_id);
1259 /* The channel is global now */
1260 channel->global_users = TRUE;
1262 /* Now actually JOIN the global client to the channel */
1263 chl = silc_calloc(1, sizeof(*chl));
1264 chl->client = client;
1265 chl->channel = channel;
1266 silc_list_add(channel->user_list, chl);
1267 silc_list_add(client->channels, chl);
1269 silc_free(client_id);
1273 case SILC_NOTIFY_TYPE_LEAVE:
1275 * Distribute the notify to local clients on the channel
1277 SILC_LOG_DEBUG(("LEAVE notify"));
1279 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1280 packet->dst_id_type);
1284 /* Get channel entry */
1285 channel = silc_idlist_find_channel_by_id(server->local_list,
1288 silc_free(channel_id);
1293 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1295 silc_free(channel_id);
1298 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1300 silc_free(channel_id);
1304 /* Send to channel */
1305 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
1306 FALSE, packet->buffer->data,
1307 packet->buffer->len, FALSE);
1309 /* Get client entry */
1310 client = silc_idlist_find_client_by_id(server->global_list,
1313 client = silc_idlist_find_client_by_id(server->local_list,
1316 silc_free(client_id);
1317 silc_free(channel_id);
1321 silc_free(client_id);
1323 /* Remove the user from channel */
1324 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1327 case SILC_NOTIFY_TYPE_SIGNOFF:
1329 * Distribute the notify to local clients on the channel
1331 SILC_LOG_DEBUG(("SIGNOFF notify"));
1334 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1337 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1341 /* Get client entry */
1342 client = silc_idlist_find_client_by_id(server->global_list,
1345 client = silc_idlist_find_client_by_id(server->local_list,
1348 silc_free(client_id);
1352 silc_free(client_id);
1354 /* Remove the client from all channels */
1355 silc_server_remove_from_channels(server, NULL, client);
1357 /* Remove the client entry */
1358 silc_idlist_del_client(server->global_list, client);
1361 case SILC_NOTIFY_TYPE_NICK_CHANGE:
1364 * Distribute the notify to local clients on the channel
1366 unsigned char *id, *id2;
1368 SILC_LOG_DEBUG(("NICK CHANGE notify"));
1370 /* Get old client ID */
1371 id = silc_argument_get_arg_type(args, 1, &tmp_len);
1374 client_id = silc_id_payload_parse_id(id, tmp_len);
1378 /* Get new client ID */
1379 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
1382 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
1386 SILC_LOG_DEBUG(("Old Client ID id(%s)",
1387 silc_id_render(client_id, SILC_ID_CLIENT)));
1388 SILC_LOG_DEBUG(("New Client ID id(%s)",
1389 silc_id_render(client_id2, SILC_ID_CLIENT)));
1391 /* Replace the Client ID */
1392 client = silc_idlist_replace_client_id(server->global_list, client_id,
1395 client = silc_idlist_replace_client_id(server->local_list, client_id,
1399 /* Send the NICK_CHANGE notify type to local clients on the channels
1400 this client is joined to. */
1401 silc_server_send_notify_on_channels(server, client,
1402 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
1406 silc_free(client_id);
1408 silc_free(client_id2);
1411 case SILC_NOTIFY_TYPE_TOPIC_SET:
1413 * Distribute the notify to local clients on the channel
1415 SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
1418 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1420 * Distribute the notify to local clients on the channel
1422 SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
1425 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1427 * Distribute the notify to local clients on the channel
1429 SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
1432 /* Ignore rest notify types for now */
1433 case SILC_NOTIFY_TYPE_NONE:
1434 case SILC_NOTIFY_TYPE_INVITE:
1435 case SILC_NOTIFY_TYPE_MOTD:
1441 silc_notify_payload_free(payload);
1444 /* Received new channel user packet. Information about new users on a
1445 channel are distributed between routers using this packet. The
1446 router receiving this will redistribute it and also sent JOIN notify
1447 to local clients on the same channel. Normal server sends JOIN notify
1448 to its local clients on the channel. */
1450 void silc_server_new_channel_user(SilcServer server,
1451 SilcSocketConnection sock,
1452 SilcPacketContext *packet)
1454 unsigned char *tmpid1, *tmpid2;
1455 SilcClientID *client_id = NULL;
1456 SilcChannelID *channel_id = NULL;
1457 unsigned short channel_id_len;
1458 unsigned short client_id_len;
1459 SilcClientEntry client;
1460 SilcChannelEntry channel;
1461 SilcChannelClientEntry chl;
1465 SILC_LOG_DEBUG(("Start"));
1467 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1468 server->server_type != SILC_ROUTER ||
1469 packet->src_id_type != SILC_ID_SERVER)
1473 ret = silc_buffer_unformat(packet->buffer,
1474 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1476 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1487 /* Decode the channel ID */
1488 channel_id = silc_id_str2id(tmpid1, channel_id_len, SILC_ID_CHANNEL);
1492 /* Decode the client ID */
1493 client_id = silc_id_str2id(tmpid2, client_id_len, SILC_ID_CLIENT);
1497 /* Find the channel */
1498 channel = silc_idlist_find_channel_by_id(server->local_list,
1501 channel = silc_idlist_find_channel_by_id(server->global_list,
1507 /* If we are router and this packet is not already broadcast packet
1508 we will broadcast it. */
1509 if (!server->standalone && server->server_type == SILC_ROUTER &&
1510 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1511 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1512 silc_server_packet_send(server, server->router->connection, packet->type,
1513 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1514 packet->buffer->data, packet->buffer->len, FALSE);
1517 /* Get client entry */
1518 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1520 client = silc_idlist_find_client_by_id(server->global_list,
1526 /* Join the client to the channel by adding it to channel's user list.
1527 Add also the channel to client entry's channels list for fast cross-
1529 chl = silc_calloc(1, sizeof(*chl));
1530 chl->client = client;
1531 chl->channel = channel;
1532 silc_list_add(channel->user_list, chl);
1533 silc_list_add(client->channels, chl);
1535 server->stat.chanclients++;
1537 /* Send JOIN notify to local clients on the channel. As we are router
1538 it is assured that this is sent only to our local clients and locally
1539 connected servers if needed. */
1540 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1541 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1542 SILC_NOTIFY_TYPE_JOIN,
1543 1, clidp->data, clidp->len);
1544 silc_buffer_free(clidp);
1550 silc_free(client_id);
1552 silc_free(channel_id);
1557 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1558 that certain ID should be removed. After that the ID will become invalid. */
1560 void silc_server_remove_id(SilcServer server,
1561 SilcSocketConnection sock,
1562 SilcPacketContext *packet)
1567 void *id, *id_entry;
1569 SILC_LOG_DEBUG(("Start"));
1571 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1572 server->server_type == SILC_SERVER ||
1573 packet->src_id_type != SILC_ID_SERVER)
1576 idp = silc_id_payload_parse(packet->buffer);
1580 id_type = silc_id_payload_get_type(idp);
1582 id = silc_id_payload_get_id(idp);
1586 /* If the sender of this packet is server and we are router we need to
1587 broadcast this packet to other routers in the network. */
1588 if (!server->standalone && server->server_type == SILC_ROUTER &&
1589 sock->type == SILC_SOCKET_TYPE_SERVER &&
1590 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1591 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1592 silc_server_packet_send(server, server->router->connection,
1594 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1595 packet->buffer->data, packet->buffer->len, FALSE);
1598 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1599 id_list = server->local_list;
1601 id_list = server->global_list;
1605 case SILC_ID_CLIENT:
1606 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1609 /* Remove from channels */
1610 silc_server_remove_from_channels(server, NULL, id_entry);
1612 /* Remove the client entry */
1613 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1614 server->stat.clients--;
1615 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1616 server->server_type == SILC_ROUTER)
1617 server->stat.cell_clients--;
1619 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1620 silc_id_render(id, SILC_ID_CLIENT),
1621 sock->type == SILC_SOCKET_TYPE_SERVER ?
1622 "Server" : "Router", sock->hostname));
1626 case SILC_ID_SERVER:
1627 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1630 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1631 server->stat.servers--;
1632 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1633 server->server_type == SILC_ROUTER)
1634 server->stat.cell_servers--;
1636 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1637 silc_id_render(id, SILC_ID_SERVER),
1638 sock->type == SILC_SOCKET_TYPE_SERVER ?
1639 "Server" : "Router", sock->hostname));
1643 case SILC_ID_CHANNEL:
1644 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1647 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1648 server->stat.channels--;
1649 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1650 server->server_type == SILC_ROUTER)
1651 server->stat.cell_channels--;
1653 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1654 silc_id_render(id, SILC_ID_CHANNEL),
1655 sock->type == SILC_SOCKET_TYPE_SERVER ?
1656 "Server" : "Router", sock->hostname));
1665 silc_id_payload_free(idp);
1668 /* Processes received SET_MODE packet. The packet is used to distribute
1669 the information about changed channel's or client's channel modes. */
1671 void silc_server_set_mode(SilcServer server,
1672 SilcSocketConnection sock,
1673 SilcPacketContext *packet)
1675 SilcSetModePayload payload = NULL;
1676 SilcArgumentPayload args = NULL;
1677 unsigned short mode_type;
1678 unsigned int mode_mask;
1679 unsigned char *tmp, *tmp2;
1680 unsigned int tmp_len, tmp_len2;
1681 unsigned char mode[4];
1682 SilcClientID *client_id;
1683 SilcChannelID *channel_id = NULL;
1684 SilcClientEntry client;
1685 SilcChannelEntry channel;
1686 SilcChannelClientEntry chl;
1688 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1689 packet->src_id_type == SILC_ID_CLIENT)
1692 SILC_LOG_DEBUG(("Start"));
1694 /* If we are router and this packet is not already broadcast packet
1695 we will broadcast it. The sending socket really cannot be router or
1696 the router is buggy. If this packet is coming from router then it must
1697 have the broadcast flag set already and we won't do anything. */
1698 if (!server->standalone && server->server_type == SILC_ROUTER &&
1699 sock->type == SILC_SOCKET_TYPE_SERVER &&
1700 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1701 SILC_LOG_DEBUG(("Broadcasting received Set Mode packet"));
1702 silc_server_packet_send(server, server->router->connection, packet->type,
1703 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1704 packet->buffer->data, packet->buffer->len, FALSE);
1707 /* Parse Set Mode payload */
1708 payload = silc_set_mode_payload_parse(packet->buffer);
1712 mode_type = silc_set_mode_get_type(payload);
1713 args = silc_set_mode_get_args(payload);
1717 mode_mask = silc_set_mode_get_mode(payload);
1718 SILC_PUT32_MSB(mode_mask, mode);
1720 switch (mode_type) {
1721 case SILC_MODE_TYPE_CHANNEL:
1722 /* Get Channel ID */
1723 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1726 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1730 /* Get channel entry */
1731 channel = silc_idlist_find_channel_by_id(server->local_list,
1734 channel = silc_idlist_find_channel_by_id(server->global_list,
1740 /* Get Client ID payload */
1741 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1745 /* Send CMODE_CHANGE notify to local channel */
1746 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1747 SILC_NOTIFY_TYPE_CMODE_CHANGE,
1749 mode, sizeof(mode));
1751 /* Change the mode */
1752 channel->mode = mode_mask;
1755 case SILC_MODE_TYPE_UCHANNEL:
1756 /* Get Channel ID */
1757 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1760 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1764 /* Get channel entry */
1765 channel = silc_idlist_find_channel_by_id(server->local_list,
1768 channel = silc_idlist_find_channel_by_id(server->global_list,
1774 /* Get Client ID payload */
1775 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1779 /* Get target Client ID */
1780 tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2);
1783 client_id = silc_id_payload_parse_id(tmp2, tmp_len2);
1787 /* Get target client entry */
1788 client = silc_idlist_find_client_by_id(server->global_list,
1791 client = silc_idlist_find_client_by_id(server->local_list,
1794 silc_free(client_id);
1798 silc_free(client_id);
1800 /* Send CUMODE_CHANGE notify to local channel */
1801 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1802 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2,
1807 /* Get entry to the channel user list */
1808 silc_list_start(channel->user_list);
1809 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
1810 if (chl->client == client) {
1811 /* Change the mode */
1812 chl->mode = mode_mask;
1824 silc_free(channel_id);
1826 silc_argument_payload_free(args);
1828 silc_set_mode_payload_free(payload);