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_CLIENT)));
389 SILC_LOG_DEBUG(("New Server ID id(%s)",
390 silc_id_render(id2, SILC_ID_CLIENT)));
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 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
417 /* Received New Client packet and processes it. Creates Client ID for the
418 client. Client becomes registered after calling this functions. */
420 SilcClientEntry silc_server_new_client(SilcServer server,
421 SilcSocketConnection sock,
422 SilcPacketContext *packet)
424 SilcBuffer buffer = packet->buffer;
425 SilcClientEntry client;
426 SilcIDCacheEntry cache;
427 SilcClientID *client_id;
429 SilcIDListData idata;
430 char *username = NULL, *realname = NULL, *id_string;
433 SILC_LOG_DEBUG(("Creating new client"));
435 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
438 /* Take client entry */
439 client = (SilcClientEntry)sock->user_data;
440 idata = (SilcIDListData)client;
442 /* Fetch the old client cache entry so that we can update it. */
443 if (!silc_idcache_find_by_context(server->local_list->clients,
444 sock->user_data, &cache)) {
445 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
449 /* Parse incoming packet */
450 ret = silc_buffer_unformat(buffer,
451 SILC_STR_UI16_STRING_ALLOC(&username),
452 SILC_STR_UI16_STRING_ALLOC(&realname),
462 /* Create Client ID */
463 silc_id_create_client_id(server->id, server->rng, server->md5hash,
464 username, &client_id);
466 /* Update client entry */
467 idata->registered = TRUE;
468 client->nickname = strdup(username);
469 client->username = username;
470 client->userinfo = realname;
471 client->id = client_id;
473 /* Update the cache entry */
474 cache->id = (void *)client_id;
475 cache->type = SILC_ID_CLIENT;
476 cache->data = username;
477 silc_idcache_sort_by_data(server->local_list->clients);
479 /* Notify our router about new client on the SILC network */
480 if (!server->standalone)
481 silc_server_send_new_id(server, (SilcSocketConnection)
482 server->router->connection,
483 server->server_type == SILC_ROUTER ? TRUE : FALSE,
484 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
486 /* Send the new client ID to the client. */
487 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
488 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
489 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
490 silc_buffer_format(reply,
491 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
492 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
493 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
495 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
496 reply->data, reply->len, FALSE);
497 silc_free(id_string);
498 silc_buffer_free(reply);
500 /* Send some nice info to the client */
501 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
502 ("Welcome to the SILC Network %s@%s",
503 username, sock->hostname));
504 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
505 ("Your host is %s, running version %s",
506 server->config->server_info->server_name,
508 if (server->server_type == SILC_ROUTER) {
509 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
510 ("There are %d clients on %d servers in SILC "
511 "Network", server->stat.clients,
512 server->stat.servers + 1));
513 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
514 ("There are %d clients on %d server in our cell",
515 server->stat.cell_clients,
516 server->stat.cell_servers + 1));
517 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
518 ("I have %d clients, %d channels, %d servers and "
520 server->stat.my_clients,
521 server->stat.my_channels,
522 server->stat.my_servers,
523 server->stat.my_routers));
524 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
525 ("%d server operators and %d router operators "
527 server->stat.my_server_ops,
528 server->stat.my_router_ops));
530 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
531 ("I have %d clients and %d channels formed",
532 server->stat.my_clients,
533 server->stat.my_channels));
534 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
535 ("%d operators online",
536 server->stat.my_server_ops));
538 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
539 ("Your connection is secured with %s cipher, "
540 "key length %d bits",
541 idata->send_key->cipher->name,
542 idata->send_key->cipher->key_len));
543 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
544 ("Your current nickname is %s",
548 silc_server_send_motd(server, sock);
553 /* Create new server. This processes received New Server packet and
554 saves the received Server ID. The server is our locally connected
555 server thus we save all the information and save it to local list.
556 This funtion can be used by both normal server and router server.
557 If normal server uses this it means that its router has connected
558 to the server. If router uses this it means that one of the cell's
559 servers is connected to the router. */
561 SilcServerEntry silc_server_new_server(SilcServer server,
562 SilcSocketConnection sock,
563 SilcPacketContext *packet)
565 SilcBuffer buffer = packet->buffer;
566 SilcServerEntry new_server;
567 SilcIDCacheEntry cache;
568 SilcServerID *server_id;
569 SilcIDListData idata;
570 unsigned char *server_name, *id_string;
571 unsigned short id_len;
574 SILC_LOG_DEBUG(("Creating new server"));
576 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
577 sock->type != SILC_SOCKET_TYPE_ROUTER)
580 /* Take server entry */
581 new_server = (SilcServerEntry)sock->user_data;
582 idata = (SilcIDListData)new_server;
584 /* Fetch the old server cache entry so that we can update it. */
585 if (!silc_idcache_find_by_context(server->local_list->servers,
586 sock->user_data, &cache)) {
587 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
591 /* Parse the incoming packet */
592 ret = silc_buffer_unformat(buffer,
593 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
594 SILC_STR_UI16_STRING_ALLOC(&server_name),
598 silc_free(id_string);
600 silc_free(server_name);
604 if (id_len > buffer->len) {
605 silc_free(id_string);
606 silc_free(server_name);
611 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
613 silc_free(id_string);
614 silc_free(server_name);
617 silc_free(id_string);
619 /* Update client entry */
620 idata->registered = TRUE;
621 new_server->server_name = server_name;
622 new_server->id = server_id;
624 /* Update the cache entry */
625 cache->id = (void *)server_id;
626 cache->type = SILC_ID_SERVER;
627 cache->data = server_name;
628 silc_idcache_sort_by_data(server->local_list->servers);
630 /* Distribute the information about new server in the SILC network
631 to our router. If we are normal server we won't send anything
632 since this connection must be our router connection. */
633 if (server->server_type == SILC_ROUTER && !server->standalone &&
634 server->router->connection != sock)
635 silc_server_send_new_id(server, server->router->connection,
636 TRUE, new_server->id, SILC_ID_SERVER,
639 if (server->server_type == SILC_ROUTER)
640 server->stat.cell_servers++;
645 /* Processes incoming New ID packet. New ID Payload is used to distribute
646 information about newly registered clients and servers. */
648 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
649 SilcPacketContext *packet)
651 SilcBuffer buffer = packet->buffer;
653 SilcServerEntry router;
654 SilcSocketConnection router_sock;
657 unsigned char *hash = NULL;
660 SILC_LOG_DEBUG(("Processing new ID"));
662 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
663 server->server_type == SILC_SERVER ||
664 packet->src_id_type != SILC_ID_SERVER)
667 idp = silc_id_payload_parse(buffer);
671 id_type = silc_id_payload_get_type(idp);
673 /* Normal server cannot have other normal server connections */
674 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
677 id = silc_id_payload_get_id(idp);
681 /* If the sender of this packet is server and we are router we need to
682 broadcast this packet to other routers in the network. */
683 if (!server->standalone && server->server_type == SILC_ROUTER &&
684 sock->type == SILC_SOCKET_TYPE_SERVER &&
685 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
686 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
687 silc_server_packet_send(server, server->router->connection,
689 packet->flags | SILC_PACKET_FLAG_BROADCAST,
690 buffer->data, buffer->len, FALSE);
693 if (sock->type == SILC_SOCKET_TYPE_SERVER)
694 id_list = server->local_list;
696 id_list = server->global_list;
699 router = sock->user_data;
704 SilcClientEntry entry;
706 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
707 silc_id_render(id, SILC_ID_CLIENT),
708 sock->type == SILC_SOCKET_TYPE_SERVER ?
709 "Server" : "Router", sock->hostname));
711 /* As a router we keep information of all global information in our
712 global list. Cell wide information however is kept in the local
713 list. The client is put to global list and we will take the hash
714 value of the Client ID and save it to the ID Cache system for fast
715 searching in the future. */
716 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
717 sizeof(unsigned char));
718 memcpy(hash, ((SilcClientID *)id)->hash,
719 sizeof(((SilcClientID *)id)->hash));
720 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
722 entry->nickname = NULL;
724 if (sock->type == SILC_SOCKET_TYPE_SERVER)
725 server->stat.cell_clients++;
726 server->stat.clients++;
729 /* XXX Adding two ID's with same IP number replaces the old entry thus
730 gives wrong route. Thus, now disabled until figured out a better way
731 to do this or when removed the whole thing. This could be removed
732 because entry->router->connection gives always the most optimal route
733 for the ID anyway (unless new routes (faster perhaps) are established
734 after receiving this ID, this we don't know however). */
735 /* Add route cache for this ID */
736 silc_server_route_add(silc_server_route_hash(
737 ((SilcClientID *)id)->ip.s_addr,
738 server->id->port), ((SilcClientID *)id)->ip.s_addr,
745 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
746 silc_id_render(id, SILC_ID_SERVER),
747 sock->type == SILC_SOCKET_TYPE_SERVER ?
748 "Server" : "Router", sock->hostname));
750 /* As a router we keep information of all global information in our global
751 list. Cell wide information however is kept in the local list. */
752 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
754 if (sock->type == SILC_SOCKET_TYPE_SERVER)
755 server->stat.cell_servers++;
756 server->stat.servers++;
759 /* Add route cache for this ID */
760 silc_server_route_add(silc_server_route_hash(
761 ((SilcServerID *)id)->ip.s_addr,
762 ((SilcServerID *)id)->port),
763 ((SilcServerID *)id)->ip.s_addr,
768 case SILC_ID_CHANNEL:
769 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
777 silc_id_payload_free(idp);
780 /* Received Remove Channel User packet to remove a user from a channel.
781 Routers notify other routers that user has left a channel. Client must
782 not send this packet. Normal server may send this packet but must not
785 void silc_server_remove_channel_user(SilcServer server,
786 SilcSocketConnection sock,
787 SilcPacketContext *packet)
789 SilcBuffer buffer = packet->buffer;
790 unsigned char *tmp1 = NULL, *tmp2 = NULL;
791 unsigned short tmp1_len, tmp2_len;
792 SilcClientID *client_id = NULL;
793 SilcChannelID *channel_id = NULL;
794 SilcChannelEntry channel;
795 SilcClientEntry client;
798 SILC_LOG_DEBUG(("Removing user from channel"));
800 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
801 server->server_type == SILC_SERVER)
804 ret = silc_buffer_unformat(buffer,
805 SILC_STR_UI16_NSTRING_ALLOC(&tmp1, &tmp1_len),
806 SILC_STR_UI16_NSTRING_ALLOC(&tmp2, &tmp2_len),
811 client_id = silc_id_str2id(tmp1, tmp1_len, SILC_ID_CLIENT);
812 channel_id = silc_id_str2id(tmp2, tmp2_len, SILC_ID_CHANNEL);
813 if (!client_id || !channel_id)
816 /* If we are router and this packet is not already broadcast packet
817 we will broadcast it. The sending socket really cannot be router or
818 the router is buggy. If this packet is coming from router then it must
819 have the broadcast flag set already and we won't do anything. */
820 if (!server->standalone && server->server_type == SILC_ROUTER &&
821 sock->type == SILC_SOCKET_TYPE_SERVER &&
822 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
823 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
824 silc_server_packet_send(server, server->router->connection, packet->type,
825 packet->flags | SILC_PACKET_FLAG_BROADCAST,
826 buffer->data, buffer->len, FALSE);
829 /* Get channel entry */
830 channel = silc_idlist_find_channel_by_id(server->local_list,
833 channel = silc_idlist_find_channel_by_id(server->global_list,
839 /* Get client entry */
840 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
842 client = silc_idlist_find_client_by_id(server->global_list,
848 /* Remove user from channel */
849 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
857 silc_free(client_id);
859 silc_free(channel_id);
862 /* Received New Channel packet. Information about new channels in the
863 network are distributed using this packet. Save the information about
866 void silc_server_new_channel(SilcServer server,
867 SilcSocketConnection sock,
868 SilcPacketContext *packet)
871 SilcChannelID *channel_id;
872 unsigned short channel_id_len;
876 SILC_LOG_DEBUG(("Processing New Channel"));
878 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
879 server->server_type == SILC_SERVER ||
880 packet->src_id_type != SILC_ID_SERVER)
884 ret = silc_buffer_unformat(packet->buffer,
885 SILC_STR_UI16_STRING_ALLOC(&channel_name),
886 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
890 silc_free(channel_name);
896 /* Decode the channel ID */
897 channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
902 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
903 silc_id_render(channel_id, SILC_ID_CHANNEL),
906 /* Add the new channel. Add it always to global list since if we receive
907 this packet then it cannot be created by ourselves but some other
908 router hence global channel. */
909 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
910 server->router->connection, NULL);
912 server->stat.channels++;
915 /* Received notify packet. Server can receive notify packets from router.
916 Server then relays the notify messages to clients if needed. */
918 void silc_server_notify(SilcServer server,
919 SilcSocketConnection sock,
920 SilcPacketContext *packet)
922 SilcNotifyPayload payload;
924 SilcArgumentPayload args;
925 SilcChannelID *channel_id;
926 SilcClientID *client_id, *client_id2;
927 SilcChannelEntry channel;
928 SilcClientEntry client;
930 unsigned int tmp_len;
932 SILC_LOG_DEBUG(("Start"));
934 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
935 packet->src_id_type != SILC_ID_SERVER)
938 /* XXX: For now we expect that the we are normal server and that the
939 sender is router. Server could send (protocol allows it) notify to
940 router but we don't support it yet. */
941 if (server->server_type != SILC_SERVER &&
942 sock->type != SILC_SOCKET_TYPE_ROUTER)
945 payload = silc_notify_payload_parse(packet->buffer);
949 type = silc_notify_get_type(payload);
950 args = silc_notify_get_args(payload);
955 case SILC_NOTIFY_TYPE_JOIN:
957 * Distribute the notify to local clients on the channel
959 SILC_LOG_DEBUG(("JOIN notify"));
961 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
962 packet->dst_id_type);
966 /* Get channel entry */
967 channel = silc_idlist_find_channel_by_id(server->local_list,
970 silc_free(channel_id);
975 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
977 silc_free(channel_id);
980 client_id = silc_id_payload_parse_id(tmp, tmp_len);
982 silc_free(channel_id);
986 /* Send to channel */
987 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
988 FALSE, packet->buffer->data,
989 packet->buffer->len, FALSE);
991 /* If the the client is not in local list we check global list (ie. the
992 channel will be global channel) and if it does not exist then create
993 entry for the client. */
994 client = silc_idlist_find_client_by_id(server->local_list,
997 SilcChannelClientEntry chl;
999 client = silc_idlist_find_client_by_id(server->global_list,
1002 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
1003 client_id, sock->user_data, NULL);
1005 silc_free(channel_id);
1006 silc_free(client_id);
1011 /* The channel is global now */
1012 channel->global_users = TRUE;
1014 /* Now actually JOIN the global client to the channel */
1015 chl = silc_calloc(1, sizeof(*chl));
1016 chl->client = client;
1017 chl->channel = channel;
1018 silc_list_add(channel->user_list, chl);
1019 silc_list_add(client->channels, chl);
1021 silc_free(client_id);
1025 case SILC_NOTIFY_TYPE_LEAVE:
1027 * Distribute the notify to local clients on the channel
1029 SILC_LOG_DEBUG(("LEAVE notify"));
1031 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1032 packet->dst_id_type);
1036 /* Get channel entry */
1037 channel = silc_idlist_find_channel_by_id(server->local_list,
1040 silc_free(channel_id);
1045 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1047 silc_free(channel_id);
1050 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1052 silc_free(channel_id);
1056 /* Send to channel */
1057 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
1058 FALSE, packet->buffer->data,
1059 packet->buffer->len, FALSE);
1061 /* Get client entry */
1062 client = silc_idlist_find_client_by_id(server->global_list,
1065 client = silc_idlist_find_client_by_id(server->local_list,
1068 silc_free(client_id);
1069 silc_free(channel_id);
1073 silc_free(client_id);
1075 /* Remove the user from channel */
1076 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1079 case SILC_NOTIFY_TYPE_SIGNOFF:
1081 * Distribute the notify to local clients on the channel
1083 SILC_LOG_DEBUG(("SIGNOFF notify"));
1086 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1089 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1093 /* Get client entry */
1094 client = silc_idlist_find_client_by_id(server->global_list,
1097 client = silc_idlist_find_client_by_id(server->local_list,
1100 silc_free(client_id);
1104 silc_free(client_id);
1106 /* Remove the client from all channels */
1107 silc_server_remove_from_channels(server, NULL, client);
1109 /* Remove the client entry */
1110 silc_idlist_del_client(server->global_list, client);
1113 case SILC_NOTIFY_TYPE_NICK_CHANGE:
1116 * Distribute the notify to local clients on the channel
1118 unsigned char *id, *id2;
1120 SILC_LOG_DEBUG(("NICK CHANGE notify"));
1122 /* Get old client ID */
1123 id = silc_argument_get_arg_type(args, 1, &tmp_len);
1126 client_id = silc_id_payload_parse_id(id, tmp_len);
1130 /* Get new client ID */
1131 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
1134 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
1138 SILC_LOG_DEBUG(("Old Client ID id(%s)",
1139 silc_id_render(client_id, SILC_ID_CLIENT)));
1140 SILC_LOG_DEBUG(("New Client ID id(%s)",
1141 silc_id_render(client_id2, SILC_ID_CLIENT)));
1143 /* Replace the Client ID */
1144 client = silc_idlist_replace_client_id(server->global_list, client_id,
1147 client = silc_idlist_replace_client_id(server->local_list, client_id,
1151 /* Send the NICK_CHANGE notify type to local clients on the channels
1152 this client is joined to. */
1153 silc_server_send_notify_on_channels(server, client,
1154 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
1158 silc_free(client_id);
1160 silc_free(client_id2);
1163 case SILC_NOTIFY_TYPE_TOPIC_SET:
1165 * Distribute the notify to local clients on the channel
1167 SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
1170 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1172 * Distribute the notify to local clients on the channel
1174 SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
1177 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1179 * Distribute the notify to local clients on the channel
1181 SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
1184 /* Ignore rest notify types for now */
1185 case SILC_NOTIFY_TYPE_NONE:
1186 case SILC_NOTIFY_TYPE_INVITE:
1187 case SILC_NOTIFY_TYPE_MOTD:
1193 silc_notify_payload_free(payload);
1196 /* Received new channel user packet. Information about new users on a
1197 channel are distributed between routers using this packet. The
1198 router receiving this will redistribute it and also sent JOIN notify
1199 to local clients on the same channel. Normal server sends JOIN notify
1200 to its local clients on the channel. */
1202 void silc_server_new_channel_user(SilcServer server,
1203 SilcSocketConnection sock,
1204 SilcPacketContext *packet)
1206 unsigned char *tmpid1, *tmpid2;
1207 SilcClientID *client_id = NULL;
1208 SilcChannelID *channel_id = NULL;
1209 unsigned short channel_id_len;
1210 unsigned short client_id_len;
1211 SilcClientEntry client;
1212 SilcChannelEntry channel;
1213 SilcChannelClientEntry chl;
1217 SILC_LOG_DEBUG(("Start"));
1219 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1220 server->server_type != SILC_ROUTER ||
1221 packet->src_id_type != SILC_ID_SERVER)
1225 ret = silc_buffer_unformat(packet->buffer,
1226 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1228 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1239 /* Decode the channel ID */
1240 channel_id = silc_id_str2id(tmpid1, channel_id_len, SILC_ID_CHANNEL);
1244 /* Decode the client ID */
1245 client_id = silc_id_str2id(tmpid2, client_id_len, SILC_ID_CLIENT);
1249 /* Find the channel */
1250 channel = silc_idlist_find_channel_by_id(server->local_list,
1253 channel = silc_idlist_find_channel_by_id(server->global_list,
1259 /* If we are router and this packet is not already broadcast packet
1260 we will broadcast it. */
1261 if (!server->standalone && server->server_type == SILC_ROUTER &&
1262 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1263 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1264 silc_server_packet_send(server, server->router->connection, packet->type,
1265 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1266 packet->buffer->data, packet->buffer->len, FALSE);
1269 /* Get client entry */
1270 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1272 client = silc_idlist_find_client_by_id(server->global_list,
1278 /* Join the client to the channel by adding it to channel's user list.
1279 Add also the channel to client entry's channels list for fast cross-
1281 chl = silc_calloc(1, sizeof(*chl));
1282 chl->client = client;
1283 chl->channel = channel;
1284 silc_list_add(channel->user_list, chl);
1285 silc_list_add(client->channels, chl);
1287 server->stat.chanclients++;
1289 /* Send JOIN notify to local clients on the channel. As we are router
1290 it is assured that this is sent only to our local clients and locally
1291 connected servers if needed. */
1292 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1293 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1294 SILC_NOTIFY_TYPE_JOIN,
1295 1, clidp->data, clidp->len);
1296 silc_buffer_free(clidp);
1302 silc_free(client_id);
1304 silc_free(channel_id);
1309 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1310 that certain ID should be removed. After that the ID will become invalid. */
1312 void silc_server_remove_id(SilcServer server,
1313 SilcSocketConnection sock,
1314 SilcPacketContext *packet)
1319 void *id, *id_entry;
1321 SILC_LOG_DEBUG(("Start"));
1323 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1324 server->server_type == SILC_SERVER ||
1325 packet->src_id_type != SILC_ID_SERVER)
1328 idp = silc_id_payload_parse(packet->buffer);
1332 id_type = silc_id_payload_get_type(idp);
1334 id = silc_id_payload_get_id(idp);
1338 /* If the sender of this packet is server and we are router we need to
1339 broadcast this packet to other routers in the network. */
1340 if (!server->standalone && server->server_type == SILC_ROUTER &&
1341 sock->type == SILC_SOCKET_TYPE_SERVER &&
1342 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1343 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1344 silc_server_packet_send(server, server->router->connection,
1346 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1347 packet->buffer->data, packet->buffer->len, FALSE);
1350 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1351 id_list = server->local_list;
1353 id_list = server->global_list;
1357 case SILC_ID_CLIENT:
1358 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1361 /* Remove from channels */
1362 silc_server_remove_from_channels(server, NULL, id_entry);
1364 /* Remove the client entry */
1365 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1366 server->stat.clients--;
1367 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1368 server->server_type == SILC_ROUTER)
1369 server->stat.cell_clients--;
1371 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1372 silc_id_render(id, SILC_ID_CLIENT),
1373 sock->type == SILC_SOCKET_TYPE_SERVER ?
1374 "Server" : "Router", sock->hostname));
1378 case SILC_ID_SERVER:
1379 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1382 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1383 server->stat.servers--;
1384 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1385 server->server_type == SILC_ROUTER)
1386 server->stat.cell_servers--;
1388 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1389 silc_id_render(id, SILC_ID_SERVER),
1390 sock->type == SILC_SOCKET_TYPE_SERVER ?
1391 "Server" : "Router", sock->hostname));
1395 case SILC_ID_CHANNEL:
1396 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1399 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1400 server->stat.channels--;
1401 if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1402 server->server_type == SILC_ROUTER)
1403 server->stat.cell_channels--;
1405 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1406 silc_id_render(id, SILC_ID_CHANNEL),
1407 sock->type == SILC_SOCKET_TYPE_SERVER ?
1408 "Server" : "Router", sock->hostname));
1417 silc_id_payload_free(idp);
1420 /* Processes received SET_MODE packet. The packet is used to distribute
1421 the information about changed channel's or client's channel modes. */
1423 void silc_server_set_mode(SilcServer server,
1424 SilcSocketConnection sock,
1425 SilcPacketContext *packet)
1427 SilcSetModePayload payload = NULL;
1428 SilcArgumentPayload args = NULL;
1429 unsigned short mode_type;
1430 unsigned int mode_mask;
1431 unsigned char *tmp, *tmp2;
1432 unsigned int tmp_len, tmp_len2;
1433 unsigned char mode[4];
1434 SilcClientID *client_id;
1435 SilcChannelID *channel_id = NULL;
1436 SilcClientEntry client;
1437 SilcChannelEntry channel;
1438 SilcChannelClientEntry chl;
1440 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1441 packet->src_id_type == SILC_ID_CLIENT)
1444 SILC_LOG_DEBUG(("Start"));
1446 /* If we are router and this packet is not already broadcast packet
1447 we will broadcast it. The sending socket really cannot be router or
1448 the router is buggy. If this packet is coming from router then it must
1449 have the broadcast flag set already and we won't do anything. */
1450 if (!server->standalone && server->server_type == SILC_ROUTER &&
1451 sock->type == SILC_SOCKET_TYPE_SERVER &&
1452 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1453 SILC_LOG_DEBUG(("Broadcasting received Set Mode packet"));
1454 silc_server_packet_send(server, server->router->connection, packet->type,
1455 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1456 packet->buffer->data, packet->buffer->len, FALSE);
1459 /* Parse Set Mode payload */
1460 payload = silc_set_mode_payload_parse(packet->buffer);
1464 mode_type = silc_set_mode_get_type(payload);
1465 args = silc_set_mode_get_args(payload);
1469 mode_mask = silc_set_mode_get_mode(payload);
1470 SILC_PUT32_MSB(mode_mask, mode);
1472 switch (mode_type) {
1473 case SILC_MODE_TYPE_CHANNEL:
1474 /* Get Channel ID */
1475 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1478 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1482 /* Get channel entry */
1483 channel = silc_idlist_find_channel_by_id(server->local_list,
1486 channel = silc_idlist_find_channel_by_id(server->global_list,
1492 /* Get Client ID payload */
1493 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1497 /* Send CMODE_CHANGE notify to local channel */
1498 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1499 SILC_NOTIFY_TYPE_CMODE_CHANGE,
1501 mode, sizeof(mode));
1503 /* Change the mode */
1504 channel->mode = mode_mask;
1507 case SILC_MODE_TYPE_UCHANNEL:
1508 /* Get Channel ID */
1509 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1512 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1516 /* Get channel entry */
1517 channel = silc_idlist_find_channel_by_id(server->local_list,
1520 channel = silc_idlist_find_channel_by_id(server->global_list,
1526 /* Get Client ID payload */
1527 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1531 /* Get target Client ID */
1532 tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2);
1535 client_id = silc_id_payload_parse_id(tmp2, tmp_len2);
1539 /* Get target client entry */
1540 client = silc_idlist_find_client_by_id(server->global_list,
1543 client = silc_idlist_find_client_by_id(server->local_list,
1546 silc_free(client_id);
1550 silc_free(client_id);
1552 /* Send CUMODE_CHANGE notify to local channel */
1553 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1554 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2,
1559 /* Get entry to the channel user list */
1560 silc_list_start(channel->user_list);
1561 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
1562 if (chl->client == client) {
1563 /* Change the mode */
1564 chl->mode = mode_mask;
1576 silc_free(channel_id);
1578 silc_argument_payload_free(args);
1580 silc_set_mode_payload_free(payload);