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_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);
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. */
317 silc_server_send_channel_key(server, channel, FALSE);
323 silc_channel_key_payload_free(payload);
326 /* Received packet to replace a ID. This checks that the requested ID
327 exists and replaces it with the new one. */
329 void silc_server_replace_id(SilcServer server,
330 SilcSocketConnection sock,
331 SilcPacketContext *packet)
333 SilcBuffer buffer = packet->buffer;
334 unsigned char *old_id = NULL, *new_id = NULL;
335 SilcIdType old_id_type, new_id_type;
336 unsigned short old_id_len, new_id_len;
337 void *id = NULL, *id2 = NULL;
339 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
340 packet->src_id_type == SILC_ID_CLIENT)
343 SILC_LOG_DEBUG(("Replacing ID"));
345 silc_buffer_unformat(buffer,
346 SILC_STR_UI_SHORT(&old_id_type),
347 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
348 SILC_STR_UI_SHORT(&new_id_type),
349 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
352 if (old_id_type != new_id_type)
355 if (old_id_len != silc_id_get_len(old_id_type) ||
356 new_id_len != silc_id_get_len(new_id_type))
359 id = silc_id_str2id(old_id, old_id_type);
363 id2 = silc_id_str2id(new_id, new_id_type);
367 /* If we are router and this packet is not already broadcast packet
368 we will broadcast it. The sending socket really cannot be router or
369 the router is buggy. If this packet is coming from router then it must
370 have the broadcast flag set already and we won't do anything. */
371 if (server->server_type == SILC_ROUTER &&
372 sock->type == SILC_SOCKET_TYPE_SERVER &&
373 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
374 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
375 silc_server_packet_send(server, server->router->connection, packet->type,
376 packet->flags | SILC_PACKET_FLAG_BROADCAST,
377 buffer->data, buffer->len, FALSE);
380 /* Replace the old ID */
381 switch(old_id_type) {
383 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
384 if (server->server_type == SILC_ROUTER)
385 silc_idlist_replace_client_id(server->global_list, id, id2);
389 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
390 if (server->server_type == SILC_ROUTER)
391 silc_idlist_replace_server_id(server->global_list, id, id2);
394 case SILC_ID_CHANNEL:
395 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
415 /* Received New Client packet and processes it. Creates Client ID for the
416 client. Client becomes registered after calling this functions. */
418 SilcClientEntry silc_server_new_client(SilcServer server,
419 SilcSocketConnection sock,
420 SilcPacketContext *packet)
422 SilcBuffer buffer = packet->buffer;
423 SilcClientEntry client;
424 SilcIDCacheEntry cache;
425 SilcClientID *client_id;
427 SilcIDListData idata;
428 char *username = NULL, *realname = NULL, *id_string;
430 SILC_LOG_DEBUG(("Creating new client"));
432 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
435 /* Take client entry */
436 client = (SilcClientEntry)sock->user_data;
437 idata = (SilcIDListData)client;
439 /* Fetch the old client cache entry so that we can update it. */
440 if (!silc_idcache_find_by_context(server->local_list->clients,
441 sock->user_data, &cache)) {
442 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
446 /* Parse incoming packet */
447 silc_buffer_unformat(buffer,
448 SILC_STR_UI16_STRING_ALLOC(&username),
449 SILC_STR_UI16_STRING_ALLOC(&realname),
452 /* Create Client ID */
453 silc_id_create_client_id(server->id, server->rng, server->md5hash,
454 username, &client_id);
456 /* Update client entry */
457 idata->registered = TRUE;
458 client->nickname = strdup(username);
459 client->username = username;
460 client->userinfo = realname;
461 client->id = client_id;
463 /* Update the cache entry */
464 cache->id = (void *)client_id;
465 cache->type = SILC_ID_CLIENT;
466 cache->data = username;
467 silc_idcache_sort_by_data(server->local_list->clients);
469 /* Notify our router about new client on the SILC network */
470 if (!server->standalone)
471 silc_server_send_new_id(server, (SilcSocketConnection)
472 server->router->connection,
473 server->server_type == SILC_ROUTER ? TRUE : FALSE,
474 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
476 /* Send the new client ID to the client. */
477 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
478 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
479 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
480 silc_buffer_format(reply,
481 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
482 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
483 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
485 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
486 reply->data, reply->len, FALSE);
487 silc_free(id_string);
488 silc_buffer_free(reply);
490 /* Send some nice info to the client */
491 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
492 ("Welcome to the SILC Network %s@%s",
493 username, sock->hostname));
494 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
495 ("Your host is %s, running version %s",
496 server->config->server_info->server_name,
498 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
499 ("Your connection is secured with %s cipher, "
500 "key length %d bits",
501 idata->send_key->cipher->name,
502 idata->send_key->cipher->key_len));
503 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
504 ("Your current nickname is %s",
508 silc_server_send_motd(server, sock);
513 /* Create new server. This processes received New Server packet and
514 saves the received Server ID. The server is our locally connected
515 server thus we save all the information and save it to local list.
516 This funtion can be used by both normal server and router server.
517 If normal server uses this it means that its router has connected
518 to the server. If router uses this it means that one of the cell's
519 servers is connected to the router. */
521 SilcServerEntry silc_server_new_server(SilcServer server,
522 SilcSocketConnection sock,
523 SilcPacketContext *packet)
525 SilcBuffer buffer = packet->buffer;
526 SilcServerEntry new_server;
527 SilcIDCacheEntry cache;
528 SilcServerID *server_id;
529 SilcIDListData idata;
530 unsigned char *server_name, *id_string;
531 unsigned short id_len;
533 SILC_LOG_DEBUG(("Creating new server"));
535 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
536 sock->type != SILC_SOCKET_TYPE_ROUTER)
539 /* Take server entry */
540 new_server = (SilcServerEntry)sock->user_data;
541 idata = (SilcIDListData)new_server;
543 /* Fetch the old server cache entry so that we can update it. */
544 if (!silc_idcache_find_by_context(server->local_list->servers,
545 sock->user_data, &cache)) {
546 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
550 /* Parse the incoming packet */
551 silc_buffer_unformat(buffer,
552 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
553 SILC_STR_UI16_STRING_ALLOC(&server_name),
556 if (id_len > buffer->len) {
557 silc_free(id_string);
558 silc_free(server_name);
563 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
564 silc_free(id_string);
566 /* Update client entry */
567 idata->registered = TRUE;
568 new_server->server_name = server_name;
569 new_server->id = server_id;
571 /* Update the cache entry */
572 cache->id = (void *)server_id;
573 cache->type = SILC_ID_SERVER;
574 cache->data = server_name;
575 silc_idcache_sort_by_data(server->local_list->servers);
577 /* Distribute the information about new server in the SILC network
578 to our router. If we are normal server we won't send anything
579 since this connection must be our router connection. */
580 if (server->server_type == SILC_ROUTER && !server->standalone &&
581 server->router->connection != sock)
582 silc_server_send_new_id(server, server->router->connection,
583 TRUE, new_server->id, SILC_ID_SERVER,
589 /* Processes incoming New ID packet. New ID Payload is used to distribute
590 information about newly registered clients and servers. */
592 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
593 SilcPacketContext *packet)
595 SilcBuffer buffer = packet->buffer;
597 SilcServerEntry tmpserver, router;
598 SilcSocketConnection router_sock;
603 SILC_LOG_DEBUG(("Processing new ID"));
605 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
606 server->server_type == SILC_SERVER ||
607 packet->src_id_type != SILC_ID_SERVER)
610 idp = silc_id_payload_parse(buffer);
614 id_type = silc_id_payload_get_type(idp);
616 /* Normal server cannot have other normal server connections */
617 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
620 id = silc_id_payload_get_id(idp);
624 /* If the sender of this packet is server and we are router we need to
625 broadcast this packet to other routers in the network. */
626 if (!server->standalone && server->server_type == SILC_ROUTER &&
627 sock->type == SILC_SOCKET_TYPE_SERVER &&
628 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
629 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
630 silc_server_packet_send(server, server->router->connection,
632 packet->flags | SILC_PACKET_FLAG_BROADCAST,
633 buffer->data, buffer->len, FALSE);
637 /* If the packet is originated from the one who sent it to us we know
638 that the ID belongs to our cell, unless the sender was router. */
639 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
640 tmpserver = (SilcServerEntry)sock->user_data;
642 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
643 sock->type == SILC_SOCKET_TYPE_SERVER) {
644 id_list = server->local_list;
646 router = sock->user_data;
647 /* router = server->id_entry; */
649 id_list = server->global_list;
650 router_sock = (SilcSocketConnection)server->router->connection;
651 router = server->router;
657 if (sock->type == SILC_SOCKET_TYPE_SERVER)
658 id_list = server->local_list;
660 id_list = server->global_list;
663 router = sock->user_data;
667 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
668 silc_id_render(id, SILC_ID_CLIENT),
669 sock->type == SILC_SOCKET_TYPE_SERVER ?
670 "Server" : "Router", sock->hostname));
672 /* Add the client to our local list. We are router and we keep
673 cell specific local database of all clients in the cell. */
674 silc_idlist_add_client(id_list, NULL, NULL, NULL, id, router, router_sock);
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,
684 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
685 silc_id_render(id, SILC_ID_SERVER),
686 sock->type == SILC_SOCKET_TYPE_SERVER ?
687 "Server" : "Router", sock->hostname));
689 /* Add the server to our local list. We are router and we keep
690 cell specific local database of all servers in the cell. */
691 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
693 /* Add route cache for this ID */
694 silc_server_route_add(silc_server_route_hash(
695 ((SilcServerID *)id)->ip.s_addr,
696 ((SilcServerID *)id)->port),
697 ((SilcServerID *)id)->ip.s_addr,
701 case SILC_ID_CHANNEL:
702 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
710 silc_id_payload_free(idp);
713 /* Received Remove Channel User packet to remove a user from a channel.
714 Routers notify other routers that user has left a channel. Client must
715 not send this packet.. Normal server may send this packet but must not
718 void silc_server_remove_channel_user(SilcServer server,
719 SilcSocketConnection sock,
720 SilcPacketContext *packet)
722 SilcBuffer buffer = packet->buffer;
723 unsigned char *tmp1 = NULL, *tmp2 = NULL;
724 SilcClientID *client_id = NULL;
725 SilcChannelID *channel_id = NULL;
726 SilcChannelEntry channel;
727 SilcClientEntry client;
729 SILC_LOG_DEBUG(("Removing user from channel"));
731 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
732 server->server_type == SILC_SERVER)
735 silc_buffer_unformat(buffer,
736 SILC_STR_UI16_STRING_ALLOC(&tmp1),
737 SILC_STR_UI16_STRING_ALLOC(&tmp2),
743 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
744 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
745 if (!client_id || !channel_id)
748 /* If we are router and this packet is not already broadcast packet
749 we will broadcast it. The sending socket really cannot be router or
750 the router is buggy. If this packet is coming from router then it must
751 have the broadcast flag set already and we won't do anything. */
752 if (!server->standalone && server->server_type == SILC_ROUTER &&
753 sock->type == SILC_SOCKET_TYPE_SERVER &&
754 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
755 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
756 silc_server_packet_send(server, server->router->connection, packet->type,
757 packet->flags | SILC_PACKET_FLAG_BROADCAST,
758 buffer->data, buffer->len, FALSE);
761 /* XXX routers should check server->global_list as well */
762 /* Get channel entry */
763 channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
767 /* XXX routers should check server->global_list as well */
768 /* Get client entry */
769 client = silc_idlist_find_client_by_id(server->local_list, client_id);
773 /* Remove from channel */
774 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
782 silc_free(client_id);
784 silc_free(channel_id);
787 /* Received New Channel packet. Information about new channels in the
788 network are distributed using this packet. Save the information about
791 void silc_server_new_channel(SilcServer server,
792 SilcSocketConnection sock,
793 SilcPacketContext *packet)
796 SilcChannelID *channel_id;
797 unsigned short channel_id_len;
800 SILC_LOG_DEBUG(("Processing New Channel"));
802 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
803 server->server_type == SILC_SERVER ||
804 packet->src_id_type != SILC_ID_SERVER)
808 if (!silc_buffer_unformat(packet->buffer,
809 SILC_STR_UI16_STRING_ALLOC(&channel_name),
810 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
814 if (!channel_name || !id)
817 /* Decode the channel ID */
818 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
823 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
824 silc_id_render(channel_id, SILC_ID_CHANNEL),
827 /* Add the new channel. Add it always to global list since if we receive
828 this packet then it cannot be created by ourselves but some other
829 router hence global channel. */
830 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
831 server->router->connection, NULL);
834 /* Received notify packet. Server can receive notify packets from router.
835 Server then relays the notify messages to clients if needed. */
837 void silc_server_notify(SilcServer server,
838 SilcSocketConnection sock,
839 SilcPacketContext *packet)
841 SilcNotifyPayload payload;
843 SilcArgumentPayload args;
844 SilcChannelID *channel_id;
845 SilcChannelEntry channel;
847 SILC_LOG_DEBUG(("Start"));
849 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
850 packet->src_id_type != SILC_ID_SERVER)
853 /* XXX: For now we expect that the we are normal server and that the
854 sender is router. Server could send (protocol allows it) notify to
855 router but we don't support it yet. */
856 if (server->server_type != SILC_SERVER &&
857 sock->type != SILC_SOCKET_TYPE_ROUTER)
860 payload = silc_notify_payload_parse(packet->buffer);
864 type = silc_notify_get_type(payload);
865 args = silc_notify_get_args(payload);
870 case SILC_NOTIFY_TYPE_JOIN:
872 * Distribute the notify to local clients on the channel
875 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
879 /* Get channel entry */
880 channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
882 silc_free(channel_id);
886 /* Send to channel */
887 silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
888 packet->buffer->data,
889 packet->buffer->len, FALSE);
892 case SILC_NOTIFY_TYPE_LEAVE:
895 case SILC_NOTIFY_TYPE_SIGNOFF:
898 /* Ignore rest notify types for now */
899 case SILC_NOTIFY_TYPE_NONE:
900 case SILC_NOTIFY_TYPE_INVITE:
901 case SILC_NOTIFY_TYPE_TOPIC_SET:
902 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
903 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
904 case SILC_NOTIFY_TYPE_MOTD:
910 silc_notify_payload_free(payload);
913 /* Received new channel user packet. Information about new users on a
914 channel are distributed between routers using this packet. The
915 router receiving this will redistribute it and also sent JOIN notify
916 to local clients on the same channel. Normal server sends JOIN notify
917 to its local clients on the channel. */
919 void silc_server_new_channel_user(SilcServer server,
920 SilcSocketConnection sock,
921 SilcPacketContext *packet)
923 unsigned char *tmpid1, *tmpid2;
924 SilcClientID *client_id = NULL;
925 SilcChannelID *channel_id = NULL;
926 unsigned short channel_id_len;
927 unsigned short client_id_len;
928 SilcClientEntry client;
929 SilcChannelEntry channel;
930 SilcChannelClientEntry chl;
932 SilcServerEntry tmpserver, router;
933 SilcSocketConnection router_sock;
937 SILC_LOG_DEBUG(("Start"));
939 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
940 server->server_type != SILC_ROUTER ||
941 packet->src_id_type != SILC_ID_SERVER)
945 if (!silc_buffer_unformat(packet->buffer,
946 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
948 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
953 if (!tmpid1 || !tmpid2)
956 /* Decode the channel ID */
957 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
961 /* Decode the client ID */
962 client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
966 /* If the packet is originated from the one who sent it to us we know
967 that the ID belongs to our cell, unless the sender was router. */
968 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
969 tmpserver = (SilcServerEntry)sock->user_data;
971 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
972 sock->type == SILC_SOCKET_TYPE_SERVER) {
973 id_list = server->local_list;
975 router = sock->user_data;
977 id_list = server->global_list;
978 router_sock = (SilcSocketConnection)server->router->connection;
979 router = server->router;
983 /* Find the channel */
984 channel = silc_idlist_find_channel_by_id(id_list, channel_id);
986 SILC_LOG_ERROR(("Received channel user for non-existent channel"));
990 /* If we are router and this packet is not already broadcast packet
991 we will broadcast it. */
992 if (!server->standalone && server->server_type == SILC_ROUTER &&
993 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
994 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
995 silc_server_packet_send(server, server->router->connection, packet->type,
996 packet->flags | SILC_PACKET_FLAG_BROADCAST,
997 packet->buffer->data, packet->buffer->len, FALSE);
1000 /* Get client entry */
1001 client = silc_idlist_find_client_by_id(id_list, client_id);
1003 /* This is new client to us, add entry to ID list */
1004 client = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1005 client_id, router, router_sock);
1010 /* Join the client to the channel by adding it to channel's user list.
1011 Add also the channel to client entry's channels list for fast cross-
1013 chl = silc_calloc(1, sizeof(*chl));
1014 chl->client = client;
1015 chl->channel = channel;
1016 silc_list_add(channel->user_list, chl);
1017 silc_list_add(client->channels, chl);
1019 /* Send JOIN notify to local clients on the channel. As we are router
1020 it is assured that this is sent only to our local clients and locally
1021 connected servers if needed. */
1022 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1023 silc_server_send_notify_to_channel(server, channel, FALSE,
1024 SILC_NOTIFY_TYPE_JOIN,
1025 1, clidp->data, clidp->len);
1026 silc_buffer_free(clidp);
1032 silc_free(client_id);
1034 silc_free(channel_id);