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, NULL);
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 /* Processes incoming command reply packet. The command reply packet may
129 be destined to one of our clients or it may directly for us. We will
130 call the command reply routine after processing the packet. */
132 void silc_server_command_reply(SilcServer server,
133 SilcSocketConnection sock,
134 SilcPacketContext *packet)
136 SilcBuffer buffer = packet->buffer;
137 SilcClientEntry client = NULL;
138 SilcSocketConnection dst_sock;
139 SilcIDListData idata;
140 SilcClientID *id = NULL;
142 SILC_LOG_DEBUG(("Start"));
144 /* Source must be server or router */
145 if (packet->src_id_type != SILC_ID_SERVER &&
146 sock->type != SILC_SOCKET_TYPE_ROUTER)
149 if (packet->dst_id_type == SILC_ID_CHANNEL)
152 if (packet->dst_id_type == SILC_ID_CLIENT) {
153 /* Destination must be one of ours */
154 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
155 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
157 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
163 if (packet->dst_id_type == SILC_ID_SERVER) {
164 /* For now this must be for us */
165 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
166 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
171 /* Execute command reply locally for the command */
172 silc_server_command_reply_process(server, sock, buffer);
174 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
175 /* Relay the packet to the client */
177 dst_sock = (SilcSocketConnection)client->connection;
178 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
179 + packet->dst_id_len + packet->padlen);
181 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
182 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
184 idata = (SilcIDListData)client;
187 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
190 /* Send the packet */
191 silc_server_packet_send_real(server, dst_sock, TRUE);
197 /* Process received channel message. The message can be originated from
200 void silc_server_channel_message(SilcServer server,
201 SilcSocketConnection sock,
202 SilcPacketContext *packet)
204 SilcChannelEntry channel = NULL;
205 SilcChannelClientEntry chl;
206 SilcChannelID *id = NULL;
209 SILC_LOG_DEBUG(("Processing channel message"));
212 if (packet->dst_id_type != SILC_ID_CHANNEL) {
213 SILC_LOG_ERROR(("Received bad message for channel, dropped"));
214 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
218 /* Find channel entry */
219 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
220 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
222 SILC_LOG_DEBUG(("Could not find channel"));
226 /* See that this client is on the channel. If the message is coming
227 from router we won't do the check as the message is from client that
228 we don't know about. Also, if the original sender is not client
229 (as it can be server as well) we don't do the check. */
230 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
231 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
232 packet->src_id_type == SILC_ID_CLIENT) {
233 silc_list_start(channel->user_list);
234 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
235 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
238 if (chl == SILC_LIST_END)
242 /* Distribute the packet to our local clients. This will send the
243 packet for further routing as well, if needed. */
244 silc_server_packet_relay_to_channel(server, sock, channel, sender,
246 packet->buffer->data,
247 packet->buffer->len, FALSE);
256 /* Received channel key packet. We distribute the key to all of our locally
257 connected clients on the channel. */
259 void silc_server_channel_key(SilcServer server,
260 SilcSocketConnection sock,
261 SilcPacketContext *packet)
263 SilcBuffer buffer = packet->buffer;
264 SilcChannelKeyPayload payload = NULL;
265 SilcChannelID *id = NULL;
266 SilcChannelEntry channel;
267 SilcChannelClientEntry chl;
269 unsigned int tmp_len;
273 if (packet->src_id_type != SILC_ID_SERVER)
276 /* Decode channel key payload */
277 payload = silc_channel_key_payload_parse(buffer);
279 SILC_LOG_ERROR(("Bad channel key payload, dropped"));
284 tmp = silc_channel_key_get_id(payload, &tmp_len);
285 id = silc_id_payload_parse_id(tmp, tmp_len);
289 /* Get the channel entry */
290 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
292 SILC_LOG_ERROR(("Received key for non-existent channel"));
296 tmp = silc_channel_key_get_key(payload, &tmp_len);
300 cipher = silc_channel_key_get_cipher(payload, NULL);;
304 /* Remove old key if exists */
306 memset(channel->key, 0, channel->key_len);
307 silc_free(channel->key);
308 silc_cipher_free(channel->channel_key);
312 /* Create new cipher */
313 if (!silc_cipher_alloc(cipher, &channel->channel_key))
317 channel->key_len = tmp_len * 8;
318 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
319 memcpy(channel->key, tmp, tmp_len);
320 channel->channel_key->cipher->set_key(channel->channel_key->context,
323 /* Distribute the key to everybody who is on the channel. If we are router
324 we will also send it to locally connected servers. */
325 silc_server_send_channel_key(server, channel, FALSE);
331 silc_channel_key_payload_free(payload);
334 /* Received packet to replace a ID. This checks that the requested ID
335 exists and replaces it with the new one. */
337 void silc_server_replace_id(SilcServer server,
338 SilcSocketConnection sock,
339 SilcPacketContext *packet)
341 SilcBuffer buffer = packet->buffer;
342 unsigned char *old_id = NULL, *new_id = NULL;
343 SilcIdType old_id_type, new_id_type;
344 unsigned short old_id_len, new_id_len;
345 void *id = NULL, *id2 = NULL;
347 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
348 packet->src_id_type == SILC_ID_CLIENT)
351 SILC_LOG_DEBUG(("Replacing ID"));
353 silc_buffer_unformat(buffer,
354 SILC_STR_UI_SHORT(&old_id_type),
355 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
356 SILC_STR_UI_SHORT(&new_id_type),
357 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
360 if (old_id_type != new_id_type)
363 if (old_id_len != silc_id_get_len(old_id_type) ||
364 new_id_len != silc_id_get_len(new_id_type))
367 id = silc_id_str2id(old_id, old_id_type);
371 id2 = silc_id_str2id(new_id, new_id_type);
375 /* If we are router and this packet is not already broadcast packet
376 we will broadcast it. The sending socket really cannot be router or
377 the router is buggy. If this packet is coming from router then it must
378 have the broadcast flag set already and we won't do anything. */
379 if (server->server_type == SILC_ROUTER &&
380 sock->type == SILC_SOCKET_TYPE_SERVER &&
381 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
382 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
383 silc_server_packet_send(server, server->router->connection, packet->type,
384 packet->flags | SILC_PACKET_FLAG_BROADCAST,
385 buffer->data, buffer->len, FALSE);
388 /* Replace the old ID */
389 switch(old_id_type) {
391 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
392 if (server->server_type == SILC_ROUTER)
393 silc_idlist_replace_client_id(server->global_list, id, id2);
397 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
398 if (server->server_type == SILC_ROUTER)
399 silc_idlist_replace_server_id(server->global_list, id, id2);
402 case SILC_ID_CHANNEL:
403 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
423 /* Received New Client packet and processes it. Creates Client ID for the
424 client. Client becomes registered after calling this functions. */
426 SilcClientEntry silc_server_new_client(SilcServer server,
427 SilcSocketConnection sock,
428 SilcPacketContext *packet)
430 SilcBuffer buffer = packet->buffer;
431 SilcClientEntry client;
432 SilcIDCacheEntry cache;
433 SilcClientID *client_id;
435 SilcIDListData idata;
436 char *username = NULL, *realname = NULL, *id_string;
438 SILC_LOG_DEBUG(("Creating new client"));
440 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
443 /* Take client entry */
444 client = (SilcClientEntry)sock->user_data;
445 idata = (SilcIDListData)client;
447 /* Fetch the old client cache entry so that we can update it. */
448 if (!silc_idcache_find_by_context(server->local_list->clients,
449 sock->user_data, &cache)) {
450 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
454 /* Parse incoming packet */
455 silc_buffer_unformat(buffer,
456 SILC_STR_UI16_STRING_ALLOC(&username),
457 SILC_STR_UI16_STRING_ALLOC(&realname),
460 /* Create Client ID */
461 silc_id_create_client_id(server->id, server->rng, server->md5hash,
462 username, &client_id);
464 /* Update client entry */
465 idata->registered = TRUE;
466 client->nickname = strdup(username);
467 client->username = username;
468 client->userinfo = realname;
469 client->id = client_id;
471 /* Update the cache entry */
472 cache->id = (void *)client_id;
473 cache->type = SILC_ID_CLIENT;
474 cache->data = username;
475 silc_idcache_sort_by_data(server->local_list->clients);
477 /* Notify our router about new client on the SILC network */
478 if (!server->standalone)
479 silc_server_send_new_id(server, (SilcSocketConnection)
480 server->router->connection,
481 server->server_type == SILC_ROUTER ? TRUE : FALSE,
482 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
484 /* Send the new client ID to the client. */
485 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
486 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
487 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
488 silc_buffer_format(reply,
489 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
490 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
491 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
493 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
494 reply->data, reply->len, FALSE);
495 silc_free(id_string);
496 silc_buffer_free(reply);
498 /* Send some nice info to the client */
499 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
500 ("Welcome to the SILC Network %s@%s",
501 username, sock->hostname));
502 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
503 ("Your host is %s, running version %s",
504 server->config->server_info->server_name,
506 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
507 ("Your connection is secured with %s cipher, "
508 "key length %d bits",
509 idata->send_key->cipher->name,
510 idata->send_key->cipher->key_len));
511 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
512 ("Your current nickname is %s",
516 silc_server_send_motd(server, sock);
521 /* Create new server. This processes received New Server packet and
522 saves the received Server ID. The server is our locally connected
523 server thus we save all the information and save it to local list.
524 This funtion can be used by both normal server and router server.
525 If normal server uses this it means that its router has connected
526 to the server. If router uses this it means that one of the cell's
527 servers is connected to the router. */
529 SilcServerEntry silc_server_new_server(SilcServer server,
530 SilcSocketConnection sock,
531 SilcPacketContext *packet)
533 SilcBuffer buffer = packet->buffer;
534 SilcServerEntry new_server;
535 SilcIDCacheEntry cache;
536 SilcServerID *server_id;
537 SilcIDListData idata;
538 unsigned char *server_name, *id_string;
539 unsigned short id_len;
541 SILC_LOG_DEBUG(("Creating new server"));
543 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
544 sock->type != SILC_SOCKET_TYPE_ROUTER)
547 /* Take server entry */
548 new_server = (SilcServerEntry)sock->user_data;
549 idata = (SilcIDListData)new_server;
551 /* Fetch the old server cache entry so that we can update it. */
552 if (!silc_idcache_find_by_context(server->local_list->servers,
553 sock->user_data, &cache)) {
554 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
558 /* Parse the incoming packet */
559 silc_buffer_unformat(buffer,
560 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
561 SILC_STR_UI16_STRING_ALLOC(&server_name),
564 if (id_len > buffer->len) {
565 silc_free(id_string);
566 silc_free(server_name);
571 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
572 silc_free(id_string);
574 /* Update client entry */
575 idata->registered = TRUE;
576 new_server->server_name = server_name;
577 new_server->id = server_id;
579 /* Update the cache entry */
580 cache->id = (void *)server_id;
581 cache->type = SILC_ID_SERVER;
582 cache->data = server_name;
583 silc_idcache_sort_by_data(server->local_list->servers);
585 /* Distribute the information about new server in the SILC network
586 to our router. If we are normal server we won't send anything
587 since this connection must be our router connection. */
588 if (server->server_type == SILC_ROUTER && !server->standalone &&
589 server->router->connection != sock)
590 silc_server_send_new_id(server, server->router->connection,
591 TRUE, new_server->id, SILC_ID_SERVER,
597 /* Processes incoming New ID packet. New ID Payload is used to distribute
598 information about newly registered clients and servers. */
600 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
601 SilcPacketContext *packet)
603 SilcBuffer buffer = packet->buffer;
605 SilcServerEntry tmpserver, router;
606 SilcSocketConnection router_sock;
609 unsigned char *hash = NULL;
612 SILC_LOG_DEBUG(("Processing new ID"));
614 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
615 server->server_type == SILC_SERVER ||
616 packet->src_id_type != SILC_ID_SERVER)
619 idp = silc_id_payload_parse(buffer);
623 id_type = silc_id_payload_get_type(idp);
625 /* Normal server cannot have other normal server connections */
626 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
629 id = silc_id_payload_get_id(idp);
633 /* If the sender of this packet is server and we are router we need to
634 broadcast this packet to other routers in the network. */
635 if (!server->standalone && server->server_type == SILC_ROUTER &&
636 sock->type == SILC_SOCKET_TYPE_SERVER &&
637 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
638 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
639 silc_server_packet_send(server, server->router->connection,
641 packet->flags | SILC_PACKET_FLAG_BROADCAST,
642 buffer->data, buffer->len, FALSE);
646 /* If the packet is originated from the one who sent it to us we know
647 that the ID belongs to our cell, unless the sender was router. */
648 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
649 tmpserver = (SilcServerEntry)sock->user_data;
651 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
652 sock->type == SILC_SOCKET_TYPE_SERVER) {
653 id_list = server->local_list;
655 router = sock->user_data;
656 /* router = server->id_entry; */
658 id_list = server->global_list;
659 router_sock = (SilcSocketConnection)server->router->connection;
660 router = server->router;
666 if (sock->type == SILC_SOCKET_TYPE_SERVER)
667 id_list = server->local_list;
669 id_list = server->global_list;
672 router = sock->user_data;
676 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
677 silc_id_render(id, SILC_ID_CLIENT),
678 sock->type == SILC_SOCKET_TYPE_SERVER ?
679 "Server" : "Router", sock->hostname));
681 /* As a router we keep information of all global information in our global
682 list. Cell wide information however is kept in the local list. The
683 client is put to global list and we will take the hash value of the
684 Client ID and save it to the ID Cache system for fast searching in the
686 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
687 sizeof(unsigned char));
688 memcpy(hash, ((SilcClientID *)id)->hash,
689 sizeof(((SilcClientID *)id)->hash));
690 silc_idlist_add_client(id_list, hash, NULL, NULL, id, router, router_sock);
693 /* XXX Adding two ID's with same IP number replaces the old entry thus
694 gives wrong route. Thus, now disabled until figured out a better way
695 to do this or when removed the whole thing. This could be removed
696 because entry->router->connection gives always the most optimal route
697 for the ID anyway (unless new routes (faster perhaps) are established
698 after receiving this ID, this we don't know however). */
699 /* Add route cache for this ID */
700 silc_server_route_add(silc_server_route_hash(
701 ((SilcClientID *)id)->ip.s_addr,
702 server->id->port), ((SilcClientID *)id)->ip.s_addr,
708 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
709 silc_id_render(id, SILC_ID_SERVER),
710 sock->type == SILC_SOCKET_TYPE_SERVER ?
711 "Server" : "Router", sock->hostname));
713 /* As a router we keep information of all global information in our global
714 list. Cell wide information however is kept in the local list. */
715 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
718 /* Add route cache for this ID */
719 silc_server_route_add(silc_server_route_hash(
720 ((SilcServerID *)id)->ip.s_addr,
721 ((SilcServerID *)id)->port),
722 ((SilcServerID *)id)->ip.s_addr,
727 case SILC_ID_CHANNEL:
728 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
736 silc_id_payload_free(idp);
739 /* Received Remove Channel User packet to remove a user from a channel.
740 Routers notify other routers that user has left a channel. Client must
741 not send this packet.. Normal server may send this packet but must not
744 void silc_server_remove_channel_user(SilcServer server,
745 SilcSocketConnection sock,
746 SilcPacketContext *packet)
748 SilcBuffer buffer = packet->buffer;
749 unsigned char *tmp1 = NULL, *tmp2 = NULL;
750 SilcClientID *client_id = NULL;
751 SilcChannelID *channel_id = NULL;
752 SilcChannelEntry channel;
753 SilcClientEntry client;
755 SILC_LOG_DEBUG(("Removing user from channel"));
757 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
758 server->server_type == SILC_SERVER)
761 silc_buffer_unformat(buffer,
762 SILC_STR_UI16_STRING_ALLOC(&tmp1),
763 SILC_STR_UI16_STRING_ALLOC(&tmp2),
769 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
770 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
771 if (!client_id || !channel_id)
774 /* If we are router and this packet is not already broadcast packet
775 we will broadcast it. The sending socket really cannot be router or
776 the router is buggy. If this packet is coming from router then it must
777 have the broadcast flag set already and we won't do anything. */
778 if (!server->standalone && server->server_type == SILC_ROUTER &&
779 sock->type == SILC_SOCKET_TYPE_SERVER &&
780 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
781 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
782 silc_server_packet_send(server, server->router->connection, packet->type,
783 packet->flags | SILC_PACKET_FLAG_BROADCAST,
784 buffer->data, buffer->len, FALSE);
787 /* XXX routers should check server->global_list as well */
788 /* Get channel entry */
789 channel = silc_idlist_find_channel_by_id(server->local_list,
794 /* XXX routers should check server->global_list as well */
795 /* Get client entry */
796 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
800 /* Remove from channel */
801 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
809 silc_free(client_id);
811 silc_free(channel_id);
814 /* Received New Channel packet. Information about new channels in the
815 network are distributed using this packet. Save the information about
818 void silc_server_new_channel(SilcServer server,
819 SilcSocketConnection sock,
820 SilcPacketContext *packet)
823 SilcChannelID *channel_id;
824 unsigned short channel_id_len;
827 SILC_LOG_DEBUG(("Processing New Channel"));
829 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
830 server->server_type == SILC_SERVER ||
831 packet->src_id_type != SILC_ID_SERVER)
835 if (!silc_buffer_unformat(packet->buffer,
836 SILC_STR_UI16_STRING_ALLOC(&channel_name),
837 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
841 if (!channel_name || !id)
844 /* Decode the channel ID */
845 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
850 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
851 silc_id_render(channel_id, SILC_ID_CHANNEL),
854 /* Add the new channel. Add it always to global list since if we receive
855 this packet then it cannot be created by ourselves but some other
856 router hence global channel. */
857 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
858 server->router->connection, NULL);
861 /* Received notify packet. Server can receive notify packets from router.
862 Server then relays the notify messages to clients if needed. */
864 void silc_server_notify(SilcServer server,
865 SilcSocketConnection sock,
866 SilcPacketContext *packet)
868 SilcNotifyPayload payload;
870 SilcArgumentPayload args;
871 SilcChannelID *channel_id;
872 SilcChannelEntry channel;
874 SILC_LOG_DEBUG(("Start"));
876 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
877 packet->src_id_type != SILC_ID_SERVER)
880 /* XXX: For now we expect that the we are normal server and that the
881 sender is router. Server could send (protocol allows it) notify to
882 router but we don't support it yet. */
883 if (server->server_type != SILC_SERVER &&
884 sock->type != SILC_SOCKET_TYPE_ROUTER)
887 payload = silc_notify_payload_parse(packet->buffer);
891 type = silc_notify_get_type(payload);
892 args = silc_notify_get_args(payload);
897 case SILC_NOTIFY_TYPE_JOIN:
899 * Distribute the notify to local clients on the channel
902 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
906 /* Get channel entry */
907 channel = silc_idlist_find_channel_by_id(server->local_list,
910 silc_free(channel_id);
914 /* Send to channel */
915 silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
916 packet->buffer->data,
917 packet->buffer->len, FALSE);
920 case SILC_NOTIFY_TYPE_LEAVE:
923 case SILC_NOTIFY_TYPE_SIGNOFF:
926 /* Ignore rest notify types for now */
927 case SILC_NOTIFY_TYPE_NONE:
928 case SILC_NOTIFY_TYPE_INVITE:
929 case SILC_NOTIFY_TYPE_TOPIC_SET:
930 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
931 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
932 case SILC_NOTIFY_TYPE_MOTD:
938 silc_notify_payload_free(payload);
941 /* Received new channel user packet. Information about new users on a
942 channel are distributed between routers using this packet. The
943 router receiving this will redistribute it and also sent JOIN notify
944 to local clients on the same channel. Normal server sends JOIN notify
945 to its local clients on the channel. */
947 void silc_server_new_channel_user(SilcServer server,
948 SilcSocketConnection sock,
949 SilcPacketContext *packet)
951 unsigned char *tmpid1, *tmpid2;
952 SilcClientID *client_id = NULL;
953 SilcChannelID *channel_id = NULL;
954 unsigned short channel_id_len;
955 unsigned short client_id_len;
956 SilcClientEntry client;
957 SilcChannelEntry channel;
958 SilcChannelClientEntry chl;
960 SilcServerEntry tmpserver, router;
961 SilcSocketConnection router_sock;
965 SILC_LOG_DEBUG(("Start"));
967 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
968 server->server_type != SILC_ROUTER ||
969 packet->src_id_type != SILC_ID_SERVER)
973 if (!silc_buffer_unformat(packet->buffer,
974 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
976 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
981 if (!tmpid1 || !tmpid2)
984 /* Decode the channel ID */
985 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
989 /* Decode the client ID */
990 client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
994 /* If the packet is originated from the one who sent it to us we know
995 that the ID belongs to our cell, unless the sender was router. */
996 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
997 tmpserver = (SilcServerEntry)sock->user_data;
999 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
1000 sock->type == SILC_SOCKET_TYPE_SERVER) {
1001 id_list = server->local_list;
1003 router = sock->user_data;
1005 id_list = server->global_list;
1006 router_sock = (SilcSocketConnection)server->router->connection;
1007 router = server->router;
1011 /* Find the channel */
1012 channel = silc_idlist_find_channel_by_id(id_list, channel_id, NULL);
1014 SILC_LOG_ERROR(("Received channel user for non-existent channel"));
1018 /* If we are router and this packet is not already broadcast packet
1019 we will broadcast it. */
1020 if (!server->standalone && server->server_type == SILC_ROUTER &&
1021 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1022 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1023 silc_server_packet_send(server, server->router->connection, packet->type,
1024 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1025 packet->buffer->data, packet->buffer->len, FALSE);
1028 /* Get client entry */
1029 client = silc_idlist_find_client_by_id(id_list, client_id, NULL);
1031 /* This is new client to us, add entry to ID list */
1032 client = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1033 client_id, router, router_sock);
1038 /* Join the client to the channel by adding it to channel's user list.
1039 Add also the channel to client entry's channels list for fast cross-
1041 chl = silc_calloc(1, sizeof(*chl));
1042 chl->client = client;
1043 chl->channel = channel;
1044 silc_list_add(channel->user_list, chl);
1045 silc_list_add(client->channels, chl);
1047 /* Send JOIN notify to local clients on the channel. As we are router
1048 it is assured that this is sent only to our local clients and locally
1049 connected servers if needed. */
1050 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1051 silc_server_send_notify_to_channel(server, channel, FALSE,
1052 SILC_NOTIFY_TYPE_JOIN,
1053 1, clidp->data, clidp->len);
1054 silc_buffer_free(clidp);
1060 silc_free(client_id);
1062 silc_free(channel_id);