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)dst_sock->user_data;
72 idata = (SilcIDListData)router;
74 silc_server_send_private_message(server, dst_sock,
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 /* Send the NICK_CHANGE notify type to local clients on the channels
368 this client is joined to. */
369 silc_server_send_notify_on_channels(server, client,
370 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
371 oidp->data, oidp->len,
372 nidp->data, nidp->len);
374 silc_buffer_free(nidp);
375 silc_buffer_free(oidp);
381 SILC_LOG_DEBUG(("Old Server ID id(%s)",
382 silc_id_render(id, SILC_ID_CLIENT)));
383 SILC_LOG_DEBUG(("New Server ID id(%s)",
384 silc_id_render(id2, SILC_ID_CLIENT)));
385 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
386 if (server->server_type == SILC_ROUTER)
387 silc_idlist_replace_server_id(server->global_list, id, id2);
390 case SILC_ID_CHANNEL:
391 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
411 /* Received New Client packet and processes it. Creates Client ID for the
412 client. Client becomes registered after calling this functions. */
414 SilcClientEntry silc_server_new_client(SilcServer server,
415 SilcSocketConnection sock,
416 SilcPacketContext *packet)
418 SilcBuffer buffer = packet->buffer;
419 SilcClientEntry client;
420 SilcIDCacheEntry cache;
421 SilcClientID *client_id;
423 SilcIDListData idata;
424 char *username = NULL, *realname = NULL, *id_string;
427 SILC_LOG_DEBUG(("Creating new client"));
429 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
432 /* Take client entry */
433 client = (SilcClientEntry)sock->user_data;
434 idata = (SilcIDListData)client;
436 /* Fetch the old client cache entry so that we can update it. */
437 if (!silc_idcache_find_by_context(server->local_list->clients,
438 sock->user_data, &cache)) {
439 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
443 /* Parse incoming packet */
444 ret = silc_buffer_unformat(buffer,
445 SILC_STR_UI16_STRING_ALLOC(&username),
446 SILC_STR_UI16_STRING_ALLOC(&realname),
456 /* Create Client ID */
457 silc_id_create_client_id(server->id, server->rng, server->md5hash,
458 username, &client_id);
460 /* Update client entry */
461 idata->registered = TRUE;
462 client->nickname = strdup(username);
463 client->username = username;
464 client->userinfo = realname;
465 client->id = client_id;
467 /* Update the cache entry */
468 cache->id = (void *)client_id;
469 cache->type = SILC_ID_CLIENT;
470 cache->data = username;
471 silc_idcache_sort_by_data(server->local_list->clients);
473 /* Notify our router about new client on the SILC network */
474 if (!server->standalone)
475 silc_server_send_new_id(server, (SilcSocketConnection)
476 server->router->connection,
477 server->server_type == SILC_ROUTER ? TRUE : FALSE,
478 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
480 /* Send the new client ID to the client. */
481 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
482 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
483 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
484 silc_buffer_format(reply,
485 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
486 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
487 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
489 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
490 reply->data, reply->len, FALSE);
491 silc_free(id_string);
492 silc_buffer_free(reply);
494 /* Send some nice info to the client */
495 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
496 ("Welcome to the SILC Network %s@%s",
497 username, sock->hostname));
498 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
499 ("Your host is %s, running version %s",
500 server->config->server_info->server_name,
502 if (server->server_type == SILC_ROUTER) {
503 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
504 ("There are %d clients on %d servers in SILC "
505 "Network", server->stat.clients,
506 server->stat.servers + 1));
507 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
508 ("There are %d clients on %d server in our cell",
509 server->stat.cell_clients,
510 server->stat.cell_servers));
511 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
512 ("I have %d clients, %d channels, %d servers and "
514 server->stat.my_clients,
515 server->stat.my_channels,
516 server->stat.my_servers,
517 server->stat.my_routers));
518 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
519 ("%d server operators and %d router operators "
521 server->stat.my_server_ops,
522 server->stat.my_router_ops));
524 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
525 ("I have %d clients and %d channels formed",
526 server->stat.my_clients,
527 server->stat.my_channels));
528 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
529 ("%d operators online",
530 server->stat.my_server_ops));
532 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
533 ("Your connection is secured with %s cipher, "
534 "key length %d bits",
535 idata->send_key->cipher->name,
536 idata->send_key->cipher->key_len));
537 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
538 ("Your current nickname is %s",
542 silc_server_send_motd(server, sock);
547 /* Create new server. This processes received New Server packet and
548 saves the received Server ID. The server is our locally connected
549 server thus we save all the information and save it to local list.
550 This funtion can be used by both normal server and router server.
551 If normal server uses this it means that its router has connected
552 to the server. If router uses this it means that one of the cell's
553 servers is connected to the router. */
555 SilcServerEntry silc_server_new_server(SilcServer server,
556 SilcSocketConnection sock,
557 SilcPacketContext *packet)
559 SilcBuffer buffer = packet->buffer;
560 SilcServerEntry new_server;
561 SilcIDCacheEntry cache;
562 SilcServerID *server_id;
563 SilcIDListData idata;
564 unsigned char *server_name, *id_string;
565 unsigned short id_len;
568 SILC_LOG_DEBUG(("Creating new server"));
570 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
571 sock->type != SILC_SOCKET_TYPE_ROUTER)
574 /* Take server entry */
575 new_server = (SilcServerEntry)sock->user_data;
576 idata = (SilcIDListData)new_server;
578 /* Fetch the old server cache entry so that we can update it. */
579 if (!silc_idcache_find_by_context(server->local_list->servers,
580 sock->user_data, &cache)) {
581 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
585 /* Parse the incoming packet */
586 ret = silc_buffer_unformat(buffer,
587 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
588 SILC_STR_UI16_STRING_ALLOC(&server_name),
592 silc_free(id_string);
594 silc_free(server_name);
598 if (id_len > buffer->len) {
599 silc_free(id_string);
600 silc_free(server_name);
605 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
607 silc_free(id_string);
608 silc_free(server_name);
611 silc_free(id_string);
613 /* Update client entry */
614 idata->registered = TRUE;
615 new_server->server_name = server_name;
616 new_server->id = server_id;
618 /* Update the cache entry */
619 cache->id = (void *)server_id;
620 cache->type = SILC_ID_SERVER;
621 cache->data = server_name;
622 silc_idcache_sort_by_data(server->local_list->servers);
624 /* Distribute the information about new server in the SILC network
625 to our router. If we are normal server we won't send anything
626 since this connection must be our router connection. */
627 if (server->server_type == SILC_ROUTER && !server->standalone &&
628 server->router->connection != sock)
629 silc_server_send_new_id(server, server->router->connection,
630 TRUE, new_server->id, SILC_ID_SERVER,
633 if (server->server_type == SILC_ROUTER)
634 server->stat.cell_servers++;
639 /* Processes incoming New ID packet. New ID Payload is used to distribute
640 information about newly registered clients and servers. */
642 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
643 SilcPacketContext *packet)
645 SilcBuffer buffer = packet->buffer;
647 SilcServerEntry router;
648 SilcSocketConnection router_sock;
651 unsigned char *hash = NULL;
654 SILC_LOG_DEBUG(("Processing new ID"));
656 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
657 server->server_type == SILC_SERVER ||
658 packet->src_id_type != SILC_ID_SERVER)
661 idp = silc_id_payload_parse(buffer);
665 id_type = silc_id_payload_get_type(idp);
667 /* Normal server cannot have other normal server connections */
668 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
671 id = silc_id_payload_get_id(idp);
675 /* If the sender of this packet is server and we are router we need to
676 broadcast this packet to other routers in the network. */
677 if (!server->standalone && server->server_type == SILC_ROUTER &&
678 sock->type == SILC_SOCKET_TYPE_SERVER &&
679 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
680 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
681 silc_server_packet_send(server, server->router->connection,
683 packet->flags | SILC_PACKET_FLAG_BROADCAST,
684 buffer->data, buffer->len, FALSE);
687 if (sock->type == SILC_SOCKET_TYPE_SERVER)
688 id_list = server->local_list;
690 id_list = server->global_list;
693 router = sock->user_data;
698 SilcClientEntry entry;
700 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
701 silc_id_render(id, SILC_ID_CLIENT),
702 sock->type == SILC_SOCKET_TYPE_SERVER ?
703 "Server" : "Router", sock->hostname));
705 /* As a router we keep information of all global information in our
706 global list. Cell wide information however is kept in the local
707 list. The client is put to global list and we will take the hash
708 value of the Client ID and save it to the ID Cache system for fast
709 searching in the future. */
710 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
711 sizeof(unsigned char));
712 memcpy(hash, ((SilcClientID *)id)->hash,
713 sizeof(((SilcClientID *)id)->hash));
714 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
715 router, router_sock);
716 entry->nickname = NULL;
718 if (sock->type == SILC_SOCKET_TYPE_SERVER)
719 server->stat.cell_clients++;
720 server->stat.clients++;
723 /* XXX Adding two ID's with same IP number replaces the old entry thus
724 gives wrong route. Thus, now disabled until figured out a better way
725 to do this or when removed the whole thing. This could be removed
726 because entry->router->connection gives always the most optimal route
727 for the ID anyway (unless new routes (faster perhaps) are established
728 after receiving this ID, this we don't know however). */
729 /* Add route cache for this ID */
730 silc_server_route_add(silc_server_route_hash(
731 ((SilcClientID *)id)->ip.s_addr,
732 server->id->port), ((SilcClientID *)id)->ip.s_addr,
739 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
740 silc_id_render(id, SILC_ID_SERVER),
741 sock->type == SILC_SOCKET_TYPE_SERVER ?
742 "Server" : "Router", sock->hostname));
744 /* As a router we keep information of all global information in our global
745 list. Cell wide information however is kept in the local list. */
746 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
748 if (sock->type == SILC_SOCKET_TYPE_SERVER)
749 server->stat.cell_servers++;
750 server->stat.servers++;
753 /* Add route cache for this ID */
754 silc_server_route_add(silc_server_route_hash(
755 ((SilcServerID *)id)->ip.s_addr,
756 ((SilcServerID *)id)->port),
757 ((SilcServerID *)id)->ip.s_addr,
762 case SILC_ID_CHANNEL:
763 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
771 silc_id_payload_free(idp);
774 /* Received Remove Channel User packet to remove a user from a channel.
775 Routers notify other routers that user has left a channel. Client must
776 not send this packet. Normal server may send this packet but must not
779 void silc_server_remove_channel_user(SilcServer server,
780 SilcSocketConnection sock,
781 SilcPacketContext *packet)
783 SilcBuffer buffer = packet->buffer;
784 unsigned char *tmp1 = NULL, *tmp2 = NULL;
785 unsigned int tmp1_len, tmp2_len;
786 SilcClientID *client_id = NULL;
787 SilcChannelID *channel_id = NULL;
788 SilcChannelEntry channel;
789 SilcClientEntry client;
792 SILC_LOG_DEBUG(("Removing user from channel"));
794 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
795 server->server_type == SILC_SERVER)
798 ret = silc_buffer_unformat(buffer,
799 SILC_STR_UI16_NSTRING_ALLOC(&tmp1, &tmp1_len),
800 SILC_STR_UI16_NSTRING_ALLOC(&tmp2, &tmp2_len),
805 client_id = silc_id_str2id(tmp1, tmp1_len, SILC_ID_CLIENT);
806 channel_id = silc_id_str2id(tmp2, tmp2_len, SILC_ID_CHANNEL);
807 if (!client_id || !channel_id)
810 /* If we are router and this packet is not already broadcast packet
811 we will broadcast it. The sending socket really cannot be router or
812 the router is buggy. If this packet is coming from router then it must
813 have the broadcast flag set already and we won't do anything. */
814 if (!server->standalone && server->server_type == SILC_ROUTER &&
815 sock->type == SILC_SOCKET_TYPE_SERVER &&
816 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
817 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
818 silc_server_packet_send(server, server->router->connection, packet->type,
819 packet->flags | SILC_PACKET_FLAG_BROADCAST,
820 buffer->data, buffer->len, FALSE);
823 /* Get channel entry */
824 channel = silc_idlist_find_channel_by_id(server->local_list,
827 channel = silc_idlist_find_channel_by_id(server->global_list,
833 /* Get client entry */
834 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
836 client = silc_idlist_find_client_by_id(server->global_list,
842 /* Remove user from channel */
843 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
851 silc_free(client_id);
853 silc_free(channel_id);
856 /* Received New Channel packet. Information about new channels in the
857 network are distributed using this packet. Save the information about
860 void silc_server_new_channel(SilcServer server,
861 SilcSocketConnection sock,
862 SilcPacketContext *packet)
865 SilcChannelID *channel_id;
866 unsigned short channel_id_len;
870 SILC_LOG_DEBUG(("Processing New Channel"));
872 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
873 server->server_type == SILC_SERVER ||
874 packet->src_id_type != SILC_ID_SERVER)
878 ret = silc_buffer_unformat(packet->buffer,
879 SILC_STR_UI16_STRING_ALLOC(&channel_name),
880 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
884 silc_free(channel_name);
890 /* Decode the channel ID */
891 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
896 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
897 silc_id_render(channel_id, SILC_ID_CHANNEL),
900 /* Add the new channel. Add it always to global list since if we receive
901 this packet then it cannot be created by ourselves but some other
902 router hence global channel. */
903 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
904 server->router->connection, NULL);
906 server->stat.channels++;
909 /* Received notify packet. Server can receive notify packets from router.
910 Server then relays the notify messages to clients if needed. */
912 void silc_server_notify(SilcServer server,
913 SilcSocketConnection sock,
914 SilcPacketContext *packet)
916 SilcNotifyPayload payload;
918 SilcArgumentPayload args;
919 SilcChannelID *channel_id;
920 SilcClientID *client_id, *client_id2;
921 SilcChannelEntry channel;
922 SilcClientEntry client;
924 unsigned int tmp_len;
926 SILC_LOG_DEBUG(("Start"));
928 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
929 packet->src_id_type != SILC_ID_SERVER)
932 /* XXX: For now we expect that the we are normal server and that the
933 sender is router. Server could send (protocol allows it) notify to
934 router but we don't support it yet. */
935 if (server->server_type != SILC_SERVER &&
936 sock->type != SILC_SOCKET_TYPE_ROUTER)
939 payload = silc_notify_payload_parse(packet->buffer);
943 type = silc_notify_get_type(payload);
944 args = silc_notify_get_args(payload);
949 case SILC_NOTIFY_TYPE_JOIN:
951 * Distribute the notify to local clients on the channel
953 SILC_LOG_DEBUG(("JOIN notify"));
955 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
956 packet->dst_id_type);
960 /* Get channel entry */
961 channel = silc_idlist_find_channel_by_id(server->local_list,
964 silc_free(channel_id);
969 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
971 silc_free(channel_id);
974 client_id = silc_id_payload_parse_id(tmp, tmp_len);
976 silc_free(channel_id);
980 /* Send to channel */
981 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
982 FALSE, packet->buffer->data,
983 packet->buffer->len, FALSE);
985 /* If the the client is not in local list we check global list (ie. the
986 channel will be global channel) and if it does not exist then create
987 entry for the client. */
988 client = silc_idlist_find_client_by_id(server->local_list,
991 SilcChannelClientEntry chl;
993 client = silc_idlist_find_client_by_id(server->global_list,
996 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
997 client_id, sock->user_data, sock);
999 silc_free(channel_id);
1000 silc_free(client_id);
1005 /* The channel is global now */
1006 channel->global_users = TRUE;
1008 /* Now actually JOIN the global client to the channel */
1009 chl = silc_calloc(1, sizeof(*chl));
1010 chl->client = client;
1011 chl->channel = channel;
1012 silc_list_add(channel->user_list, chl);
1013 silc_list_add(client->channels, chl);
1015 silc_free(client_id);
1019 case SILC_NOTIFY_TYPE_LEAVE:
1021 * Distribute the notify to local clients on the channel
1023 SILC_LOG_DEBUG(("LEAVE notify"));
1025 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1026 packet->dst_id_type);
1030 /* Get channel entry */
1031 channel = silc_idlist_find_channel_by_id(server->local_list,
1034 silc_free(channel_id);
1039 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1041 silc_free(channel_id);
1044 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1046 silc_free(channel_id);
1050 /* Send to channel */
1051 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
1052 FALSE, packet->buffer->data,
1053 packet->buffer->len, FALSE);
1055 /* Get client entry */
1056 client = silc_idlist_find_client_by_id(server->global_list,
1059 client = silc_idlist_find_client_by_id(server->local_list,
1062 silc_free(client_id);
1063 silc_free(channel_id);
1067 silc_free(client_id);
1069 /* Remove the user from channel */
1070 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1073 case SILC_NOTIFY_TYPE_SIGNOFF:
1075 * Distribute the notify to local clients on the channel
1077 SILC_LOG_DEBUG(("SIGNOFF notify"));
1080 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1083 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1087 /* Get client entry */
1088 client = silc_idlist_find_client_by_id(server->global_list,
1091 client = silc_idlist_find_client_by_id(server->local_list,
1094 silc_free(client_id);
1098 silc_free(client_id);
1100 /* Remove the client from all channels */
1101 silc_server_remove_from_channels(server, NULL, client);
1103 /* Remove the client entry */
1104 silc_idlist_del_client(server->global_list, client);
1107 case SILC_NOTIFY_TYPE_NICK_CHANGE:
1110 * Distribute the notify to local clients on the channel
1112 unsigned char *id, *id2;
1114 SILC_LOG_DEBUG(("NICK CHANGE notify"));
1116 /* Get old client ID */
1117 id = silc_argument_get_arg_type(args, 1, &tmp_len);
1120 client_id = silc_id_payload_parse_id(id, tmp_len);
1124 /* Get new client ID */
1125 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
1128 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
1132 SILC_LOG_DEBUG(("Old Client ID id(%s)",
1133 silc_id_render(client_id, SILC_ID_CLIENT)));
1134 SILC_LOG_DEBUG(("New Client ID id(%s)",
1135 silc_id_render(client_id2, SILC_ID_CLIENT)));
1137 /* Replace the Client ID */
1138 client = silc_idlist_replace_client_id(server->global_list, client_id,
1141 client = silc_idlist_replace_client_id(server->local_list, client_id,
1145 /* Send the NICK_CHANGE notify type to local clients on the channels
1146 this client is joined to. */
1147 silc_server_send_notify_on_channels(server, client,
1148 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
1152 silc_free(client_id);
1154 silc_free(client_id2);
1157 case SILC_NOTIFY_TYPE_TOPIC_SET:
1159 * Distribute the notify to local clients on the channel
1161 SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
1164 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1166 * Distribute the notify to local clients on the channel
1168 SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
1171 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1173 * Distribute the notify to local clients on the channel
1175 SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
1178 /* Ignore rest notify types for now */
1179 case SILC_NOTIFY_TYPE_NONE:
1180 case SILC_NOTIFY_TYPE_INVITE:
1181 case SILC_NOTIFY_TYPE_MOTD:
1187 silc_notify_payload_free(payload);
1190 /* Received new channel user packet. Information about new users on a
1191 channel are distributed between routers using this packet. The
1192 router receiving this will redistribute it and also sent JOIN notify
1193 to local clients on the same channel. Normal server sends JOIN notify
1194 to its local clients on the channel. */
1196 void silc_server_new_channel_user(SilcServer server,
1197 SilcSocketConnection sock,
1198 SilcPacketContext *packet)
1200 unsigned char *tmpid1, *tmpid2;
1201 SilcClientID *client_id = NULL;
1202 SilcChannelID *channel_id = NULL;
1203 unsigned short channel_id_len;
1204 unsigned short client_id_len;
1205 SilcClientEntry client;
1206 SilcChannelEntry channel;
1207 SilcChannelClientEntry chl;
1211 SILC_LOG_DEBUG(("Start"));
1213 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1214 server->server_type != SILC_ROUTER ||
1215 packet->src_id_type != SILC_ID_SERVER)
1219 ret = silc_buffer_unformat(packet->buffer,
1220 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1222 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1233 /* Decode the channel ID */
1234 channel_id = silc_id_str2id(tmpid1, channel_id_len, SILC_ID_CHANNEL);
1238 /* Decode the client ID */
1239 client_id = silc_id_str2id(tmpid2, client_id_len, SILC_ID_CLIENT);
1243 /* Find the channel */
1244 channel = silc_idlist_find_channel_by_id(server->local_list,
1247 channel = silc_idlist_find_channel_by_id(server->global_list,
1253 /* If we are router and this packet is not already broadcast packet
1254 we will broadcast it. */
1255 if (!server->standalone && server->server_type == SILC_ROUTER &&
1256 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1257 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1258 silc_server_packet_send(server, server->router->connection, packet->type,
1259 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1260 packet->buffer->data, packet->buffer->len, FALSE);
1263 /* Get client entry */
1264 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1266 client = silc_idlist_find_client_by_id(server->global_list,
1272 /* Join the client to the channel by adding it to channel's user list.
1273 Add also the channel to client entry's channels list for fast cross-
1275 chl = silc_calloc(1, sizeof(*chl));
1276 chl->client = client;
1277 chl->channel = channel;
1278 silc_list_add(channel->user_list, chl);
1279 silc_list_add(client->channels, chl);
1281 server->stat.chanclients++;
1283 /* Send JOIN notify to local clients on the channel. As we are router
1284 it is assured that this is sent only to our local clients and locally
1285 connected servers if needed. */
1286 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1287 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1288 SILC_NOTIFY_TYPE_JOIN,
1289 1, clidp->data, clidp->len);
1290 silc_buffer_free(clidp);
1296 silc_free(client_id);
1298 silc_free(channel_id);
1303 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1304 that certain ID should be removed. After that the ID will become invalid. */
1306 void silc_server_remove_id(SilcServer server,
1307 SilcSocketConnection sock,
1308 SilcPacketContext *packet)
1313 void *id, *id_entry;
1315 SILC_LOG_DEBUG(("Start"));
1317 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1318 server->server_type == SILC_SERVER ||
1319 packet->src_id_type != SILC_ID_SERVER)
1322 idp = silc_id_payload_parse(packet->buffer);
1326 id_type = silc_id_payload_get_type(idp);
1328 id = silc_id_payload_get_id(idp);
1332 /* If the sender of this packet is server and we are router we need to
1333 broadcast this packet to other routers in the network. */
1334 if (!server->standalone && server->server_type == SILC_ROUTER &&
1335 sock->type == SILC_SOCKET_TYPE_SERVER &&
1336 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1337 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1338 silc_server_packet_send(server, server->router->connection,
1340 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1341 packet->buffer->data, packet->buffer->len, FALSE);
1344 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1345 id_list = server->local_list;
1347 id_list = server->global_list;
1351 case SILC_ID_CLIENT:
1352 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1355 /* Remove from channels */
1356 silc_server_remove_from_channels(server, NULL, id_entry);
1358 /* Remove the client entry */
1359 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1360 server->stat.clients--;
1362 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1363 silc_id_render(id, SILC_ID_CLIENT),
1364 sock->type == SILC_SOCKET_TYPE_SERVER ?
1365 "Server" : "Router", sock->hostname));
1369 case SILC_ID_SERVER:
1370 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1373 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1374 server->stat.servers--;
1376 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1377 silc_id_render(id, SILC_ID_SERVER),
1378 sock->type == SILC_SOCKET_TYPE_SERVER ?
1379 "Server" : "Router", sock->hostname));
1383 case SILC_ID_CHANNEL:
1384 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1387 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1388 server->stat.channels--;
1390 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1391 silc_id_render(id, SILC_ID_CHANNEL),
1392 sock->type == SILC_SOCKET_TYPE_SERVER ?
1393 "Server" : "Router", sock->hostname));
1402 silc_id_payload_free(idp);
1405 /* Processes received SET_MODE packet. The packet is used to distribute
1406 the information about changed channel's or client's channel modes. */
1408 void silc_server_set_mode(SilcServer server,
1409 SilcSocketConnection sock,
1410 SilcPacketContext *packet)
1412 SilcSetModePayload payload = NULL;
1413 SilcArgumentPayload args = NULL;
1414 unsigned short mode_type;
1415 unsigned int mode_mask;
1416 unsigned char *tmp, *tmp2;
1417 unsigned int tmp_len, tmp_len2;
1418 unsigned char mode[4];
1419 SilcClientID *client_id;
1420 SilcChannelID *channel_id = NULL;
1421 SilcClientEntry client;
1422 SilcChannelEntry channel;
1423 SilcChannelClientEntry chl;
1425 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1426 packet->src_id_type == SILC_ID_CLIENT)
1429 SILC_LOG_DEBUG(("Start"));
1431 /* If we are router and this packet is not already broadcast packet
1432 we will broadcast it. The sending socket really cannot be router or
1433 the router is buggy. If this packet is coming from router then it must
1434 have the broadcast flag set already and we won't do anything. */
1435 if (!server->standalone && server->server_type == SILC_ROUTER &&
1436 sock->type == SILC_SOCKET_TYPE_SERVER &&
1437 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1438 SILC_LOG_DEBUG(("Broadcasting received Set Mode packet"));
1439 silc_server_packet_send(server, server->router->connection, packet->type,
1440 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1441 packet->buffer->data, packet->buffer->len, FALSE);
1444 /* Parse Set Mode payload */
1445 payload = silc_set_mode_payload_parse(packet->buffer);
1449 mode_type = silc_set_mode_get_type(payload);
1450 args = silc_set_mode_get_args(payload);
1454 mode_mask = silc_set_mode_get_mode(payload);
1455 SILC_PUT32_MSB(mode_mask, mode);
1457 switch (mode_type) {
1458 case SILC_MODE_TYPE_CHANNEL:
1459 /* Get Channel ID */
1460 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1463 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1467 /* Get channel entry */
1468 channel = silc_idlist_find_channel_by_id(server->local_list,
1471 channel = silc_idlist_find_channel_by_id(server->global_list,
1477 /* Get Client ID payload */
1478 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1482 /* Send CMODE_CHANGE notify to local channel */
1483 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1484 SILC_NOTIFY_TYPE_CMODE_CHANGE,
1486 mode, sizeof(mode));
1488 /* Change the mode */
1489 channel->mode = mode_mask;
1492 case SILC_MODE_TYPE_UCHANNEL:
1493 /* Get Channel ID */
1494 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1497 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1501 /* Get channel entry */
1502 channel = silc_idlist_find_channel_by_id(server->local_list,
1505 channel = silc_idlist_find_channel_by_id(server->global_list,
1511 /* Get Client ID payload */
1512 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1516 /* Get target Client ID */
1517 tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2);
1520 client_id = silc_id_payload_parse_id(tmp2, tmp_len2);
1524 /* Get target client entry */
1525 client = silc_idlist_find_client_by_id(server->global_list,
1528 client = silc_idlist_find_client_by_id(server->local_list,
1531 silc_free(client_id);
1535 silc_free(client_id);
1537 /* Send CUMODE_CHANGE notify to local channel */
1538 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1539 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2,
1544 /* Get entry to the channel user list */
1545 silc_list_start(channel->user_list);
1546 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
1547 if (chl->client == client) {
1548 /* Change the mode */
1549 chl->mode = mode_mask;
1561 silc_free(channel_id);
1563 silc_argument_payload_free(args);
1565 silc_set_mode_payload_free(payload);