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. */
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);
636 /* If the packet is originated from the one who sent it to us we know
637 that the ID belongs to our cell, unless the sender was router. */
638 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
639 tmpserver = (SilcServerEntry)sock->user_data;
641 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
642 sock->type == SILC_SOCKET_TYPE_SERVER) {
643 id_list = server->local_list;
645 router = sock->user_data;
646 /* router = server->id_entry; */
648 id_list = server->global_list;
649 router_sock = (SilcSocketConnection)server->router->connection;
650 router = server->router;
657 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
658 silc_id_render(id, SILC_ID_CLIENT),
659 sock->type == SILC_SOCKET_TYPE_SERVER ?
660 "Server" : "Router", sock->hostname));
662 /* Add the client to our local list. We are router and we keep
663 cell specific local database of all clients in the cell. */
664 silc_idlist_add_client(id_list, NULL, NULL, NULL, id, router, router_sock);
668 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
669 silc_id_render(id, SILC_ID_SERVER),
670 sock->type == SILC_SOCKET_TYPE_SERVER ?
671 "Server" : "Router", sock->hostname));
673 /* Add the server to our local list. We are router and we keep
674 cell specific local database of all servers in the cell. */
675 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
678 case SILC_ID_CHANNEL:
679 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
687 silc_id_payload_free(idp);
690 /* Received Remove Channel User packet to remove a user from a channel.
691 Routers notify other routers that user has left a channel. Client must
692 not send this packet.. Normal server may send this packet but must not
695 void silc_server_remove_channel_user(SilcServer server,
696 SilcSocketConnection sock,
697 SilcPacketContext *packet)
699 SilcBuffer buffer = packet->buffer;
700 unsigned char *tmp1 = NULL, *tmp2 = NULL;
701 SilcClientID *client_id = NULL;
702 SilcChannelID *channel_id = NULL;
703 SilcChannelEntry channel;
704 SilcClientEntry client;
706 SILC_LOG_DEBUG(("Removing user from channel"));
708 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
709 server->server_type == SILC_SERVER)
712 silc_buffer_unformat(buffer,
713 SILC_STR_UI16_STRING_ALLOC(&tmp1),
714 SILC_STR_UI16_STRING_ALLOC(&tmp2),
720 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
721 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
722 if (!client_id || !channel_id)
725 /* If we are router and this packet is not already broadcast packet
726 we will broadcast it. The sending socket really cannot be router or
727 the router is buggy. If this packet is coming from router then it must
728 have the broadcast flag set already and we won't do anything. */
729 if (!server->standalone && server->server_type == SILC_ROUTER &&
730 sock->type == SILC_SOCKET_TYPE_SERVER &&
731 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
732 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
733 silc_server_packet_send(server, server->router->connection, packet->type,
734 packet->flags | SILC_PACKET_FLAG_BROADCAST,
735 buffer->data, buffer->len, FALSE);
738 /* XXX routers should check server->global_list as well */
739 /* Get channel entry */
740 channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
744 /* XXX routers should check server->global_list as well */
745 /* Get client entry */
746 client = silc_idlist_find_client_by_id(server->local_list, client_id);
750 /* Remove from channel */
751 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
759 silc_free(client_id);
761 silc_free(channel_id);
764 /* Received New Channel packet. Information about new channels in the
765 network are distributed using this packet. Save the information about
768 void silc_server_new_channel(SilcServer server,
769 SilcSocketConnection sock,
770 SilcPacketContext *packet)
773 SilcChannelID *channel_id;
774 unsigned short channel_id_len;
777 SILC_LOG_DEBUG(("Processing New Channel"));
779 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
780 server->server_type == SILC_SERVER ||
781 packet->src_id_type != SILC_ID_SERVER)
785 if (!silc_buffer_unformat(packet->buffer,
786 SILC_STR_UI16_STRING_ALLOC(&channel_name),
787 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
791 if (!channel_name || !id)
794 /* Decode the channel ID */
795 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
800 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
801 silc_id_render(channel_id, SILC_ID_CHANNEL),
804 /* Add the new channel. Add it always to global list since if we receive
805 this packet then it cannot be created by ourselves but some other
806 router hence global channel. */
807 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
808 server->router->connection, NULL);
811 /* Received notify packet. Server can receive notify packets from router.
812 Server then relays the notify messages to clients if needed. */
814 void silc_server_notify(SilcServer server,
815 SilcSocketConnection sock,
816 SilcPacketContext *packet)
818 SilcNotifyPayload payload;
820 SilcArgumentPayload args;
821 SilcChannelID *channel_id;
822 SilcChannelEntry channel;
824 SILC_LOG_DEBUG(("Start"));
826 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
827 packet->src_id_type != SILC_ID_SERVER)
830 /* XXX: For now we expect that the we are normal server and that the
831 sender is router. Server could send (protocol allows it) notify to
832 router but we don't support it yet. */
833 if (server->server_type != SILC_SERVER &&
834 sock->type != SILC_SOCKET_TYPE_ROUTER)
837 payload = silc_notify_payload_parse(packet->buffer);
841 type = silc_notify_get_type(payload);
842 args = silc_notify_get_args(payload);
847 case SILC_NOTIFY_TYPE_JOIN:
849 * Distribute the notify to local clients on the channel
852 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
856 /* Get channel entry */
857 channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
859 silc_free(channel_id);
863 /* Send to channel */
864 silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
865 packet->buffer->data,
866 packet->buffer->len, FALSE);
869 case SILC_NOTIFY_TYPE_LEAVE:
872 case SILC_NOTIFY_TYPE_SIGNOFF:
875 /* Ignore rest notify types for now */
876 case SILC_NOTIFY_TYPE_NONE:
877 case SILC_NOTIFY_TYPE_INVITE:
878 case SILC_NOTIFY_TYPE_TOPIC_SET:
879 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
880 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
881 case SILC_NOTIFY_TYPE_MOTD:
887 silc_notify_payload_free(payload);
890 /* Received new channel user packet. Information about new users on a
891 channel are distributed between routers using this packet. The
892 router receiving this will redistribute it and also sent JOIN notify
893 to local clients on the same channel. Normal server sends JOIN notify
894 to its local clients on the channel. */
896 void silc_server_new_channel_user(SilcServer server,
897 SilcSocketConnection sock,
898 SilcPacketContext *packet)
900 unsigned char *tmpid1, *tmpid2;
901 SilcClientID *client_id = NULL;
902 SilcChannelID *channel_id = NULL;
903 unsigned short channel_id_len;
904 unsigned short client_id_len;
905 SilcClientEntry client;
906 SilcChannelEntry channel;
907 SilcChannelClientEntry chl;
909 SilcServerEntry tmpserver, router;
910 SilcSocketConnection router_sock;
914 SILC_LOG_DEBUG(("Start"));
916 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
917 server->server_type != SILC_ROUTER ||
918 packet->src_id_type != SILC_ID_SERVER)
922 if (!silc_buffer_unformat(packet->buffer,
923 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
925 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
930 if (!tmpid1 || !tmpid2)
933 /* Decode the channel ID */
934 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
938 /* Decode the client ID */
939 client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
943 /* If the packet is originated from the one who sent it to us we know
944 that the ID belongs to our cell, unless the sender was router. */
945 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
946 tmpserver = (SilcServerEntry)sock->user_data;
948 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
949 sock->type == SILC_SOCKET_TYPE_SERVER) {
950 id_list = server->local_list;
952 router = sock->user_data;
954 id_list = server->global_list;
955 router_sock = (SilcSocketConnection)server->router->connection;
956 router = server->router;
960 /* Find the channel */
961 channel = silc_idlist_find_channel_by_id(id_list, channel_id);
963 SILC_LOG_ERROR(("Received channel user for non-existent channel"));
967 /* If we are router and this packet is not already broadcast packet
968 we will broadcast it. */
969 if (!server->standalone && server->server_type == SILC_ROUTER &&
970 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
971 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
972 silc_server_packet_send(server, server->router->connection, packet->type,
973 packet->flags | SILC_PACKET_FLAG_BROADCAST,
974 packet->buffer->data, packet->buffer->len, FALSE);
977 /* Get client entry */
978 client = silc_idlist_find_client_by_id(id_list, client_id);
980 /* This is new client to us, add entry to ID list */
981 client = silc_idlist_add_client(id_list, NULL, NULL, NULL,
982 client_id, router, router_sock);
987 /* Join the client to the channel by adding it to channel's user list.
988 Add also the channel to client entry's channels list for fast cross-
990 chl = silc_calloc(1, sizeof(*chl));
991 chl->client = client;
992 chl->channel = channel;
993 silc_list_add(channel->user_list, chl);
994 silc_list_add(client->channels, chl);
996 /* Send JOIN notify to local clients on the channel. As we are router
997 it is assured that this is sent only to our local clients and locally
998 connected servers if needed. */
999 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1000 silc_server_send_notify_to_channel(server, channel, FALSE,
1001 SILC_NOTIFY_TYPE_JOIN,
1002 1, clidp->data, clidp->len);
1003 silc_buffer_free(clidp);
1009 silc_free(client_id);
1011 silc_free(channel_id);