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"));
48 if (!packet->dst_id) {
49 SILC_LOG_ERROR(("Bad Client ID in private message packet, dropped"));
53 /* Decode destination Client ID */
54 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
56 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
60 /* If the destination belongs to our server we don't have to route
61 the message anywhere but to send it to the local destination. */
62 client = silc_idlist_find_client_by_id(server->local_list, id);
64 /* It exists, now deliver the message to the destination */
65 dst_sock = (SilcSocketConnection)client->connection;
67 /* If we are router and the client has router then the client is in
68 our cell but not directly connected to us. */
69 if (server->server_type == SILC_ROUTER && client->router) {
70 /* We are of course in this case the client's router thus the real
71 "router" of the client is the server who owns the client. Thus
72 we will send the packet to that server. */
73 router = (SilcServerEntry)dst_sock->user_data;
74 idata = (SilcIDListData)router;
75 // assert(client->router == server->id_entry);
77 silc_server_send_private_message(server, dst_sock,
84 /* Seems that client really is directly connected to us */
85 idata = (SilcIDListData)client;
86 silc_server_send_private_message(server, dst_sock,
92 /* Destination belongs to someone not in this server. If we are normal
93 server our action is to send the packet to our router. */
94 if (server->server_type == SILC_SERVER && !server->standalone) {
95 router = server->router;
97 /* Send to primary route */
99 dst_sock = (SilcSocketConnection)router->connection;
100 idata = (SilcIDListData)router;
101 silc_server_send_private_message(server, dst_sock,
103 idata->hmac, packet);
108 /* We are router and we will perform route lookup for the destination
109 and send the message to fastest route. */
110 if (server->server_type == SILC_ROUTER && !server->standalone) {
111 dst_sock = silc_server_get_route(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);
124 silc_server_send_error(server, sock,
125 "No such nickname: Private message not sent");
128 /* Relays received command reply packet to the correct destination. The
129 destination must be one of our locally connected client or the packet
130 will be ignored. This is called when server has forwarded one of
131 client's command request to router and router has now replied to the
134 void silc_server_packet_relay_command_reply(SilcServer server,
135 SilcSocketConnection sock,
136 SilcPacketContext *packet)
138 SilcBuffer buffer = packet->buffer;
139 SilcClientEntry client;
141 SilcSocketConnection dst_sock;
142 SilcIDListData idata;
144 SILC_LOG_DEBUG(("Start"));
146 /* Source must be server or router */
147 if (packet->src_id_type != SILC_ID_SERVER &&
148 sock->type != SILC_SOCKET_TYPE_ROUTER)
151 /* Destination must be client */
152 if (packet->dst_id_type != SILC_ID_CLIENT)
155 /* Execute command reply locally for the command */
156 silc_server_command_reply_process(server, sock, buffer);
158 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
160 /* Destination must be one of ours */
161 client = silc_idlist_find_client_by_id(server->local_list, id);
163 SILC_LOG_ERROR(("Cannot relay command reply to unknown client"));
168 /* Relay the packet to the client */
170 dst_sock = (SilcSocketConnection)client->connection;
171 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
172 + packet->dst_id_len + packet->padlen);
174 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
175 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
177 idata = (SilcIDListData)client;
180 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
183 /* Send the packet */
184 silc_server_packet_send_real(server, dst_sock, TRUE);
189 /* Process received channel message. The message can be originated from
192 void silc_server_channel_message(SilcServer server,
193 SilcSocketConnection sock,
194 SilcPacketContext *packet)
196 SilcChannelEntry channel = NULL;
197 SilcChannelClientEntry chl;
198 SilcChannelID *id = NULL;
201 SILC_LOG_DEBUG(("Processing channel message"));
204 if (packet->dst_id_type != SILC_ID_CHANNEL) {
205 SILC_LOG_ERROR(("Received bad message for channel, dropped"));
206 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
210 /* Find channel entry */
211 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
212 channel = silc_idlist_find_channel_by_id(server->local_list, id);
214 SILC_LOG_DEBUG(("Could not find channel"));
218 /* See that this client is on the channel. If the message is coming
219 from router we won't do the check as the message is from client that
220 we don't know about. Also, if the original sender is not client
221 (as it can be server as well) we don't do the check. */
222 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
223 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
224 packet->src_id_type == SILC_ID_CLIENT) {
225 silc_list_start(channel->user_list);
226 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
227 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
230 if (chl == SILC_LIST_END)
234 /* Distribute the packet to our local clients. This will send the
235 packet for further routing as well, if needed. */
236 silc_server_packet_relay_to_channel(server, sock, channel, sender,
238 packet->buffer->data,
239 packet->buffer->len, FALSE);
248 /* Received channel key packet. We distribute the key to all of our locally
249 connected clients on the channel. */
251 void silc_server_channel_key(SilcServer server,
252 SilcSocketConnection sock,
253 SilcPacketContext *packet)
255 SilcBuffer buffer = packet->buffer;
256 SilcChannelKeyPayload payload = NULL;
257 SilcChannelID *id = NULL;
258 SilcChannelEntry channel;
259 SilcChannelClientEntry chl;
261 unsigned int tmp_len;
265 if (packet->src_id_type != SILC_ID_SERVER)
268 /* Decode channel key payload */
269 payload = silc_channel_key_payload_parse(buffer);
271 SILC_LOG_ERROR(("Bad channel key payload, dropped"));
276 tmp = silc_channel_key_get_id(payload, &tmp_len);
277 id = silc_id_payload_parse_id(tmp, tmp_len);
281 /* Get the channel entry */
282 channel = silc_idlist_find_channel_by_id(server->local_list, id);
284 SILC_LOG_ERROR(("Received key for non-existent channel"));
288 tmp = silc_channel_key_get_key(payload, &tmp_len);
292 cipher = silc_channel_key_get_cipher(payload, NULL);;
296 /* Remove old key if exists */
298 memset(channel->key, 0, channel->key_len);
299 silc_free(channel_key);
300 silc_cipher_free(channel->channel_key);
304 /* Create new cipher */
305 if (!silc_cipher_alloc(cipher, &channel->channel_key))
309 channel->key_len = tmp_len * 8;
310 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
311 memcpy(channel->key, tmp, tmp_len);
312 channel->channel_key->cipher->set_key(channel->channel_key->context,
315 /* Distribute the key to everybody who is on the channel. If we are router
316 we will also send it to locally connected servers. If we are normal
317 server and old key did not exist then we don't use this function
318 as the client is not in our channel user list just yet. We send the
319 key after receiveing JOIN notify from router. */
320 if (server->server_type == SILC_SERVER && exist)
321 silc_server_send_channel_key(server, channel, FALSE);
322 if (server->server_type == SILC_ROUTER)
323 silc_server_send_channel_key(server, channel, FALSE);
329 silc_channel_key_payload_free(payload);
332 /* Received packet to replace a ID. This checks that the requested ID
333 exists and replaces it with the new one. */
335 void silc_server_replace_id(SilcServer server,
336 SilcSocketConnection sock,
337 SilcPacketContext *packet)
339 SilcBuffer buffer = packet->buffer;
340 unsigned char *old_id = NULL, *new_id = NULL;
341 SilcIdType old_id_type, new_id_type;
342 unsigned short old_id_len, new_id_len;
343 void *id = NULL, *id2 = NULL;
345 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
346 packet->src_id_type == SILC_ID_CLIENT)
349 SILC_LOG_DEBUG(("Replacing ID"));
351 silc_buffer_unformat(buffer,
352 SILC_STR_UI_SHORT(&old_id_type),
353 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
354 SILC_STR_UI_SHORT(&new_id_type),
355 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
358 if (old_id_type != new_id_type)
361 if (old_id_len != silc_id_get_len(old_id_type) ||
362 new_id_len != silc_id_get_len(new_id_type))
365 id = silc_id_str2id(old_id, old_id_type);
369 id2 = silc_id_str2id(new_id, new_id_type);
373 /* If we are router and this packet is not already broadcast packet
374 we will broadcast it. The sending socket really cannot be router or
375 the router is buggy. If this packet is coming from router then it must
376 have the broadcast flag set already and we won't do anything. */
377 if (server->server_type == SILC_ROUTER &&
378 sock->type == SILC_SOCKET_TYPE_SERVER &&
379 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
380 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
381 silc_server_packet_send(server, server->router->connection, packet->type,
382 packet->flags | SILC_PACKET_FLAG_BROADCAST,
383 buffer->data, buffer->len, FALSE);
386 /* Replace the old ID */
387 switch(old_id_type) {
389 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
390 if (server->server_type == SILC_ROUTER)
391 silc_idlist_replace_client_id(server->global_list, id, id2);
395 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
396 if (server->server_type == SILC_ROUTER)
397 silc_idlist_replace_server_id(server->global_list, id, id2);
400 case SILC_ID_CHANNEL:
401 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
421 /* Received New Client packet and processes it. Creates Client ID for the
422 client. Client becomes registered after calling this functions. */
424 SilcClientEntry silc_server_new_client(SilcServer server,
425 SilcSocketConnection sock,
426 SilcPacketContext *packet)
428 SilcBuffer buffer = packet->buffer;
429 SilcClientEntry client;
430 SilcIDCacheEntry cache;
431 SilcClientID *client_id;
433 SilcIDListData idata;
434 char *username = NULL, *realname = NULL, *id_string;
436 SILC_LOG_DEBUG(("Creating new client"));
438 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
441 /* Take client entry */
442 client = (SilcClientEntry)sock->user_data;
443 idata = (SilcIDListData)client;
445 /* Fetch the old client cache entry so that we can update it. */
446 if (!silc_idcache_find_by_context(server->local_list->clients,
447 sock->user_data, &cache)) {
448 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
452 /* Parse incoming packet */
453 silc_buffer_unformat(buffer,
454 SILC_STR_UI16_STRING_ALLOC(&username),
455 SILC_STR_UI16_STRING_ALLOC(&realname),
458 /* Create Client ID */
459 silc_id_create_client_id(server->id, server->rng, server->md5hash,
460 username, &client_id);
462 /* Update client entry */
463 idata->registered = TRUE;
464 client->nickname = strdup(username);
465 client->username = username;
466 client->userinfo = realname;
467 client->id = client_id;
469 /* Update the cache entry */
470 cache->id = (void *)client_id;
471 cache->type = SILC_ID_CLIENT;
472 cache->data = username;
473 silc_idcache_sort_by_data(server->local_list->clients);
475 /* Notify our router about new client on the SILC network */
476 if (!server->standalone)
477 silc_server_send_new_id(server, (SilcSocketConnection)
478 server->router->connection,
479 server->server_type == SILC_ROUTER ? TRUE : FALSE,
480 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
482 /* Send the new client ID to the client. */
483 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
484 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
485 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
486 silc_buffer_format(reply,
487 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
488 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
489 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
491 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
492 reply->data, reply->len, FALSE);
493 silc_free(id_string);
494 silc_buffer_free(reply);
496 /* Send some nice info to the client */
497 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
498 ("Welcome to the SILC Network %s@%s",
499 username, sock->hostname));
500 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
501 ("Your host is %s, running version %s",
502 server->config->server_info->server_name,
504 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
505 ("Your connection is secured with %s cipher, "
506 "key length %d bits",
507 idata->send_key->cipher->name,
508 idata->send_key->cipher->key_len));
509 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
510 ("Your current nickname is %s",
514 silc_server_send_motd(server, sock);
519 /* Create new server. This processes received New Server packet and
520 saves the received Server ID. The server is our locally connected
521 server thus we save all the information and save it to local list.
522 This funtion can be used by both normal server and router server.
523 If normal server uses this it means that its router has connected
524 to the server. If router uses this it means that one of the cell's
525 servers is connected to the router. */
527 SilcServerEntry silc_server_new_server(SilcServer server,
528 SilcSocketConnection sock,
529 SilcPacketContext *packet)
531 SilcBuffer buffer = packet->buffer;
532 SilcServerEntry new_server;
533 SilcIDCacheEntry cache;
534 SilcServerID *server_id;
535 SilcIDListData idata;
536 unsigned char *server_name, *id_string;
537 unsigned short id_len;
539 SILC_LOG_DEBUG(("Creating new server"));
541 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
542 sock->type != SILC_SOCKET_TYPE_ROUTER)
545 /* Take server entry */
546 new_server = (SilcServerEntry)sock->user_data;
547 idata = (SilcIDListData)new_server;
549 /* Fetch the old server cache entry so that we can update it. */
550 if (!silc_idcache_find_by_context(server->local_list->servers,
551 sock->user_data, &cache)) {
552 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
556 /* Parse the incoming packet */
557 silc_buffer_unformat(buffer,
558 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
559 SILC_STR_UI16_STRING_ALLOC(&server_name),
562 if (id_len > buffer->len) {
563 silc_free(id_string);
564 silc_free(server_name);
569 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
570 silc_free(id_string);
572 /* Update client entry */
573 idata->registered = TRUE;
574 new_server->server_name = server_name;
575 new_server->id = server_id;
577 /* Update the cache entry */
578 cache->id = (void *)server_id;
579 cache->type = SILC_ID_SERVER;
580 cache->data = server_name;
581 silc_idcache_sort_by_data(server->local_list->servers);
583 /* Distribute the information about new server in the SILC network
584 to our router. If we are normal server we won't send anything
585 since this connection must be our router connection. */
586 if (server->server_type == SILC_ROUTER && !server->standalone &&
587 server->router->connection != sock)
588 silc_server_send_new_id(server, server->router->connection,
589 TRUE, new_server->id, SILC_ID_SERVER,
595 /* Processes incoming New ID packet. New ID Payload is used to distribute
596 information about newly registered clients and servers. */
598 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
599 SilcPacketContext *packet)
601 SilcBuffer buffer = packet->buffer;
603 SilcServerEntry tmpserver, router;
604 SilcSocketConnection router_sock;
609 SILC_LOG_DEBUG(("Processing new ID"));
611 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
612 server->server_type == SILC_SERVER ||
613 packet->src_id_type != SILC_ID_SERVER)
616 idp = silc_id_payload_parse(buffer);
620 id_type = silc_id_payload_get_type(idp);
622 /* Normal server cannot have other normal server connections */
623 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
626 id = silc_id_payload_get_id(idp);
630 /* If the sender of this packet is server and we are router we need to
631 broadcast this packet to other routers in the network. */
632 if (!server->standalone && server->server_type == SILC_ROUTER &&
633 sock->type == SILC_SOCKET_TYPE_SERVER &&
634 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
635 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
636 silc_server_packet_send(server, server->router->connection,
638 packet->flags | SILC_PACKET_FLAG_BROADCAST,
639 buffer->data, buffer->len, FALSE);
642 /* If the packet is originated from the one who sent it to us we know
643 that the ID belongs to our cell, unless the sender was router. */
644 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
645 tmpserver = (SilcServerEntry)sock->user_data;
647 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
648 sock->type == SILC_SOCKET_TYPE_SERVER) {
649 id_list = server->local_list;
651 router = sock->user_data;
652 /* router = server->id_entry; */
654 id_list = server->global_list;
655 router_sock = (SilcSocketConnection)server->router->connection;
656 router = server->router;
664 SilcClientEntry idlist;
666 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
667 silc_id_render(id, SILC_ID_CLIENT),
668 sock->type == SILC_SOCKET_TYPE_SERVER ?
669 "Server" : "Router", sock->hostname));
671 /* Add the client to our local list. We are router and we keep
672 cell specific local database of all clients in the cell. */
673 idlist = silc_idlist_add_client(id_list, NULL, NULL, NULL,
674 id, router, router_sock);
680 SilcServerEntry idlist;
682 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
683 silc_id_render(id, SILC_ID_SERVER),
684 sock->type == SILC_SOCKET_TYPE_SERVER ?
685 "Server" : "Router", sock->hostname));
687 /* Add the server to our local list. We are router and we keep
688 cell specific local database of all servers in the cell. */
689 idlist = silc_idlist_add_server(id_list, NULL, 0, id, router,
694 case SILC_ID_CHANNEL:
695 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
697 SILC_LOG_DEBUG(("New channel id(%s) from [%s] %s",
698 silc_id_render(id, SILC_ID_CHANNEL),
699 sock->type == SILC_SOCKET_TYPE_SERVER ?
700 "Server" : "Router", sock->hostname));
702 /* Add the channel to our local list. We are router and we keep
703 cell specific local database of all channels in the cell. */
704 silc_idlist_add_channel(id_list, NULL, 0, id, router, NULL);
713 silc_id_payload_free(idp);
716 /* Received Remove Channel User packet to remove a user from a channel.
717 Routers notify other routers that user has left a channel. Client must
718 not send this packet.. Normal server may send this packet but must not
721 void silc_server_remove_channel_user(SilcServer server,
722 SilcSocketConnection sock,
723 SilcPacketContext *packet)
725 SilcBuffer buffer = packet->buffer;
726 unsigned char *tmp1 = NULL, *tmp2 = NULL;
727 SilcClientID *client_id = NULL;
728 SilcChannelID *channel_id = NULL;
729 SilcChannelEntry channel;
730 SilcClientEntry client;
732 SILC_LOG_DEBUG(("Removing user from channel"));
734 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
735 server->server_type == SILC_SERVER)
738 silc_buffer_unformat(buffer,
739 SILC_STR_UI16_STRING_ALLOC(&tmp1),
740 SILC_STR_UI16_STRING_ALLOC(&tmp2),
746 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
747 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
748 if (!client_id || !channel_id)
751 /* If we are router and this packet is not already broadcast packet
752 we will broadcast it. The sending socket really cannot be router or
753 the router is buggy. If this packet is coming from router then it must
754 have the broadcast flag set already and we won't do anything. */
755 if (!server->standalone && server->server_type == SILC_ROUTER &&
756 sock->type == SILC_SOCKET_TYPE_SERVER &&
757 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
758 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
759 silc_server_packet_send(server, server->router->connection, packet->type,
760 packet->flags | SILC_PACKET_FLAG_BROADCAST,
761 buffer->data, buffer->len, FALSE);
764 /* XXX routers should check server->global_list as well */
765 /* Get channel entry */
766 channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
770 /* XXX routers should check server->global_list as well */
771 /* Get client entry */
772 client = silc_idlist_find_client_by_id(server->local_list, client_id);
776 /* Remove from channel */
777 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
785 silc_free(client_id);
787 silc_free(channel_id);
790 /* Received New Channel packet. Information about new channels in the
791 network are distributed using this packet. Save the information about
794 void silc_server_new_channel(SilcServer server,
795 SilcSocketConnection sock,
796 SilcPacketContext *packet)
799 SilcChannelID *channel_id;
800 unsigned short channel_id_len;
803 SILC_LOG_DEBUG(("Processing New Channel"));
805 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
806 server->server_type == SILC_SERVER ||
807 packet->src_id_type != SILC_ID_SERVER)
811 if (!silc_buffer_unformat(packet->buffer,
812 SILC_STR_UI16_STRING_ALLOC(&channel_name),
813 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
817 if (!channel_name || !id)
820 /* Decode the channel ID */
821 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
826 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
827 silc_id_render(channel_id, SILC_ID_CHANNEL),
830 /* Add the new channel. Add it always to global list since if we receive
831 this packet then it cannot be created by ourselves but some other
832 router hence global channel. */
833 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
834 server->router->connection, NULL);
837 /* Received notify packet. Server can receive notify packets from router.
838 Server then relays the notify messages to clients if needed. */
840 void silc_server_notify(SilcServer server,
841 SilcSocketConnection sock,
842 SilcPacketContext *packet)
844 SilcNotifyPayload payload;
846 SilcArgumentPayload args;
847 SilcClientID *client_id;
848 SilcChannelID *channel_id;
849 SilcClientEntry client;
850 SilcChannelEntry channel;
852 unsigned int tmp_len;
855 SILC_LOG_DEBUG(("Start"));
857 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
858 packet->src_id_type != SILC_ID_SERVER)
861 /* XXX: For now we expect that the we are normal server and that the
862 sender is router. Server could send (protocol allows it) notify to
863 router but we don't support it yet. */
864 if (server->server_type != SILC_SERVER &&
865 sock->type != SILC_SOCKET_TYPE_ROUTER)
868 payload = silc_notify_payload_parse(packet->buffer);
872 type = silc_notify_get_type(payload);
873 args = silc_notify_get_args(payload);
878 case SILC_NOTIFY_TYPE_JOIN:
881 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
885 client_id = silc_id_payload_parse_id(tmp, tmp_len);
887 /* Get client entry */
888 client = silc_idlist_find_client_by_id(server->local_list, client_id);
890 silc_free(client_id);
896 /* Get channel entry */
897 channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
899 silc_free(client_id);
903 silc_free(client_id);
907 case SILC_NOTIFY_TYPE_LEAVE:
910 case SILC_NOTIFY_TYPE_SIGNOFF:
913 /* Ignore rest notify types for now */
914 case SILC_NOTIFY_TYPE_NONE:
915 case SILC_NOTIFY_TYPE_INVITE:
916 case SILC_NOTIFY_TYPE_TOPIC_SET:
917 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
918 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
919 case SILC_NOTIFY_TYPE_MOTD:
925 silc_notify_payload_free(payload);
928 /* Received new channel user packet. Information about new users on a
929 channel are distributed between routers using this packet. The
930 router receiving this will redistribute it and also sent JOIN notify
931 to local clients on the same channel. Normal server sends JOIN notify
932 to its local clients on the channel. */
934 void silc_server_new_channel_user(SilcServer server,
935 SilcSocketConnection sock,
936 SilcPacketContext *packet)
938 unsigned char *tmpid1, *tmpid2;
939 SilcClientID *client_id = NULL;
940 SilcChannelID *channel_id = NULL;
941 unsigned short channel_id_len;
942 unsigned short client_id_len;
943 SilcClientEntry client;
944 SilcChannelEntry channel;
945 SilcChannelClientEntry chl;
947 SilcServerEntry tmpserver, router;
948 SilcSocketConnection router_sock;
952 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
953 server->server_type != SILC_ROUTER ||
954 packet->src_id_type != SILC_ID_SERVER)
958 if (!silc_buffer_unformat(packet->buffer,
959 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
961 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
966 if (!tmpid1 || !tmpid2)
969 /* Decode the channel ID */
970 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
974 /* Decode the client ID */
975 client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
979 /* If the packet is originated from the one who sent it to us we know
980 that the ID belongs to our cell, unless the sender was router. */
981 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
982 tmpserver = (SilcServerEntry)sock->user_data;
984 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
985 sock->type == SILC_SOCKET_TYPE_SERVER) {
986 id_list = server->local_list;
988 router = sock->user_data;
990 id_list = server->global_list;
991 router_sock = (SilcSocketConnection)server->router->connection;
992 router = server->router;
996 /* Find the channel */
997 channel = silc_idlist_find_channel_by_id(id_list, channel_id);
999 SILC_LOG_ERROR(("Received channel user for non-existent channel"));
1003 /* If we are router and this packet is not already broadcast packet
1004 we will broadcast it. */
1005 if (!server->standalone && server->server_type == SILC_ROUTER &&
1006 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1007 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1008 silc_server_packet_send(server, server->router->connection, packet->type,
1009 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1010 packet->buffer->data, packet->buffer->len, FALSE);
1013 /* Get client entry */
1014 client = silc_idlist_find_client_by_id(id_list, client_id);
1016 /* This is new client to us, add entry to ID list */
1017 client = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1018 client_id, router, router_sock);
1023 /* Join the client to the channel by adding it to channel's user list.
1024 Add also the channel to client entry's channels list for fast cross-
1026 chl = silc_calloc(1, sizeof(*chl));
1027 chl->client = client;
1028 chl->channel = channel;
1029 silc_list_add(channel->user_list, chl);
1030 silc_list_add(client->channels, chl);
1032 /* Send JOIN notify to local clients on the channel. As we are router
1033 it is assured that this is sent only to our local clients and locally
1034 connected servers if needed. */
1035 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1036 silc_server_send_notify_to_channel(server, channel, TRUE,
1037 SILC_NOTIFY_TYPE_JOIN,
1038 1, clidp->data, clidp->len);
1039 silc_buffer_free(clidp);
1045 silc_free(client_id);
1047 silc_free(channel_id);