5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 extern char *server_version;
30 /* Received private message. This resolves the destination of the message
31 and sends the packet. This is used by both server and router. If the
32 destination is our locally connected client this sends the packet to
33 the client. This may also send the message for further routing if
34 the destination is not in our server (or router). */
36 void silc_server_private_message(SilcServer server,
37 SilcSocketConnection sock,
38 SilcPacketContext *packet)
41 SilcServerEntry router;
42 SilcSocketConnection dst_sock;
43 SilcClientEntry client;
46 SILC_LOG_DEBUG(("Start"));
51 /* Decode destination Client ID */
52 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
54 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
58 /* If the destination belongs to our server we don't have to route
59 the message anywhere but to send it to the local destination. */
60 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
62 /* It exists, now deliver the message to the destination */
63 dst_sock = (SilcSocketConnection)client->connection;
65 /* If we are router and the client has router then the client is in
66 our cell but not directly connected to us. */
67 if (server->server_type == SILC_ROUTER && client->router) {
68 /* We are of course in this case the client's router thus the real
69 "router" of the client is the server who owns the client. Thus
70 we will send the packet to that server. */
71 router = (SilcServerEntry)dst_sock->user_data;
72 idata = (SilcIDListData)router;
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, SILC_ID_CLIENT);
156 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
158 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
164 if (packet->dst_id_type == SILC_ID_SERVER) {
165 /* For now this must be for us */
166 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
167 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
172 /* Execute command reply locally for the command */
173 silc_server_command_reply_process(server, sock, buffer);
175 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
176 /* Relay the packet to the client */
178 dst_sock = (SilcSocketConnection)client->connection;
179 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
180 + packet->dst_id_len + packet->padlen);
182 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
183 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
185 idata = (SilcIDListData)client;
188 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
191 /* Send the packet */
192 silc_server_packet_send_real(server, dst_sock, TRUE);
198 /* Process received channel message. The message can be originated from
201 void silc_server_channel_message(SilcServer server,
202 SilcSocketConnection sock,
203 SilcPacketContext *packet)
205 SilcChannelEntry channel = NULL;
206 SilcChannelClientEntry chl;
207 SilcChannelID *id = NULL;
210 SILC_LOG_DEBUG(("Processing channel message"));
213 if (packet->dst_id_type != SILC_ID_CHANNEL) {
214 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
218 /* Find channel entry */
219 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
220 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
222 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
224 SILC_LOG_DEBUG(("Could not find channel"));
229 /* See that this client is on the channel. If the message is coming
230 from router we won't do the check as the message is from client that
231 we don't know about. Also, if the original sender is not client
232 (as it can be server as well) we don't do the check. */
233 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
234 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
235 packet->src_id_type == SILC_ID_CLIENT) {
236 silc_list_start(channel->user_list);
237 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
238 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
241 if (chl == SILC_LIST_END)
245 /* Distribute the packet to our local clients. This will send the
246 packet for further routing as well, if needed. */
247 silc_server_packet_relay_to_channel(server, sock, channel, sender,
249 packet->buffer->data,
250 packet->buffer->len, FALSE);
259 /* Received channel key packet. We distribute the key to all of our locally
260 connected clients on the channel. */
262 void silc_server_channel_key(SilcServer server,
263 SilcSocketConnection sock,
264 SilcPacketContext *packet)
266 SilcBuffer buffer = packet->buffer;
267 SilcChannelEntry channel;
269 if (packet->src_id_type != SILC_ID_SERVER)
272 /* Save the channel key */
273 channel = silc_server_save_channel_key(server, buffer, NULL);
277 /* Distribute the key to everybody who is on the channel. If we are router
278 we will also send it to locally connected servers. */
279 silc_server_send_channel_key(server, sock, channel, FALSE);
282 /* Received packet to replace a ID. This checks that the requested ID
283 exists and replaces it with the new one. */
285 void silc_server_replace_id(SilcServer server,
286 SilcSocketConnection sock,
287 SilcPacketContext *packet)
289 SilcBuffer buffer = packet->buffer;
290 unsigned char *old_id = NULL, *new_id = NULL;
291 SilcIdType old_id_type, new_id_type;
292 unsigned short old_id_len, new_id_len;
293 void *id = NULL, *id2 = NULL;
295 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
296 packet->src_id_type == SILC_ID_CLIENT)
299 SILC_LOG_DEBUG(("Replacing ID"));
301 silc_buffer_unformat(buffer,
302 SILC_STR_UI_SHORT(&old_id_type),
303 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
304 SILC_STR_UI_SHORT(&new_id_type),
305 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
308 if (old_id_type != new_id_type)
311 if (old_id_len != silc_id_get_len(old_id_type) ||
312 new_id_len != silc_id_get_len(new_id_type))
315 id = silc_id_str2id(old_id, old_id_type);
319 id2 = silc_id_str2id(new_id, new_id_type);
323 /* If we are router and this packet is not already broadcast packet
324 we will broadcast it. The sending socket really cannot be router or
325 the router is buggy. If this packet is coming from router then it must
326 have the broadcast flag set already and we won't do anything. */
327 if (!server->standalone && server->server_type == SILC_ROUTER &&
328 sock->type == SILC_SOCKET_TYPE_SERVER &&
329 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
330 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
331 silc_server_packet_send(server, server->router->connection, packet->type,
332 packet->flags | SILC_PACKET_FLAG_BROADCAST,
333 buffer->data, buffer->len, FALSE);
336 /* Replace the old ID */
337 switch(old_id_type) {
339 SILC_LOG_DEBUG(("Old Client ID id(%s)",
340 silc_id_render(id, SILC_ID_CLIENT)));
341 SILC_LOG_DEBUG(("New Client ID id(%s)",
342 silc_id_render(id2, SILC_ID_CLIENT)));
343 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
344 if (server->server_type == SILC_ROUTER)
345 silc_idlist_replace_client_id(server->global_list, id, id2);
349 SILC_LOG_DEBUG(("Old Server ID id(%s)",
350 silc_id_render(id, SILC_ID_CLIENT)));
351 SILC_LOG_DEBUG(("New Server ID id(%s)",
352 silc_id_render(id2, SILC_ID_CLIENT)));
353 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
354 if (server->server_type == SILC_ROUTER)
355 silc_idlist_replace_server_id(server->global_list, id, id2);
358 case SILC_ID_CHANNEL:
359 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
379 /* Received New Client packet and processes it. Creates Client ID for the
380 client. Client becomes registered after calling this functions. */
382 SilcClientEntry silc_server_new_client(SilcServer server,
383 SilcSocketConnection sock,
384 SilcPacketContext *packet)
386 SilcBuffer buffer = packet->buffer;
387 SilcClientEntry client;
388 SilcIDCacheEntry cache;
389 SilcClientID *client_id;
391 SilcIDListData idata;
392 char *username = NULL, *realname = NULL, *id_string;
394 SILC_LOG_DEBUG(("Creating new client"));
396 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
399 /* Take client entry */
400 client = (SilcClientEntry)sock->user_data;
401 idata = (SilcIDListData)client;
403 /* Fetch the old client cache entry so that we can update it. */
404 if (!silc_idcache_find_by_context(server->local_list->clients,
405 sock->user_data, &cache)) {
406 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
410 /* Parse incoming packet */
411 silc_buffer_unformat(buffer,
412 SILC_STR_UI16_STRING_ALLOC(&username),
413 SILC_STR_UI16_STRING_ALLOC(&realname),
416 /* Create Client ID */
417 silc_id_create_client_id(server->id, server->rng, server->md5hash,
418 username, &client_id);
420 /* Update client entry */
421 idata->registered = TRUE;
422 client->nickname = strdup(username);
423 client->username = username;
424 client->userinfo = realname;
425 client->id = client_id;
427 /* Update the cache entry */
428 cache->id = (void *)client_id;
429 cache->type = SILC_ID_CLIENT;
430 cache->data = username;
431 silc_idcache_sort_by_data(server->local_list->clients);
433 /* Notify our router about new client on the SILC network */
434 if (!server->standalone)
435 silc_server_send_new_id(server, (SilcSocketConnection)
436 server->router->connection,
437 server->server_type == SILC_ROUTER ? TRUE : FALSE,
438 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
440 /* Send the new client ID to the client. */
441 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
442 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
443 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
444 silc_buffer_format(reply,
445 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
446 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
447 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
449 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
450 reply->data, reply->len, FALSE);
451 silc_free(id_string);
452 silc_buffer_free(reply);
454 /* Send some nice info to the client */
455 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
456 ("Welcome to the SILC Network %s@%s",
457 username, sock->hostname));
458 if (server->server_type == SILC_ROUTER) {
459 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
460 ("There are %d clients on %d servers in SILC "
461 "Network", server->stat.clients,
462 server->stat.servers));
463 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
464 ("There are %d clients on %d server in our cell",
465 server->stat.cell_clients,
466 server->stat.cell_servers));
467 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
468 ("I have %d clients, %d channels, %d servers and "
470 server->stat.my_clients,
471 server->stat.my_channels,
472 server->stat.my_servers,
473 server->stat.my_routers));
474 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
475 ("%d server operators and %d router operators "
477 server->stat.my_server_ops,
478 server->stat.my_router_ops));
480 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
481 ("I have %d clients and %d channels formed",
482 server->stat.my_clients,
483 server->stat.my_channels));
484 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
485 ("%d operators online",
486 server->stat.my_server_ops));
488 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
489 ("Your host is %s, running version %s",
490 server->config->server_info->server_name,
492 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
493 ("Your connection is secured with %s cipher, "
494 "key length %d bits",
495 idata->send_key->cipher->name,
496 idata->send_key->cipher->key_len));
497 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
498 ("Your current nickname is %s",
502 silc_server_send_motd(server, sock);
507 /* Create new server. This processes received New Server packet and
508 saves the received Server ID. The server is our locally connected
509 server thus we save all the information and save it to local list.
510 This funtion can be used by both normal server and router server.
511 If normal server uses this it means that its router has connected
512 to the server. If router uses this it means that one of the cell's
513 servers is connected to the router. */
515 SilcServerEntry silc_server_new_server(SilcServer server,
516 SilcSocketConnection sock,
517 SilcPacketContext *packet)
519 SilcBuffer buffer = packet->buffer;
520 SilcServerEntry new_server;
521 SilcIDCacheEntry cache;
522 SilcServerID *server_id;
523 SilcIDListData idata;
524 unsigned char *server_name, *id_string;
525 unsigned short id_len;
527 SILC_LOG_DEBUG(("Creating new server"));
529 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
530 sock->type != SILC_SOCKET_TYPE_ROUTER)
533 /* Take server entry */
534 new_server = (SilcServerEntry)sock->user_data;
535 idata = (SilcIDListData)new_server;
537 /* Fetch the old server cache entry so that we can update it. */
538 if (!silc_idcache_find_by_context(server->local_list->servers,
539 sock->user_data, &cache)) {
540 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
544 /* Parse the incoming packet */
545 silc_buffer_unformat(buffer,
546 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
547 SILC_STR_UI16_STRING_ALLOC(&server_name),
550 if (id_len > buffer->len) {
551 silc_free(id_string);
552 silc_free(server_name);
557 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
558 silc_free(id_string);
560 /* Update client entry */
561 idata->registered = TRUE;
562 new_server->server_name = server_name;
563 new_server->id = server_id;
565 /* Update the cache entry */
566 cache->id = (void *)server_id;
567 cache->type = SILC_ID_SERVER;
568 cache->data = server_name;
569 silc_idcache_sort_by_data(server->local_list->servers);
571 /* Distribute the information about new server in the SILC network
572 to our router. If we are normal server we won't send anything
573 since this connection must be our router connection. */
574 if (server->server_type == SILC_ROUTER && !server->standalone &&
575 server->router->connection != sock)
576 silc_server_send_new_id(server, server->router->connection,
577 TRUE, new_server->id, SILC_ID_SERVER,
580 if (server->server_type == SILC_ROUTER)
581 server->stat.cell_servers++;
586 /* Processes incoming New ID packet. New ID Payload is used to distribute
587 information about newly registered clients and servers. */
589 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
590 SilcPacketContext *packet)
592 SilcBuffer buffer = packet->buffer;
594 SilcServerEntry router;
595 SilcSocketConnection router_sock;
598 unsigned char *hash = NULL;
601 SILC_LOG_DEBUG(("Processing new ID"));
603 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
604 server->server_type == SILC_SERVER ||
605 packet->src_id_type != SILC_ID_SERVER)
608 idp = silc_id_payload_parse(buffer);
612 id_type = silc_id_payload_get_type(idp);
614 /* Normal server cannot have other normal server connections */
615 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
618 id = silc_id_payload_get_id(idp);
622 /* If the sender of this packet is server and we are router we need to
623 broadcast this packet to other routers in the network. */
624 if (!server->standalone && server->server_type == SILC_ROUTER &&
625 sock->type == SILC_SOCKET_TYPE_SERVER &&
626 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
627 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
628 silc_server_packet_send(server, server->router->connection,
630 packet->flags | SILC_PACKET_FLAG_BROADCAST,
631 buffer->data, buffer->len, FALSE);
634 if (sock->type == SILC_SOCKET_TYPE_SERVER)
635 id_list = server->local_list;
637 id_list = server->global_list;
640 router = sock->user_data;
645 SilcClientEntry entry;
647 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
648 silc_id_render(id, SILC_ID_CLIENT),
649 sock->type == SILC_SOCKET_TYPE_SERVER ?
650 "Server" : "Router", sock->hostname));
652 /* As a router we keep information of all global information in our
653 global list. Cell wide information however is kept in the local
654 list. The client is put to global list and we will take the hash
655 value of the Client ID and save it to the ID Cache system for fast
656 searching in the future. */
657 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
658 sizeof(unsigned char));
659 memcpy(hash, ((SilcClientID *)id)->hash,
660 sizeof(((SilcClientID *)id)->hash));
661 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
662 router, router_sock);
663 entry->nickname = NULL;
665 if (sock->type == SILC_SOCKET_TYPE_SERVER)
666 server->stat.cell_clients++;
667 server->stat.clients++;
670 /* XXX Adding two ID's with same IP number replaces the old entry thus
671 gives wrong route. Thus, now disabled until figured out a better way
672 to do this or when removed the whole thing. This could be removed
673 because entry->router->connection gives always the most optimal route
674 for the ID anyway (unless new routes (faster perhaps) are established
675 after receiving this ID, this we don't know however). */
676 /* Add route cache for this ID */
677 silc_server_route_add(silc_server_route_hash(
678 ((SilcClientID *)id)->ip.s_addr,
679 server->id->port), ((SilcClientID *)id)->ip.s_addr,
686 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
687 silc_id_render(id, SILC_ID_SERVER),
688 sock->type == SILC_SOCKET_TYPE_SERVER ?
689 "Server" : "Router", sock->hostname));
691 /* As a router we keep information of all global information in our global
692 list. Cell wide information however is kept in the local list. */
693 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
695 if (sock->type == SILC_SOCKET_TYPE_SERVER)
696 server->stat.cell_servers++;
697 server->stat.servers++;
700 /* Add route cache for this ID */
701 silc_server_route_add(silc_server_route_hash(
702 ((SilcServerID *)id)->ip.s_addr,
703 ((SilcServerID *)id)->port),
704 ((SilcServerID *)id)->ip.s_addr,
709 case SILC_ID_CHANNEL:
710 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
718 silc_id_payload_free(idp);
721 /* Received Remove Channel User packet to remove a user from a channel.
722 Routers notify other routers that user has left a channel. Client must
723 not send this packet. Normal server may send this packet but must not
726 void silc_server_remove_channel_user(SilcServer server,
727 SilcSocketConnection sock,
728 SilcPacketContext *packet)
730 SilcBuffer buffer = packet->buffer;
731 unsigned char *tmp1 = NULL, *tmp2 = NULL;
732 SilcClientID *client_id = NULL;
733 SilcChannelID *channel_id = NULL;
734 SilcChannelEntry channel;
735 SilcClientEntry client;
737 SILC_LOG_DEBUG(("Removing user from channel"));
739 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
740 server->server_type == SILC_SERVER)
743 silc_buffer_unformat(buffer,
744 SILC_STR_UI16_STRING_ALLOC(&tmp1),
745 SILC_STR_UI16_STRING_ALLOC(&tmp2),
751 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
752 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
753 if (!client_id || !channel_id)
756 /* If we are router and this packet is not already broadcast packet
757 we will broadcast it. The sending socket really cannot be router or
758 the router is buggy. If this packet is coming from router then it must
759 have the broadcast flag set already and we won't do anything. */
760 if (!server->standalone && server->server_type == SILC_ROUTER &&
761 sock->type == SILC_SOCKET_TYPE_SERVER &&
762 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
763 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
764 silc_server_packet_send(server, server->router->connection, packet->type,
765 packet->flags | SILC_PACKET_FLAG_BROADCAST,
766 buffer->data, buffer->len, FALSE);
769 /* Get channel entry */
770 channel = silc_idlist_find_channel_by_id(server->local_list,
773 channel = silc_idlist_find_channel_by_id(server->global_list,
779 /* Get client entry */
780 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
782 client = silc_idlist_find_client_by_id(server->global_list,
788 /* Remove user from channel */
789 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
797 silc_free(client_id);
799 silc_free(channel_id);
802 /* Received New Channel packet. Information about new channels in the
803 network are distributed using this packet. Save the information about
806 void silc_server_new_channel(SilcServer server,
807 SilcSocketConnection sock,
808 SilcPacketContext *packet)
811 SilcChannelID *channel_id;
812 unsigned short channel_id_len;
815 SILC_LOG_DEBUG(("Processing New Channel"));
817 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
818 server->server_type == SILC_SERVER ||
819 packet->src_id_type != SILC_ID_SERVER)
823 if (!silc_buffer_unformat(packet->buffer,
824 SILC_STR_UI16_STRING_ALLOC(&channel_name),
825 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
829 if (!channel_name || !id)
832 /* Decode the channel ID */
833 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
838 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
839 silc_id_render(channel_id, SILC_ID_CHANNEL),
842 /* Add the new channel. Add it always to global list since if we receive
843 this packet then it cannot be created by ourselves but some other
844 router hence global channel. */
845 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
846 server->router->connection, NULL);
848 server->stat.channels++;
851 /* Received notify packet. Server can receive notify packets from router.
852 Server then relays the notify messages to clients if needed. */
854 void silc_server_notify(SilcServer server,
855 SilcSocketConnection sock,
856 SilcPacketContext *packet)
858 SilcNotifyPayload payload;
860 SilcArgumentPayload args;
861 SilcChannelID *channel_id;
862 SilcClientID *client_id;
863 SilcChannelEntry channel;
864 SilcClientEntry client;
866 unsigned int tmp_len;
868 SILC_LOG_DEBUG(("Start"));
870 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
871 packet->src_id_type != SILC_ID_SERVER)
874 /* XXX: For now we expect that the we are normal server and that the
875 sender is router. Server could send (protocol allows it) notify to
876 router but we don't support it yet. */
877 if (server->server_type != SILC_SERVER &&
878 sock->type != SILC_SOCKET_TYPE_ROUTER)
881 payload = silc_notify_payload_parse(packet->buffer);
885 type = silc_notify_get_type(payload);
886 args = silc_notify_get_args(payload);
891 case SILC_NOTIFY_TYPE_JOIN:
893 * Distribute the notify to local clients on the channel
895 SILC_LOG_DEBUG(("JOIN notify"));
897 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
901 /* Get channel entry */
902 channel = silc_idlist_find_channel_by_id(server->local_list,
905 silc_free(channel_id);
910 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
912 silc_free(channel_id);
915 client_id = silc_id_payload_parse_id(tmp, tmp_len);
917 /* Send to channel */
918 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
919 FALSE, packet->buffer->data,
920 packet->buffer->len, FALSE);
922 /* If the the client is not in local list we check global list (ie. the
923 channel will be global channel) and if it does not exist then create
924 entry for the client. */
925 client = silc_idlist_find_client_by_id(server->local_list,
928 SilcChannelClientEntry chl;
930 client = silc_idlist_find_client_by_id(server->global_list,
933 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
934 client_id, sock->user_data, sock);
936 /* The channel is global now */
937 channel->global_users = TRUE;
939 /* Now actually JOIN the global client to the channel */
940 chl = silc_calloc(1, sizeof(*chl));
941 chl->client = client;
942 chl->channel = channel;
943 silc_list_add(channel->user_list, chl);
944 silc_list_add(client->channels, chl);
946 silc_free(client_id);
950 case SILC_NOTIFY_TYPE_LEAVE:
952 * Distribute the notify to local clients on the channel
954 SILC_LOG_DEBUG(("LEAVE notify"));
956 channel_id = silc_id_str2id(packet->dst_id, 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 /* Send to channel */
977 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
978 FALSE, packet->buffer->data,
979 packet->buffer->len, FALSE);
981 /* Get client entry */
982 client = silc_idlist_find_client_by_id(server->global_list,
985 client = silc_idlist_find_client_by_id(server->local_list,
988 silc_free(channel_id);
992 silc_free(client_id);
994 /* Remove the user from channel */
995 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
998 case SILC_NOTIFY_TYPE_SIGNOFF:
1000 * Distribute the notify to local clients on the channel
1002 SILC_LOG_DEBUG(("SIGNOFF notify"));
1005 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1008 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1010 /* Get client entry */
1011 client = silc_idlist_find_client_by_id(server->global_list,
1014 client = silc_idlist_find_client_by_id(server->local_list,
1019 silc_free(client_id);
1021 /* Remove the client from all channels */
1022 silc_server_remove_from_channels(server, NULL, client);
1024 /* Remove the client entry */
1025 silc_idlist_del_client(server->global_list, client);
1028 /* Ignore rest notify types for now */
1029 case SILC_NOTIFY_TYPE_NONE:
1030 case SILC_NOTIFY_TYPE_INVITE:
1031 case SILC_NOTIFY_TYPE_TOPIC_SET:
1032 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1033 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1034 case SILC_NOTIFY_TYPE_MOTD:
1040 silc_notify_payload_free(payload);
1043 /* Received new channel user packet. Information about new users on a
1044 channel are distributed between routers using this packet. The
1045 router receiving this will redistribute it and also sent JOIN notify
1046 to local clients on the same channel. Normal server sends JOIN notify
1047 to its local clients on the channel. */
1049 void silc_server_new_channel_user(SilcServer server,
1050 SilcSocketConnection sock,
1051 SilcPacketContext *packet)
1053 unsigned char *tmpid1, *tmpid2;
1054 SilcClientID *client_id = NULL;
1055 SilcChannelID *channel_id = NULL;
1056 unsigned short channel_id_len;
1057 unsigned short client_id_len;
1058 SilcClientEntry client;
1059 SilcChannelEntry channel;
1060 SilcChannelClientEntry chl;
1063 SILC_LOG_DEBUG(("Start"));
1065 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1066 server->server_type != SILC_ROUTER ||
1067 packet->src_id_type != SILC_ID_SERVER)
1071 if (!silc_buffer_unformat(packet->buffer,
1072 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1074 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1079 if (!tmpid1 || !tmpid2)
1082 /* Decode the channel ID */
1083 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
1087 /* Decode the client ID */
1088 client_id = silc_id_str2id(tmpid2, SILC_ID_CLIENT);
1092 /* Find the channel */
1093 channel = silc_idlist_find_channel_by_id(server->local_list,
1096 channel = silc_idlist_find_channel_by_id(server->global_list,
1102 /* If we are router and this packet is not already broadcast packet
1103 we will broadcast it. */
1104 if (!server->standalone && server->server_type == SILC_ROUTER &&
1105 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1106 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1107 silc_server_packet_send(server, server->router->connection, packet->type,
1108 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1109 packet->buffer->data, packet->buffer->len, FALSE);
1112 /* Get client entry */
1113 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1115 client = silc_idlist_find_client_by_id(server->global_list,
1121 /* Join the client to the channel by adding it to channel's user list.
1122 Add also the channel to client entry's channels list for fast cross-
1124 chl = silc_calloc(1, sizeof(*chl));
1125 chl->client = client;
1126 chl->channel = channel;
1127 silc_list_add(channel->user_list, chl);
1128 silc_list_add(client->channels, chl);
1130 server->stat.chanclients++;
1132 /* Send JOIN notify to local clients on the channel. As we are router
1133 it is assured that this is sent only to our local clients and locally
1134 connected servers if needed. */
1135 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1136 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1137 SILC_NOTIFY_TYPE_JOIN,
1138 1, clidp->data, clidp->len);
1139 silc_buffer_free(clidp);
1145 silc_free(client_id);
1147 silc_free(channel_id);
1152 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1153 that certain ID should be removed. After that the ID will become invalid. */
1155 void silc_server_remove_id(SilcServer server,
1156 SilcSocketConnection sock,
1157 SilcPacketContext *packet)
1162 void *id, *id_entry;
1164 SILC_LOG_DEBUG(("Start"));
1166 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1167 server->server_type == SILC_SERVER ||
1168 packet->src_id_type != SILC_ID_SERVER)
1171 idp = silc_id_payload_parse(packet->buffer);
1175 id_type = silc_id_payload_get_type(idp);
1177 id = silc_id_payload_get_id(idp);
1181 /* If the sender of this packet is server and we are router we need to
1182 broadcast this packet to other routers in the network. */
1183 if (!server->standalone && server->server_type == SILC_ROUTER &&
1184 sock->type == SILC_SOCKET_TYPE_SERVER &&
1185 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1186 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1187 silc_server_packet_send(server, server->router->connection,
1189 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1190 packet->buffer->data, packet->buffer->len, FALSE);
1193 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1194 id_list = server->local_list;
1196 id_list = server->global_list;
1200 case SILC_ID_CLIENT:
1201 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1204 /* Remove from channels */
1205 silc_server_remove_from_channels(server, NULL, id_entry);
1207 /* Remove the client entry */
1208 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1209 server->stat.clients--;
1211 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1212 silc_id_render(id, SILC_ID_CLIENT),
1213 sock->type == SILC_SOCKET_TYPE_SERVER ?
1214 "Server" : "Router", sock->hostname));
1218 case SILC_ID_SERVER:
1219 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1222 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1223 server->stat.servers--;
1225 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1226 silc_id_render(id, SILC_ID_SERVER),
1227 sock->type == SILC_SOCKET_TYPE_SERVER ?
1228 "Server" : "Router", sock->hostname));
1232 case SILC_ID_CHANNEL:
1233 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1236 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1237 server->stat.channels--;
1239 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1240 silc_id_render(id, SILC_ID_CHANNEL),
1241 sock->type == SILC_SOCKET_TYPE_SERVER ?
1242 "Server" : "Router", sock->hostname));
1251 silc_id_payload_free(idp);