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. */
250 /* XXX Router must accept this packet and distribute the key to all its
251 server that has clients on the channel */
253 void silc_server_channel_key(SilcServer server,
254 SilcSocketConnection sock,
255 SilcPacketContext *packet)
257 SilcBuffer buffer = packet->buffer;
258 SilcChannelKeyPayload payload = NULL;
259 SilcChannelID *id = NULL;
260 SilcChannelEntry channel;
261 SilcChannelClientEntry chl;
263 unsigned int tmp_len;
266 if (packet->src_id_type != SILC_ID_SERVER &&
267 sock->type != SILC_SOCKET_TYPE_ROUTER)
270 /* Decode channel key payload */
271 payload = silc_channel_key_payload_parse(buffer);
273 SILC_LOG_ERROR(("Bad channel key payload, dropped"));
278 tmp = silc_channel_key_get_id(payload, &tmp_len);
279 id = silc_id_payload_parse_id(tmp, tmp_len);
283 /* Get the channel entry */
284 channel = silc_idlist_find_channel_by_id(server->local_list, id);
286 SILC_LOG_ERROR(("Received key for non-existent channel"));
290 /* Save the key for us as well */
291 tmp = silc_channel_key_get_key(payload, &tmp_len);
294 cipher = silc_channel_key_get_cipher(payload, NULL);;
297 if (!silc_cipher_alloc(cipher, &channel->channel_key))
300 /* Distribute the key to all clients on the channel */
301 silc_list_start(channel->user_list);
302 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
303 silc_server_packet_send(server, chl->client->connection,
304 SILC_PACKET_CHANNEL_KEY, 0,
305 buffer->data, buffer->len, TRUE);
308 channel->key_len = tmp_len * 8;
309 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
310 memcpy(channel->key, tmp, tmp_len);
311 channel->channel_key->cipher->set_key(channel->channel_key->context,
317 silc_channel_key_payload_free(payload);
320 /* Received packet to replace a ID. This checks that the requested ID
321 exists and replaces it with the new one. */
323 void silc_server_replace_id(SilcServer server,
324 SilcSocketConnection sock,
325 SilcPacketContext *packet)
327 SilcBuffer buffer = packet->buffer;
328 unsigned char *old_id = NULL, *new_id = NULL;
329 SilcIdType old_id_type, new_id_type;
330 unsigned short old_id_len, new_id_len;
331 void *id = NULL, *id2 = NULL;
333 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
334 packet->src_id_type == SILC_ID_CLIENT)
337 SILC_LOG_DEBUG(("Replacing ID"));
339 silc_buffer_unformat(buffer,
340 SILC_STR_UI_SHORT(&old_id_type),
341 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
342 SILC_STR_UI_SHORT(&new_id_type),
343 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
346 if (old_id_type != new_id_type)
349 if (old_id_len != silc_id_get_len(old_id_type) ||
350 new_id_len != silc_id_get_len(new_id_type))
353 id = silc_id_str2id(old_id, old_id_type);
357 id2 = silc_id_str2id(new_id, new_id_type);
361 /* If we are router and this packet is not already broadcast packet
362 we will broadcast it. The sending socket really cannot be router or
363 the router is buggy. If this packet is coming from router then it must
364 have the broadcast flag set already and we won't do anything. */
365 if (server->server_type == SILC_ROUTER &&
366 sock->type == SILC_SOCKET_TYPE_SERVER &&
367 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
368 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
369 silc_server_packet_send(server, server->router->connection, packet->type,
370 packet->flags | SILC_PACKET_FLAG_BROADCAST,
371 buffer->data, buffer->len, FALSE);
374 /* Replace the old ID */
375 switch(old_id_type) {
377 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
378 if (server->server_type == SILC_ROUTER)
379 silc_idlist_replace_client_id(server->global_list, id, id2);
383 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
384 if (server->server_type == SILC_ROUTER)
385 silc_idlist_replace_server_id(server->global_list, id, id2);
388 case SILC_ID_CHANNEL:
389 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
409 /* Received New Client packet and processes it. Creates Client ID for the
410 client. Client becomes registered after calling this functions. */
412 SilcClientEntry silc_server_new_client(SilcServer server,
413 SilcSocketConnection sock,
414 SilcPacketContext *packet)
416 SilcBuffer buffer = packet->buffer;
417 SilcClientEntry client;
418 SilcIDCacheEntry cache;
419 SilcClientID *client_id;
421 SilcIDListData idata;
422 char *username = NULL, *realname = NULL, *id_string;
424 SILC_LOG_DEBUG(("Creating new client"));
426 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
429 /* Take client entry */
430 client = (SilcClientEntry)sock->user_data;
431 idata = (SilcIDListData)client;
433 /* Fetch the old client cache entry so that we can update it. */
434 if (!silc_idcache_find_by_context(server->local_list->clients,
435 sock->user_data, &cache)) {
436 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
440 /* Parse incoming packet */
441 silc_buffer_unformat(buffer,
442 SILC_STR_UI16_STRING_ALLOC(&username),
443 SILC_STR_UI16_STRING_ALLOC(&realname),
446 /* Create Client ID */
447 silc_id_create_client_id(server->id, server->rng, server->md5hash,
448 username, &client_id);
450 /* Update client entry */
451 idata->registered = TRUE;
452 client->nickname = strdup(username);
453 client->username = username;
454 client->userinfo = realname;
455 client->id = client_id;
457 /* Update the cache entry */
458 cache->id = (void *)client_id;
459 cache->type = SILC_ID_CLIENT;
460 cache->data = username;
461 silc_idcache_sort_by_data(server->local_list->clients);
463 /* Notify our router about new client on the SILC network */
464 if (!server->standalone)
465 silc_server_send_new_id(server, (SilcSocketConnection)
466 server->router->connection,
467 server->server_type == SILC_ROUTER ? TRUE : FALSE,
468 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
470 /* Send the new client ID to the client. */
471 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
472 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
473 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
474 silc_buffer_format(reply,
475 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
476 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
477 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
479 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
480 reply->data, reply->len, FALSE);
481 silc_free(id_string);
482 silc_buffer_free(reply);
484 /* Send some nice info to the client */
485 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
486 ("Welcome to the SILC Network %s@%s",
487 username, sock->hostname));
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,
583 /* Processes incoming New ID packet. New ID Payload is used to distribute
584 information about newly registered clients, servers and created
587 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
588 SilcPacketContext *packet)
590 SilcBuffer buffer = packet->buffer;
592 SilcServerEntry tmpserver, router;
593 SilcSocketConnection router_sock;
598 SILC_LOG_DEBUG(("Processing new ID"));
600 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
601 server->server_type == SILC_SERVER ||
602 packet->src_id_type != SILC_ID_SERVER)
605 idp = silc_id_payload_parse(buffer);
609 id_type = silc_id_payload_get_type(idp);
611 /* Normal server cannot have other normal server connections */
612 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
615 id = silc_id_payload_get_id(idp);
619 /* If the sender of this packet is server and we are router we need to
620 broadcast this packet to other routers in the network. */
621 if (!server->standalone && server->server_type == SILC_ROUTER &&
622 sock->type == SILC_SOCKET_TYPE_SERVER &&
623 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
624 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
625 silc_server_packet_send(server, server->router->connection,
627 packet->flags | SILC_PACKET_FLAG_BROADCAST,
628 buffer->data, buffer->len, FALSE);
631 /* If the packet is originated from the one who sent it to us we know
632 that the ID belongs to our cell, unless the sender was router. */
633 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
634 tmpserver = (SilcServerEntry)sock->user_data;
636 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
637 sock->type == SILC_SOCKET_TYPE_SERVER) {
638 id_list = server->local_list;
640 router = sock->user_data;
641 /* router = server->id_entry; */
643 id_list = server->global_list;
644 router_sock = (SilcSocketConnection)server->router->connection;
645 router = server->router;
653 SilcClientEntry idlist;
655 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
656 silc_id_render(id, SILC_ID_CLIENT),
657 sock->type == SILC_SOCKET_TYPE_SERVER ?
658 "Server" : "Router", sock->hostname));
660 /* Add the client to our local list. We are router and we keep
661 cell specific local database of all clients in the cell. */
662 idlist = silc_idlist_add_client(id_list, NULL, NULL, NULL,
663 id, router, router_sock);
669 SilcServerEntry idlist;
671 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
672 silc_id_render(id, SILC_ID_SERVER),
673 sock->type == SILC_SOCKET_TYPE_SERVER ?
674 "Server" : "Router", sock->hostname));
676 /* Add the server to our local list. We are router and we keep
677 cell specific local database of all servers in the cell. */
678 idlist = silc_idlist_add_server(id_list, NULL, 0, id, router,
683 case SILC_ID_CHANNEL:
684 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
686 SILC_LOG_DEBUG(("New channel id(%s) from [%s] %s",
687 silc_id_render(id, SILC_ID_CHANNEL),
688 sock->type == SILC_SOCKET_TYPE_SERVER ?
689 "Server" : "Router", sock->hostname));
691 /* Add the channel to our local list. We are router and we keep
692 cell specific local database of all channels in the cell. */
693 silc_idlist_add_channel(id_list, NULL, 0, id, router, NULL);
702 silc_id_payload_free(idp);
705 /* Received Remove Channel User packet to remove a user from a channel.
706 Routers notify other routers that user has left a channel. Client must
707 not send this packet.. Normal server may send this packet but must not
710 void silc_server_remove_channel_user(SilcServer server,
711 SilcSocketConnection sock,
712 SilcPacketContext *packet)
714 SilcBuffer buffer = packet->buffer;
715 unsigned char *tmp1 = NULL, *tmp2 = NULL;
716 SilcClientID *client_id = NULL;
717 SilcChannelID *channel_id = NULL;
718 SilcChannelEntry channel;
719 SilcClientEntry client;
721 SILC_LOG_DEBUG(("Removing user from channel"));
723 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
724 server->server_type == SILC_SERVER)
727 silc_buffer_unformat(buffer,
728 SILC_STR_UI16_STRING_ALLOC(&tmp1),
729 SILC_STR_UI16_STRING_ALLOC(&tmp2),
735 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
736 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
737 if (!client_id || !channel_id)
740 /* If we are router and this packet is not already broadcast packet
741 we will broadcast it. The sending socket really cannot be router or
742 the router is buggy. If this packet is coming from router then it must
743 have the broadcast flag set already and we won't do anything. */
744 if (!server->standalone && server->server_type == SILC_ROUTER &&
745 sock->type == SILC_SOCKET_TYPE_SERVER &&
746 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
747 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
748 silc_server_packet_send(server, server->router->connection, packet->type,
749 packet->flags | SILC_PACKET_FLAG_BROADCAST,
750 buffer->data, buffer->len, FALSE);
753 /* XXX routers should check server->global_list as well */
754 /* Get channel entry */
755 channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
759 /* XXX routers should check server->global_list as well */
760 /* Get client entry */
761 client = silc_idlist_find_client_by_id(server->local_list, client_id);
765 /* Remove from channel */
766 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
774 silc_free(client_id);
776 silc_free(channel_id);
779 /* Received New Channel packet. Information about new channels in the
780 network are distributed using this packet. Save the information about
783 void silc_server_new_channel(SilcServer server,
784 SilcSocketConnection sock,
785 SilcPacketContext *packet)
788 SilcChannelID *channel_id;
789 unsigned short channel_id_len;
792 SILC_LOG_DEBUG(("Processing New Channel"));
794 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
795 server->server_type == SILC_SERVER ||
796 packet->src_id_type != SILC_ID_SERVER)
800 if (!silc_buffer_unformat(packet->buffer,
801 SILC_STR_UI16_STRING_ALLOC(&channel_name),
802 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
806 if (!channel_name || !id)
809 /* Decode the channel ID */
810 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
815 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
816 silc_id_render(channel_id, SILC_ID_CHANNEL),
819 /* Add the new channel. Add it always to global list since if we receive
820 this packet then it cannot be created by ourselves but some other
821 router hence global channel. */
822 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
823 server->router->connection, NULL);
826 /* Received notify packet. Server can receive notify packets from router.
827 Server then relays the notify messages to clients if needed. */
829 void silc_server_notify(SilcServer server,
830 SilcSocketConnection sock,
831 SilcPacketContext *packet)
833 SilcNotifyPayload payload;
835 SilcArgumentPayload args;
838 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
839 packet->src_id_type != SILC_ID_SERVER)
842 /* For now we expect that the we are normal server and that the
843 sender is router. Server could send (protocol allows it) notify to
844 router but we don't support it yet. XXX! */
845 if (server->server_type != SILC_SERVER &&
846 sock->type != SILC_SOCKET_TYPE_ROUTER)
849 payload = silc_notify_payload_parse(packet->buffer);
853 type = silc_notify_get_type(payload);
854 args = silc_notify_get_args(payload);
859 case SILC_NOTIFY_TYPE_JOIN:
862 case SILC_NOTIFY_TYPE_LEAVE:
865 case SILC_NOTIFY_TYPE_SIGNOFF:
868 /* Ignore rest notify types for now */
869 case SILC_NOTIFY_TYPE_NONE:
870 case SILC_NOTIFY_TYPE_INVITE:
871 case SILC_NOTIFY_TYPE_TOPIC_SET:
872 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
873 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
874 case SILC_NOTIFY_TYPE_MOTD:
880 silc_notify_payload_free(payload);
883 /* Received new channel user packet. Information about new users on a
884 channel are distributed between routers using this packet. The
885 router receiving this will redistribute it and also sent JOIN notify
886 to local clients on the same channel. Normal server sends JOIN notify
887 to its local clients on the channel. */
889 void silc_server_new_channel_user(SilcServer server,
890 SilcSocketConnection sock,
891 SilcPacketContext *packet)
893 unsigned char *tmpid1, *tmpid2;
894 SilcClientID *client_id = NULL;
895 SilcChannelID *channel_id = NULL;
896 unsigned short channel_id_len;
897 unsigned short client_id_len;
898 SilcClientEntry client;
899 SilcChannelEntry channel;
900 SilcChannelClientEntry chl;
902 SilcServerEntry tmpserver, router;
903 SilcSocketConnection router_sock;
907 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
908 server->server_type != SILC_ROUTER ||
909 packet->src_id_type != SILC_ID_SERVER)
913 if (!silc_buffer_unformat(packet->buffer,
914 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
916 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
921 if (!tmpid1 || !tmpid2)
924 /* Decode the channel ID */
925 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
929 /* Decode the client ID */
930 client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
934 /* If the packet is originated from the one who sent it to us we know
935 that the ID belongs to our cell, unless the sender was router. */
936 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
937 tmpserver = (SilcServerEntry)sock->user_data;
939 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
940 sock->type == SILC_SOCKET_TYPE_SERVER) {
941 id_list = server->local_list;
943 router = sock->user_data;
945 id_list = server->global_list;
946 router_sock = (SilcSocketConnection)server->router->connection;
947 router = server->router;
951 /* Find the channel */
952 channel = silc_idlist_find_channel_by_id(id_list, channel_id);
954 SILC_LOG_ERROR(("Received channel user for non-existent channel"));
958 /* If we are router and this packet is not already broadcast packet
959 we will broadcast it. */
960 if (!server->standalone && server->server_type == SILC_ROUTER &&
961 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
962 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
963 silc_server_packet_send(server, server->router->connection, packet->type,
964 packet->flags | SILC_PACKET_FLAG_BROADCAST,
965 packet->buffer->data, packet->buffer->len, FALSE);
968 /* Get client entry */
969 client = silc_idlist_find_client_by_id(id_list, client_id);
971 /* This is new client to us, add entry to ID list */
972 client = silc_idlist_add_client(id_list, NULL, NULL, NULL,
973 client_id, router, router_sock);
978 /* Join the client to the channel by adding it to channel's user list.
979 Add also the channel to client entry's channels list for fast cross-
981 chl = silc_calloc(1, sizeof(*chl));
982 chl->client = client;
983 chl->channel = channel;
984 silc_list_add(channel->user_list, chl);
985 silc_list_add(client->channels, chl);
987 /* Send JOIN notify to local clients on the channel. As we are router
988 it is assured that this is sent only to our local clients and locally
989 connected servers if needed. */
990 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
991 silc_server_send_notify_to_channel(server, channel, TRUE,
992 SILC_NOTIFY_TYPE_JOIN,
993 1, clidp->data, clidp->len);
994 silc_buffer_free(clidp);
1000 silc_free(client_id);
1002 silc_free(channel_id);