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),
469 silc_server_disconnect_remote(server, sock, "Server closed connection: "
470 "Incomplete client information");
474 /* Create Client ID */
475 silc_id_create_client_id(server->id, server->rng, server->md5hash,
476 username, &client_id);
478 /* Update client entry */
479 idata->registered = TRUE;
480 client->nickname = strdup(username);
481 client->username = username;
482 client->userinfo = realname ? realname : strdup("");
483 client->id = client_id;
485 /* Update the cache entry */
486 cache->id = (void *)client_id;
487 cache->type = SILC_ID_CLIENT;
488 cache->data = username;
489 silc_idcache_sort_by_data(server->local_list->clients);
491 /* Notify our router about new client on the SILC network */
492 if (!server->standalone)
493 silc_server_send_new_id(server, (SilcSocketConnection)
494 server->router->connection,
495 server->server_type == SILC_ROUTER ? TRUE : FALSE,
496 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
498 /* Send the new client ID to the client. */
499 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
500 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
501 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
502 silc_buffer_format(reply,
503 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
504 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
505 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
507 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
508 reply->data, reply->len, FALSE);
509 silc_free(id_string);
510 silc_buffer_free(reply);
512 /* Send some nice info to the client */
513 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
514 ("Welcome to the SILC Network %s@%s",
515 username, sock->hostname));
516 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
517 ("Your host is %s, running version %s",
518 server->config->server_info->server_name,
520 if (server->server_type == SILC_ROUTER) {
521 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
522 ("There are %d clients on %d servers in SILC "
523 "Network", server->stat.clients,
524 server->stat.servers + 1));
525 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
526 ("There are %d clients on %d server in our cell",
527 server->stat.cell_clients,
528 server->stat.cell_servers + 1));
529 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
530 ("I have %d clients, %d channels, %d servers and "
532 server->stat.my_clients,
533 server->stat.my_channels,
534 server->stat.my_servers,
535 server->stat.my_routers));
536 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
537 ("%d server operators and %d router operators "
539 server->stat.my_server_ops,
540 server->stat.my_router_ops));
542 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
543 ("I have %d clients and %d channels formed",
544 server->stat.my_clients,
545 server->stat.my_channels));
546 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
547 ("%d operators online",
548 server->stat.my_server_ops));
550 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
551 ("Your connection is secured with %s cipher, "
552 "key length %d bits",
553 idata->send_key->cipher->name,
554 idata->send_key->cipher->key_len));
555 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
556 ("Your current nickname is %s",
560 silc_server_send_motd(server, sock);
565 /* Create new server. This processes received New Server packet and
566 saves the received Server ID. The server is our locally connected
567 server thus we save all the information and save it to local list.
568 This funtion can be used by both normal server and router server.
569 If normal server uses this it means that its router has connected
570 to the server. If router uses this it means that one of the cell's
571 servers is connected to the router. */
573 SilcServerEntry silc_server_new_server(SilcServer server,
574 SilcSocketConnection sock,
575 SilcPacketContext *packet)
577 SilcBuffer buffer = packet->buffer;
578 SilcServerEntry new_server;
579 SilcIDCacheEntry cache;
580 SilcServerID *server_id;
581 SilcIDListData idata;
582 unsigned char *server_name, *id_string;
583 unsigned short id_len;
586 SILC_LOG_DEBUG(("Creating new server"));
588 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
589 sock->type != SILC_SOCKET_TYPE_ROUTER)
592 /* Take server entry */
593 new_server = (SilcServerEntry)sock->user_data;
594 idata = (SilcIDListData)new_server;
596 /* Fetch the old server cache entry so that we can update it. */
597 if (!silc_idcache_find_by_context(server->local_list->servers,
598 sock->user_data, &cache)) {
599 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
603 /* Parse the incoming packet */
604 ret = silc_buffer_unformat(buffer,
605 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
606 SILC_STR_UI16_STRING_ALLOC(&server_name),
610 silc_free(id_string);
612 silc_free(server_name);
616 if (id_len > buffer->len) {
617 silc_free(id_string);
618 silc_free(server_name);
623 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
625 silc_free(id_string);
626 silc_free(server_name);
629 silc_free(id_string);
631 /* Update client entry */
632 idata->registered = TRUE;
633 new_server->server_name = server_name;
634 new_server->id = server_id;
636 /* Update the cache entry */
637 cache->id = (void *)server_id;
638 cache->type = SILC_ID_SERVER;
639 cache->data = server_name;
640 silc_idcache_sort_by_data(server->local_list->servers);
642 /* Distribute the information about new server in the SILC network
643 to our router. If we are normal server we won't send anything
644 since this connection must be our router connection. */
645 if (server->server_type == SILC_ROUTER && !server->standalone &&
646 server->router->connection != sock)
647 silc_server_send_new_id(server, server->router->connection,
648 TRUE, new_server->id, SILC_ID_SERVER,
651 if (server->server_type == SILC_ROUTER)
652 server->stat.cell_servers++;
657 /* Processes incoming New ID packet. New ID Payload is used to distribute
658 information about newly registered clients and servers. */
660 static void silc_server_new_id_real(SilcServer server,
661 SilcSocketConnection sock,
662 SilcPacketContext *packet,
665 SilcBuffer buffer = packet->buffer;
667 SilcServerEntry router;
668 SilcSocketConnection router_sock;
671 unsigned char *hash = NULL;
674 SILC_LOG_DEBUG(("Processing new ID"));
676 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
677 server->server_type == SILC_SERVER ||
678 packet->src_id_type != SILC_ID_SERVER)
681 idp = silc_id_payload_parse(buffer);
685 id_type = silc_id_payload_get_type(idp);
687 /* Normal server cannot have other normal server connections */
688 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
691 id = silc_id_payload_get_id(idp);
695 /* If the sender of this packet is server and we are router we need to
696 broadcast this packet to other routers in the network. */
697 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
698 sock->type == SILC_SOCKET_TYPE_SERVER &&
699 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
700 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
701 silc_server_packet_send(server, server->router->connection,
703 packet->flags | SILC_PACKET_FLAG_BROADCAST,
704 buffer->data, buffer->len, FALSE);
707 if (sock->type == SILC_SOCKET_TYPE_SERVER)
708 id_list = server->local_list;
710 id_list = server->global_list;
713 router = sock->user_data;
718 SilcClientEntry entry;
720 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
721 silc_id_render(id, SILC_ID_CLIENT),
722 sock->type == SILC_SOCKET_TYPE_SERVER ?
723 "Server" : "Router", sock->hostname));
725 /* As a router we keep information of all global information in our
726 global list. Cell wide information however is kept in the local
727 list. The client is put to global list and we will take the hash
728 value of the Client ID and save it to the ID Cache system for fast
729 searching in the future. */
730 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
731 sizeof(unsigned char));
732 memcpy(hash, ((SilcClientID *)id)->hash,
733 sizeof(((SilcClientID *)id)->hash));
734 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
736 entry->nickname = NULL;
738 if (sock->type == SILC_SOCKET_TYPE_SERVER)
739 server->stat.cell_clients++;
740 server->stat.clients++;
743 /* XXX Adding two ID's with same IP number replaces the old entry thus
744 gives wrong route. Thus, now disabled until figured out a better way
745 to do this or when removed the whole thing. This could be removed
746 because entry->router->connection gives always the most optimal route
747 for the ID anyway (unless new routes (faster perhaps) are established
748 after receiving this ID, this we don't know however). */
749 /* Add route cache for this ID */
750 silc_server_route_add(silc_server_route_hash(
751 ((SilcClientID *)id)->ip.s_addr,
752 server->id->port), ((SilcClientID *)id)->ip.s_addr,
759 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
760 silc_id_render(id, SILC_ID_SERVER),
761 sock->type == SILC_SOCKET_TYPE_SERVER ?
762 "Server" : "Router", sock->hostname));
764 /* As a router we keep information of all global information in our global
765 list. Cell wide information however is kept in the local list. */
766 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
768 if (sock->type == SILC_SOCKET_TYPE_SERVER)
769 server->stat.cell_servers++;
770 server->stat.servers++;
773 /* Add route cache for this ID */
774 silc_server_route_add(silc_server_route_hash(
775 ((SilcServerID *)id)->ip.s_addr,
776 ((SilcServerID *)id)->port),
777 ((SilcServerID *)id)->ip.s_addr,
782 case SILC_ID_CHANNEL:
783 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
791 silc_id_payload_free(idp);
795 /* Processes incoming New ID packet. New ID Payload is used to distribute
796 information about newly registered clients and servers. */
798 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
799 SilcPacketContext *packet)
801 silc_server_new_id_real(server, sock, packet, TRUE);
804 /* Receoved New Id List packet, list of New ID payloads inside one
805 packet. Process the New ID payloads one by one. */
807 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
808 SilcPacketContext *packet)
810 SilcPacketContext *new_id;
812 unsigned short id_len;
814 SILC_LOG_DEBUG(("Processing New ID List"));
816 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
817 packet->src_id_type != SILC_ID_SERVER)
820 /* If the sender of this packet is server and we are router we need to
821 broadcast this packet to other routers in the network. Broadcast
822 this list packet instead of multiple New ID packets. */
823 if (!server->standalone && server->server_type == SILC_ROUTER &&
824 sock->type == SILC_SOCKET_TYPE_SERVER &&
825 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
826 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
827 silc_server_packet_send(server, server->router->connection,
829 packet->flags | SILC_PACKET_FLAG_BROADCAST,
830 packet->buffer->data, packet->buffer->len, FALSE);
833 /* Make copy of the original packet context, except for the actual
834 data buffer, which we will here now fetch from the original buffer. */
835 new_id = silc_packet_context_alloc();
836 new_id->type = SILC_PACKET_NEW_ID;
837 new_id->flags = packet->flags;
838 new_id->src_id = packet->src_id;
839 new_id->src_id_len = packet->src_id_len;
840 new_id->src_id_type = packet->src_id_type;
841 new_id->dst_id = packet->dst_id;
842 new_id->dst_id_len = packet->dst_id_len;
843 new_id->dst_id_type = packet->dst_id_type;
845 idp = silc_buffer_alloc(256);
846 new_id->buffer = idp;
848 while (packet->buffer->len) {
849 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
850 if ((id_len > packet->buffer->len) ||
851 (id_len > idp->truelen))
854 silc_buffer_pull_tail(idp, 4 + id_len);
855 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
857 /* Process the New ID */
858 silc_server_new_id_real(server, sock, new_id, FALSE);
860 silc_buffer_push_tail(idp, 4 + id_len);
861 silc_buffer_pull(packet->buffer, 4 + id_len);
864 silc_buffer_free(idp);
868 /* Received New Channel packet. Information about new channels in the
869 network are distributed using this packet. Save the information about
870 the new channel. This usually comes from router but also normal server
871 can send this to notify channels it has when it connects to us. */
873 void silc_server_new_channel(SilcServer server,
874 SilcSocketConnection sock,
875 SilcPacketContext *packet)
878 SilcChannelID *channel_id;
879 unsigned short channel_id_len;
883 SILC_LOG_DEBUG(("Processing New Channel"));
885 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
886 packet->src_id_type != SILC_ID_SERVER ||
887 server->server_type == SILC_SERVER)
891 ret = silc_buffer_unformat(packet->buffer,
892 SILC_STR_UI16_STRING_ALLOC(&channel_name),
893 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
897 silc_free(channel_name);
903 /* Decode the channel ID */
904 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
908 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
909 /* Add the server to global list as it is coming from router. It
910 cannot be our own channel as it is coming from router. */
912 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
913 silc_id_render(channel_id, SILC_ID_CHANNEL),
916 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
917 server->router->connection, NULL);
919 server->stat.channels++;
921 /* The channel is coming from our server, thus it is in our cell
922 we will add it to our local list. */
923 SilcChannelEntry channel;
926 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
927 silc_id_render(channel_id, SILC_ID_CHANNEL),
930 /* Check that we don't already have this channel */
931 channel = silc_idlist_find_channel_by_name(server->local_list,
934 channel = silc_idlist_find_channel_by_name(server->global_list,
937 /* If the channel does not exist, then create it. We create the channel
938 with the channel ID provided by the server. This creates a new
939 key to the channel as well that we will send to the server. */
941 channel = silc_server_create_new_channel_with_id(server, NULL,
947 /* Send the new channel key to the server */
948 chk = silc_channel_key_payload_encode(channel_id_len, id,
949 strlen(channel->channel_key->
951 channel->channel_key->cipher->name,
952 channel->key_len / 8,
954 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
955 chk->data, chk->len, FALSE);
956 silc_buffer_free(chk);
959 /* The channel exist by that name, check whether the ID's match.
960 If they don't then we'll force the server to use the ID we have.
961 We also create a new key for the channel. */
963 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
964 /* They don't match, send Replace ID packet to the server to
965 force the ID change. */
966 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
967 silc_server_send_replace_id(server, sock, FALSE,
968 channel_id, SILC_ID_CHANNEL,
970 channel->id, SILC_ID_CHANNEL,
971 SILC_ID_CHANNEL_LEN);
974 /* Create new key for the channel and send it to the server and
975 everybody else possibly on the channel. */
977 silc_server_create_channel_key(server, channel, 0);
979 /* Send to the channel */
980 silc_server_send_channel_key(server, sock, channel, FALSE);
982 /* Send to the server */
983 chk = silc_channel_key_payload_encode(channel_id_len, id,
984 strlen(channel->channel_key->
986 channel->channel_key->cipher->name,
987 channel->key_len / 8,
989 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
990 chk->data, chk->len, FALSE);
991 silc_buffer_free(chk);
993 /* Since the channel is coming from server and we also know about it
994 then send the JOIN notify to the server so that it see's our
995 users on the channel "joining" the channel. */
1003 /* Received New Channel List packet, list of New Channel List payloads inside
1004 one packet. Process the New Channel payloads one by one. */
1006 void silc_server_new_channel_list(SilcServer server,
1007 SilcSocketConnection sock,
1008 SilcPacketContext *packet)
1010 SilcPacketContext *new;
1012 unsigned short len1, len2;
1014 SILC_LOG_DEBUG(("Processing New Channel List"));
1016 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1017 packet->src_id_type != SILC_ID_SERVER ||
1018 server->server_type == SILC_SERVER)
1021 /* If the sender of this packet is server and we are router we need to
1022 broadcast this packet to other routers in the network. Broadcast
1023 this list packet instead of multiple New Channel packets. */
1024 if (!server->standalone && server->server_type == SILC_ROUTER &&
1025 sock->type == SILC_SOCKET_TYPE_SERVER &&
1026 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1027 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1028 silc_server_packet_send(server, server->router->connection,
1030 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1031 packet->buffer->data, packet->buffer->len, FALSE);
1034 /* Make copy of the original packet context, except for the actual
1035 data buffer, which we will here now fetch from the original buffer. */
1036 new = silc_packet_context_alloc();
1037 new->type = SILC_PACKET_NEW_CHANNEL;
1038 new->flags = packet->flags;
1039 new->src_id = packet->src_id;
1040 new->src_id_len = packet->src_id_len;
1041 new->src_id_type = packet->src_id_type;
1042 new->dst_id = packet->dst_id;
1043 new->dst_id_len = packet->dst_id_len;
1044 new->dst_id_type = packet->dst_id_type;
1046 buffer = silc_buffer_alloc(512);
1047 new->buffer = buffer;
1049 while (packet->buffer->len) {
1050 SILC_GET16_MSB(len1, packet->buffer->data);
1051 if ((len1 > packet->buffer->len) ||
1052 (len1 > buffer->truelen))
1055 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1056 if ((len2 > packet->buffer->len) ||
1057 (len2 > buffer->truelen))
1060 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1061 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1063 /* Process the New Channel */
1064 silc_server_new_channel(server, sock, new);
1066 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1067 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1070 silc_buffer_free(buffer);
1074 /* Received new channel user packet. Information about new users on a
1075 channel are distributed between routers using this packet. The
1076 router receiving this will redistribute it and also sent JOIN notify
1077 to local clients on the same channel. Normal server sends JOIN notify
1078 to its local clients on the channel. */
1080 static void silc_server_new_channel_user_real(SilcServer server,
1081 SilcSocketConnection sock,
1082 SilcPacketContext *packet,
1085 unsigned char *tmpid1, *tmpid2;
1086 SilcClientID *client_id = NULL;
1087 SilcChannelID *channel_id = NULL;
1088 unsigned short channel_id_len;
1089 unsigned short client_id_len;
1090 SilcClientEntry client;
1091 SilcChannelEntry channel;
1092 SilcChannelClientEntry chl;
1096 SILC_LOG_DEBUG(("Start"));
1098 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1099 server->server_type != SILC_ROUTER ||
1100 packet->src_id_type != SILC_ID_SERVER)
1104 ret = silc_buffer_unformat(packet->buffer,
1105 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1107 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1118 /* Decode the channel ID */
1119 channel_id = silc_id_str2id(tmpid1, channel_id_len, SILC_ID_CHANNEL);
1123 /* Decode the client ID */
1124 client_id = silc_id_str2id(tmpid2, client_id_len, SILC_ID_CLIENT);
1128 /* If we are router and this packet is not already broadcast packet
1129 we will broadcast it. */
1130 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1131 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1132 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1133 silc_server_packet_send(server, server->router->connection, packet->type,
1134 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1135 packet->buffer->data, packet->buffer->len, FALSE);
1138 /* Find the channel */
1139 channel = silc_idlist_find_channel_by_id(server->local_list,
1142 channel = silc_idlist_find_channel_by_id(server->global_list,
1148 /* Get client entry */
1149 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1151 client = silc_idlist_find_client_by_id(server->global_list,
1157 /* Join the client to the channel by adding it to channel's user list.
1158 Add also the channel to client entry's channels list for fast cross-
1160 chl = silc_calloc(1, sizeof(*chl));
1161 chl->client = client;
1162 chl->channel = channel;
1163 silc_list_add(channel->user_list, chl);
1164 silc_list_add(client->channels, chl);
1166 server->stat.chanclients++;
1168 /* Send JOIN notify to local clients on the channel. As we are router
1169 it is assured that this is sent only to our local clients and locally
1170 connected servers if needed. */
1171 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1172 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1173 SILC_NOTIFY_TYPE_JOIN,
1174 1, clidp->data, clidp->len);
1175 silc_buffer_free(clidp);
1181 silc_free(client_id);
1183 silc_free(channel_id);
1188 /* Received new channel user packet. Information about new users on a
1189 channel are distributed between routers using this packet. The
1190 router receiving this will redistribute it and also sent JOIN notify
1191 to local clients on the same channel. Normal server sends JOIN notify
1192 to its local clients on the channel. */
1194 void silc_server_new_channel_user(SilcServer server,
1195 SilcSocketConnection sock,
1196 SilcPacketContext *packet)
1198 silc_server_new_channel_user_real(server, sock, packet, TRUE);
1201 /* Received New Channel User List packet, list of New Channel User payloads
1202 inside one packet. Process the payloads one by one. */
1204 void silc_server_new_channel_user_list(SilcServer server,
1205 SilcSocketConnection sock,
1206 SilcPacketContext *packet)
1208 SilcPacketContext *new;
1210 unsigned short len1, len2;
1212 SILC_LOG_DEBUG(("Processing New Channel User List"));
1214 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1215 packet->src_id_type != SILC_ID_SERVER ||
1216 server->server_type == SILC_SERVER)
1219 /* If we are router and this packet is not already broadcast packet
1220 we will broadcast it. Brodcast this list packet instead of multiple
1221 New Channel User packets. */
1222 if (!server->standalone && server->server_type == SILC_ROUTER &&
1223 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1224 SILC_LOG_DEBUG(("Broadcasting received New Channel User List packet"));
1225 silc_server_packet_send(server, server->router->connection, packet->type,
1226 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1227 packet->buffer->data, packet->buffer->len, FALSE);
1230 /* Make copy of the original packet context, except for the actual
1231 data buffer, which we will here now fetch from the original buffer. */
1232 new = silc_packet_context_alloc();
1233 new->type = SILC_PACKET_NEW_CHANNEL_USER;
1234 new->flags = packet->flags;
1235 new->src_id = packet->src_id;
1236 new->src_id_len = packet->src_id_len;
1237 new->src_id_type = packet->src_id_type;
1238 new->dst_id = packet->dst_id;
1239 new->dst_id_len = packet->dst_id_len;
1240 new->dst_id_type = packet->dst_id_type;
1242 buffer = silc_buffer_alloc(256);
1243 new->buffer = buffer;
1245 while (packet->buffer->len) {
1246 SILC_GET16_MSB(len1, packet->buffer->data);
1247 if ((len1 > packet->buffer->len) ||
1248 (len1 > buffer->truelen))
1251 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1252 if ((len2 > packet->buffer->len) ||
1253 (len2 > buffer->truelen))
1256 silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1257 silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1259 /* Process the New Channel User */
1260 silc_server_new_channel_user_real(server, sock, new, FALSE);
1262 silc_buffer_push_tail(buffer, 4 + len1 + len2);
1263 silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1266 silc_buffer_free(buffer);
1270 /* Received Remove Channel User packet to remove a user from a channel.
1271 Routers notify other routers that user has left a channel. Client must
1272 not send this packet. Normal server may send this packet but must not
1275 void silc_server_remove_channel_user(SilcServer server,
1276 SilcSocketConnection sock,
1277 SilcPacketContext *packet)
1279 SilcBuffer buffer = packet->buffer;
1280 unsigned char *tmp1 = NULL, *tmp2 = NULL;
1281 unsigned short tmp1_len, tmp2_len;
1282 SilcClientID *client_id = NULL;
1283 SilcChannelID *channel_id = NULL;
1284 SilcChannelEntry channel;
1285 SilcClientEntry client;
1288 SILC_LOG_DEBUG(("Removing user from channel"));
1290 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1291 packet->src_id_type != SILC_ID_SERVER ||
1292 server->server_type == SILC_SERVER)
1295 ret = silc_buffer_unformat(buffer,
1296 SILC_STR_UI16_NSTRING_ALLOC(&tmp1, &tmp1_len),
1297 SILC_STR_UI16_NSTRING_ALLOC(&tmp2, &tmp2_len),
1302 client_id = silc_id_str2id(tmp1, tmp1_len, SILC_ID_CLIENT);
1303 channel_id = silc_id_str2id(tmp2, tmp2_len, SILC_ID_CHANNEL);
1304 if (!client_id || !channel_id)
1307 /* If we are router and this packet is not already broadcast packet
1308 we will broadcast it. The sending socket really cannot be router or
1309 the router is buggy. If this packet is coming from router then it must
1310 have the broadcast flag set already and we won't do anything. */
1311 if (!server->standalone && server->server_type == SILC_ROUTER &&
1312 sock->type == SILC_SOCKET_TYPE_SERVER &&
1313 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1314 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
1315 silc_server_packet_send(server, server->router->connection, packet->type,
1316 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1317 buffer->data, buffer->len, FALSE);
1320 /* Get channel entry */
1321 channel = silc_idlist_find_channel_by_id(server->local_list,
1324 channel = silc_idlist_find_channel_by_id(server->global_list,
1330 /* Get client entry */
1331 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1333 client = silc_idlist_find_client_by_id(server->global_list,
1339 /* Remove user from channel */
1340 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
1348 silc_free(client_id);
1350 silc_free(channel_id);
1353 /* Received notify packet. Server can receive notify packets from router.
1354 Server then relays the notify messages to clients if needed. */
1356 void silc_server_notify(SilcServer server,
1357 SilcSocketConnection sock,
1358 SilcPacketContext *packet)
1360 SilcNotifyPayload payload;
1361 SilcNotifyType type;
1362 SilcArgumentPayload args;
1363 SilcChannelID *channel_id;
1364 SilcClientID *client_id, *client_id2;
1365 SilcChannelEntry channel;
1366 SilcClientEntry client;
1368 unsigned int tmp_len;
1370 SILC_LOG_DEBUG(("Start"));
1372 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1373 packet->src_id_type != SILC_ID_SERVER)
1376 /* XXX: For now we expect that the we are normal server and that the
1377 sender is router. Server could send (protocol allows it) notify to
1378 router but we don't support it yet. */
1379 if (server->server_type != SILC_SERVER &&
1380 sock->type != SILC_SOCKET_TYPE_ROUTER)
1383 payload = silc_notify_payload_parse(packet->buffer);
1387 type = silc_notify_get_type(payload);
1388 args = silc_notify_get_args(payload);
1393 case SILC_NOTIFY_TYPE_JOIN:
1395 * Distribute the notify to local clients on the channel
1397 SILC_LOG_DEBUG(("JOIN notify"));
1399 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1400 packet->dst_id_type);
1404 /* Get channel entry */
1405 channel = silc_idlist_find_channel_by_id(server->local_list,
1408 silc_free(channel_id);
1413 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1415 silc_free(channel_id);
1418 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1420 silc_free(channel_id);
1424 /* Send to channel */
1425 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
1426 FALSE, packet->buffer->data,
1427 packet->buffer->len, FALSE);
1429 /* If the the client is not in local list we check global list (ie. the
1430 channel will be global channel) and if it does not exist then create
1431 entry for the client. */
1432 client = silc_idlist_find_client_by_id(server->local_list,
1435 SilcChannelClientEntry chl;
1437 client = silc_idlist_find_client_by_id(server->global_list,
1440 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
1441 client_id, sock->user_data, NULL);
1443 silc_free(channel_id);
1444 silc_free(client_id);
1449 /* The channel is global now */
1450 channel->global_users = TRUE;
1452 /* Now actually JOIN the global client to the channel */
1453 chl = silc_calloc(1, sizeof(*chl));
1454 chl->client = client;
1455 chl->channel = channel;
1456 silc_list_add(channel->user_list, chl);
1457 silc_list_add(client->channels, chl);
1459 silc_free(client_id);
1463 case SILC_NOTIFY_TYPE_LEAVE:
1465 * Distribute the notify to local clients on the channel
1467 SILC_LOG_DEBUG(("LEAVE notify"));
1469 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1470 packet->dst_id_type);
1474 /* Get channel entry */
1475 channel = silc_idlist_find_channel_by_id(server->local_list,
1478 silc_free(channel_id);
1483 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1485 silc_free(channel_id);
1488 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1490 silc_free(channel_id);
1494 /* Send to channel */
1495 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
1496 FALSE, packet->buffer->data,
1497 packet->buffer->len, FALSE);
1499 /* Get client entry */
1500 client = silc_idlist_find_client_by_id(server->global_list,
1503 client = silc_idlist_find_client_by_id(server->local_list,
1506 silc_free(client_id);
1507 silc_free(channel_id);
1511 silc_free(client_id);
1513 /* Remove the user from channel */
1514 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1517 case SILC_NOTIFY_TYPE_SIGNOFF:
1519 * Distribute the notify to local clients on the channel
1521 SILC_LOG_DEBUG(("SIGNOFF notify"));
1524 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1527 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1531 /* Get client entry */
1532 client = silc_idlist_find_client_by_id(server->global_list,
1535 client = silc_idlist_find_client_by_id(server->local_list,
1538 silc_free(client_id);
1542 silc_free(client_id);
1544 /* Remove the client from all channels */
1545 silc_server_remove_from_channels(server, NULL, client);
1547 /* Remove the client entry */
1548 silc_idlist_del_client(server->global_list, client);
1551 case SILC_NOTIFY_TYPE_NICK_CHANGE:
1554 * Distribute the notify to local clients on the channel
1556 unsigned char *id, *id2;
1558 SILC_LOG_DEBUG(("NICK CHANGE notify"));
1560 /* Get old client ID */
1561 id = silc_argument_get_arg_type(args, 1, &tmp_len);
1564 client_id = silc_id_payload_parse_id(id, tmp_len);
1568 /* Get new client ID */
1569 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
1572 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
1576 SILC_LOG_DEBUG(("Old Client ID id(%s)",
1577 silc_id_render(client_id, SILC_ID_CLIENT)));
1578 SILC_LOG_DEBUG(("New Client ID id(%s)",
1579 silc_id_render(client_id2, SILC_ID_CLIENT)));
1581 /* Replace the Client ID */
1582 client = silc_idlist_replace_client_id(server->global_list, client_id,
1585 client = silc_idlist_replace_client_id(server->local_list, client_id,
1589 /* Send the NICK_CHANGE notify type to local clients on the channels
1590 this client is joined to. */
1591 silc_server_send_notify_on_channels(server, client,
1592 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
1596 silc_free(client_id);
1598 silc_free(client_id2);
1601 case SILC_NOTIFY_TYPE_TOPIC_SET:
1603 * Distribute the notify to local clients on the channel
1605 SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
1608 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1610 * Distribute the notify to local clients on the channel
1612 SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
1615 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1617 * Distribute the notify to local clients on the channel
1619 SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
1622 /* Ignore rest notify types for now */
1623 case SILC_NOTIFY_TYPE_NONE:
1624 case SILC_NOTIFY_TYPE_INVITE:
1625 case SILC_NOTIFY_TYPE_MOTD:
1631 silc_notify_payload_free(payload);
1634 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1635 that certain ID should be removed. After that the ID will become invalid. */
1637 void silc_server_remove_id(SilcServer server,
1638 SilcSocketConnection sock,
1639 SilcPacketContext *packet)
1644 void *id, *id_entry;
1646 SILC_LOG_DEBUG(("Start"));
1648 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1649 server->server_type == SILC_SERVER ||
1650 packet->src_id_type != SILC_ID_SERVER)
1653 idp = silc_id_payload_parse(packet->buffer);
1657 id_type = silc_id_payload_get_type(idp);
1659 id = silc_id_payload_get_id(idp);
1663 /* If the sender of this packet is server and we are router we need to
1664 broadcast this packet to other routers in the network. */
1665 if (!server->standalone && server->server_type == SILC_ROUTER &&
1666 sock->type == SILC_SOCKET_TYPE_SERVER &&
1667 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1668 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1669 silc_server_packet_send(server, server->router->connection,
1671 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1672 packet->buffer->data, packet->buffer->len, FALSE);
1675 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1676 id_list = server->local_list;
1678 id_list = server->global_list;
1682 case SILC_ID_CLIENT:
1683 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1686 /* Remove from channels */
1687 silc_server_remove_from_channels(server, NULL, id_entry);
1689 /* Remove the client entry */
1690 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1691 server->stat.clients--;
1692 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1693 server->server_type == SILC_ROUTER)
1694 server->stat.cell_clients--;
1696 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1697 silc_id_render(id, SILC_ID_CLIENT),
1698 sock->type == SILC_SOCKET_TYPE_SERVER ?
1699 "Server" : "Router", sock->hostname));
1703 case SILC_ID_SERVER:
1704 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1707 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1708 server->stat.servers--;
1709 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1710 server->server_type == SILC_ROUTER)
1711 server->stat.cell_servers--;
1713 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1714 silc_id_render(id, SILC_ID_SERVER),
1715 sock->type == SILC_SOCKET_TYPE_SERVER ?
1716 "Server" : "Router", sock->hostname));
1720 case SILC_ID_CHANNEL:
1721 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1724 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1725 server->stat.channels--;
1726 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1727 server->server_type == SILC_ROUTER)
1728 server->stat.cell_channels--;
1730 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1731 silc_id_render(id, SILC_ID_CHANNEL),
1732 sock->type == SILC_SOCKET_TYPE_SERVER ?
1733 "Server" : "Router", sock->hostname));
1742 silc_id_payload_free(idp);
1745 /* Processes received SET_MODE packet. The packet is used to distribute
1746 the information about changed channel's or client's channel modes. */
1748 void silc_server_set_mode(SilcServer server,
1749 SilcSocketConnection sock,
1750 SilcPacketContext *packet)
1752 SilcSetModePayload payload = NULL;
1753 SilcArgumentPayload args = NULL;
1754 unsigned short mode_type;
1755 unsigned int mode_mask;
1756 unsigned char *tmp, *tmp2;
1757 unsigned int tmp_len, tmp_len2;
1758 unsigned char mode[4];
1759 SilcClientID *client_id;
1760 SilcChannelID *channel_id = NULL;
1761 SilcClientEntry client;
1762 SilcChannelEntry channel;
1763 SilcChannelClientEntry chl;
1765 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1766 packet->src_id_type == SILC_ID_CLIENT)
1769 SILC_LOG_DEBUG(("Start"));
1771 /* If we are router and this packet is not already broadcast packet
1772 we will broadcast it. The sending socket really cannot be router or
1773 the router is buggy. If this packet is coming from router then it must
1774 have the broadcast flag set already and we won't do anything. */
1775 if (!server->standalone && server->server_type == SILC_ROUTER &&
1776 sock->type == SILC_SOCKET_TYPE_SERVER &&
1777 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1778 SILC_LOG_DEBUG(("Broadcasting received Set Mode packet"));
1779 silc_server_packet_send(server, server->router->connection, packet->type,
1780 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1781 packet->buffer->data, packet->buffer->len, FALSE);
1784 /* Parse Set Mode payload */
1785 payload = silc_set_mode_payload_parse(packet->buffer);
1789 mode_type = silc_set_mode_get_type(payload);
1790 args = silc_set_mode_get_args(payload);
1794 mode_mask = silc_set_mode_get_mode(payload);
1795 SILC_PUT32_MSB(mode_mask, mode);
1797 switch (mode_type) {
1798 case SILC_MODE_TYPE_CHANNEL:
1799 /* Get Channel ID */
1800 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1803 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1807 /* Get channel entry */
1808 channel = silc_idlist_find_channel_by_id(server->local_list,
1811 channel = silc_idlist_find_channel_by_id(server->global_list,
1817 /* Get Client ID payload */
1818 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1822 /* Send CMODE_CHANGE notify to local channel */
1823 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1824 SILC_NOTIFY_TYPE_CMODE_CHANGE,
1826 mode, sizeof(mode));
1828 /* Change the mode */
1829 channel->mode = mode_mask;
1832 case SILC_MODE_TYPE_UCHANNEL:
1833 /* Get Channel ID */
1834 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1837 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1841 /* Get channel entry */
1842 channel = silc_idlist_find_channel_by_id(server->local_list,
1845 channel = silc_idlist_find_channel_by_id(server->global_list,
1851 /* Get Client ID payload */
1852 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1856 /* Get target Client ID */
1857 tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2);
1860 client_id = silc_id_payload_parse_id(tmp2, tmp_len2);
1864 /* Get target client entry */
1865 client = silc_idlist_find_client_by_id(server->global_list,
1868 client = silc_idlist_find_client_by_id(server->local_list,
1871 silc_free(client_id);
1875 silc_free(client_id);
1877 /* Send CUMODE_CHANGE notify to local channel */
1878 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1879 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2,
1884 /* Get entry to the channel user list */
1885 silc_list_start(channel->user_list);
1886 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
1887 if (chl->client == client) {
1888 /* Change the mode */
1889 chl->mode = mode_mask;
1901 silc_free(channel_id);
1903 silc_argument_payload_free(args);
1905 silc_set_mode_payload_free(payload);