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 /* 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_command_reply(SilcServer server,
135 SilcSocketConnection sock,
136 SilcPacketContext *packet)
138 SilcBuffer buffer = packet->buffer;
139 SilcClientEntry client = NULL;
140 SilcSocketConnection dst_sock;
141 SilcIDListData idata;
142 SilcClientID *id = NULL;
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 if (packet->dst_id_type == SILC_ID_CHANNEL)
154 if (packet->dst_id_type == SILC_ID_CLIENT) {
155 /* Destination must be one of ours */
156 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
157 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
159 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
165 if (packet->dst_id_type == SILC_ID_SERVER) {
166 /* For now this must be for us */
167 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
168 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
173 /* Execute command reply locally for the command */
174 silc_server_command_reply_process(server, sock, buffer);
176 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
177 /* Relay the packet to the client */
179 dst_sock = (SilcSocketConnection)client->connection;
180 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
181 + packet->dst_id_len + packet->padlen);
183 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
184 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
186 idata = (SilcIDListData)client;
189 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
192 /* Send the packet */
193 silc_server_packet_send_real(server, dst_sock, TRUE);
199 /* Process received channel message. The message can be originated from
202 void silc_server_channel_message(SilcServer server,
203 SilcSocketConnection sock,
204 SilcPacketContext *packet)
206 SilcChannelEntry channel = NULL;
207 SilcChannelClientEntry chl;
208 SilcChannelID *id = NULL;
211 SILC_LOG_DEBUG(("Processing channel message"));
214 if (packet->dst_id_type != SILC_ID_CHANNEL) {
215 SILC_LOG_ERROR(("Received bad message for channel, dropped"));
216 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
220 /* Find channel entry */
221 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
222 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
224 SILC_LOG_DEBUG(("Could not find channel"));
228 /* See that this client is on the channel. If the message is coming
229 from router we won't do the check as the message is from client that
230 we don't know about. Also, if the original sender is not client
231 (as it can be server as well) we don't do the check. */
232 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
233 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
234 packet->src_id_type == SILC_ID_CLIENT) {
235 silc_list_start(channel->user_list);
236 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
237 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
240 if (chl == SILC_LIST_END)
244 /* Distribute the packet to our local clients. This will send the
245 packet for further routing as well, if needed. */
246 silc_server_packet_relay_to_channel(server, sock, channel, sender,
248 packet->buffer->data,
249 packet->buffer->len, FALSE);
258 /* Received channel key packet. We distribute the key to all of our locally
259 connected clients on the channel. */
261 void silc_server_channel_key(SilcServer server,
262 SilcSocketConnection sock,
263 SilcPacketContext *packet)
265 SilcBuffer buffer = packet->buffer;
266 SilcChannelKeyPayload payload = NULL;
267 SilcChannelID *id = NULL;
268 SilcChannelEntry channel;
269 SilcChannelClientEntry chl;
271 unsigned int tmp_len;
275 if (packet->src_id_type != SILC_ID_SERVER)
278 /* Decode channel key payload */
279 payload = silc_channel_key_payload_parse(buffer);
281 SILC_LOG_ERROR(("Bad channel key payload, dropped"));
286 tmp = silc_channel_key_get_id(payload, &tmp_len);
287 id = silc_id_payload_parse_id(tmp, tmp_len);
291 /* Get the channel entry */
292 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
294 SILC_LOG_ERROR(("Received key for non-existent channel"));
298 tmp = silc_channel_key_get_key(payload, &tmp_len);
302 cipher = silc_channel_key_get_cipher(payload, NULL);;
306 /* Remove old key if exists */
308 memset(channel->key, 0, channel->key_len);
309 silc_free(channel->key);
310 silc_cipher_free(channel->channel_key);
314 /* Create new cipher */
315 if (!silc_cipher_alloc(cipher, &channel->channel_key))
319 channel->key_len = tmp_len * 8;
320 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
321 memcpy(channel->key, tmp, tmp_len);
322 channel->channel_key->cipher->set_key(channel->channel_key->context,
325 /* Distribute the key to everybody who is on the channel. If we are router
326 we will also send it to locally connected servers. */
327 silc_server_send_channel_key(server, channel, FALSE);
333 silc_channel_key_payload_free(payload);
336 /* Received packet to replace a ID. This checks that the requested ID
337 exists and replaces it with the new one. */
339 void silc_server_replace_id(SilcServer server,
340 SilcSocketConnection sock,
341 SilcPacketContext *packet)
343 SilcBuffer buffer = packet->buffer;
344 unsigned char *old_id = NULL, *new_id = NULL;
345 SilcIdType old_id_type, new_id_type;
346 unsigned short old_id_len, new_id_len;
347 void *id = NULL, *id2 = NULL;
349 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
350 packet->src_id_type == SILC_ID_CLIENT)
353 SILC_LOG_DEBUG(("Replacing ID"));
355 silc_buffer_unformat(buffer,
356 SILC_STR_UI_SHORT(&old_id_type),
357 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
358 SILC_STR_UI_SHORT(&new_id_type),
359 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
362 if (old_id_type != new_id_type)
365 if (old_id_len != silc_id_get_len(old_id_type) ||
366 new_id_len != silc_id_get_len(new_id_type))
369 id = silc_id_str2id(old_id, old_id_type);
373 id2 = silc_id_str2id(new_id, new_id_type);
377 /* If we are router and this packet is not already broadcast packet
378 we will broadcast it. The sending socket really cannot be router or
379 the router is buggy. If this packet is coming from router then it must
380 have the broadcast flag set already and we won't do anything. */
381 if (server->server_type == SILC_ROUTER &&
382 sock->type == SILC_SOCKET_TYPE_SERVER &&
383 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
384 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
385 silc_server_packet_send(server, server->router->connection, packet->type,
386 packet->flags | SILC_PACKET_FLAG_BROADCAST,
387 buffer->data, buffer->len, FALSE);
390 /* Replace the old ID */
391 switch(old_id_type) {
393 if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
394 if (server->server_type == SILC_ROUTER)
395 silc_idlist_replace_client_id(server->global_list, id, id2);
399 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
400 if (server->server_type == SILC_ROUTER)
401 silc_idlist_replace_server_id(server->global_list, id, id2);
404 case SILC_ID_CHANNEL:
405 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
425 /* Received New Client packet and processes it. Creates Client ID for the
426 client. Client becomes registered after calling this functions. */
428 SilcClientEntry silc_server_new_client(SilcServer server,
429 SilcSocketConnection sock,
430 SilcPacketContext *packet)
432 SilcBuffer buffer = packet->buffer;
433 SilcClientEntry client;
434 SilcIDCacheEntry cache;
435 SilcClientID *client_id;
437 SilcIDListData idata;
438 char *username = NULL, *realname = NULL, *id_string;
440 SILC_LOG_DEBUG(("Creating new client"));
442 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
445 /* Take client entry */
446 client = (SilcClientEntry)sock->user_data;
447 idata = (SilcIDListData)client;
449 /* Fetch the old client cache entry so that we can update it. */
450 if (!silc_idcache_find_by_context(server->local_list->clients,
451 sock->user_data, &cache)) {
452 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
456 /* Parse incoming packet */
457 silc_buffer_unformat(buffer,
458 SILC_STR_UI16_STRING_ALLOC(&username),
459 SILC_STR_UI16_STRING_ALLOC(&realname),
462 /* Create Client ID */
463 silc_id_create_client_id(server->id, server->rng, server->md5hash,
464 username, &client_id);
466 /* Update client entry */
467 idata->registered = TRUE;
468 client->nickname = strdup(username);
469 client->username = username;
470 client->userinfo = realname;
471 client->id = client_id;
473 /* Update the cache entry */
474 cache->id = (void *)client_id;
475 cache->type = SILC_ID_CLIENT;
476 cache->data = username;
477 silc_idcache_sort_by_data(server->local_list->clients);
479 /* Notify our router about new client on the SILC network */
480 if (!server->standalone)
481 silc_server_send_new_id(server, (SilcSocketConnection)
482 server->router->connection,
483 server->server_type == SILC_ROUTER ? TRUE : FALSE,
484 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
486 /* Send the new client ID to the client. */
487 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
488 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
489 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
490 silc_buffer_format(reply,
491 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
492 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
493 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
495 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
496 reply->data, reply->len, FALSE);
497 silc_free(id_string);
498 silc_buffer_free(reply);
500 /* Send some nice info to the client */
501 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
502 ("Welcome to the SILC Network %s@%s",
503 username, sock->hostname));
504 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
505 ("Your host is %s, running version %s",
506 server->config->server_info->server_name,
508 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
509 ("Your connection is secured with %s cipher, "
510 "key length %d bits",
511 idata->send_key->cipher->name,
512 idata->send_key->cipher->key_len));
513 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
514 ("Your current nickname is %s",
518 silc_server_send_motd(server, sock);
523 /* Create new server. This processes received New Server packet and
524 saves the received Server ID. The server is our locally connected
525 server thus we save all the information and save it to local list.
526 This funtion can be used by both normal server and router server.
527 If normal server uses this it means that its router has connected
528 to the server. If router uses this it means that one of the cell's
529 servers is connected to the router. */
531 SilcServerEntry silc_server_new_server(SilcServer server,
532 SilcSocketConnection sock,
533 SilcPacketContext *packet)
535 SilcBuffer buffer = packet->buffer;
536 SilcServerEntry new_server;
537 SilcIDCacheEntry cache;
538 SilcServerID *server_id;
539 SilcIDListData idata;
540 unsigned char *server_name, *id_string;
541 unsigned short id_len;
543 SILC_LOG_DEBUG(("Creating new server"));
545 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
546 sock->type != SILC_SOCKET_TYPE_ROUTER)
549 /* Take server entry */
550 new_server = (SilcServerEntry)sock->user_data;
551 idata = (SilcIDListData)new_server;
553 /* Fetch the old server cache entry so that we can update it. */
554 if (!silc_idcache_find_by_context(server->local_list->servers,
555 sock->user_data, &cache)) {
556 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
560 /* Parse the incoming packet */
561 silc_buffer_unformat(buffer,
562 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
563 SILC_STR_UI16_STRING_ALLOC(&server_name),
566 if (id_len > buffer->len) {
567 silc_free(id_string);
568 silc_free(server_name);
573 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
574 silc_free(id_string);
576 /* Update client entry */
577 idata->registered = TRUE;
578 new_server->server_name = server_name;
579 new_server->id = server_id;
581 /* Update the cache entry */
582 cache->id = (void *)server_id;
583 cache->type = SILC_ID_SERVER;
584 cache->data = server_name;
585 silc_idcache_sort_by_data(server->local_list->servers);
587 /* Distribute the information about new server in the SILC network
588 to our router. If we are normal server we won't send anything
589 since this connection must be our router connection. */
590 if (server->server_type == SILC_ROUTER && !server->standalone &&
591 server->router->connection != sock)
592 silc_server_send_new_id(server, server->router->connection,
593 TRUE, new_server->id, SILC_ID_SERVER,
599 /* Processes incoming New ID packet. New ID Payload is used to distribute
600 information about newly registered clients and servers. */
602 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
603 SilcPacketContext *packet)
605 SilcBuffer buffer = packet->buffer;
607 SilcServerEntry tmpserver, router;
608 SilcSocketConnection router_sock;
611 unsigned char *hash = NULL;
614 SILC_LOG_DEBUG(("Processing new ID"));
616 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
617 server->server_type == SILC_SERVER ||
618 packet->src_id_type != SILC_ID_SERVER)
621 idp = silc_id_payload_parse(buffer);
625 id_type = silc_id_payload_get_type(idp);
627 /* Normal server cannot have other normal server connections */
628 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
631 id = silc_id_payload_get_id(idp);
635 /* If the sender of this packet is server and we are router we need to
636 broadcast this packet to other routers in the network. */
637 if (!server->standalone && server->server_type == SILC_ROUTER &&
638 sock->type == SILC_SOCKET_TYPE_SERVER &&
639 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
640 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
641 silc_server_packet_send(server, server->router->connection,
643 packet->flags | SILC_PACKET_FLAG_BROADCAST,
644 buffer->data, buffer->len, FALSE);
648 /* If the packet is originated from the one who sent it to us we know
649 that the ID belongs to our cell, unless the sender was router. */
650 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
651 tmpserver = (SilcServerEntry)sock->user_data;
653 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
654 sock->type == SILC_SOCKET_TYPE_SERVER) {
655 id_list = server->local_list;
657 router = sock->user_data;
658 /* router = server->id_entry; */
660 id_list = server->global_list;
661 router_sock = (SilcSocketConnection)server->router->connection;
662 router = server->router;
668 if (sock->type == SILC_SOCKET_TYPE_SERVER)
669 id_list = server->local_list;
671 id_list = server->global_list;
674 router = sock->user_data;
678 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
679 silc_id_render(id, SILC_ID_CLIENT),
680 sock->type == SILC_SOCKET_TYPE_SERVER ?
681 "Server" : "Router", sock->hostname));
683 /* As a router we keep information of all global information in our global
684 list. Cell wide information however is kept in the local list. The
685 client is put to global list and we will take the hash value of the
686 Client ID and save it to the ID Cache system for fast searching in the
688 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
689 sizeof(unsigned char));
690 memcpy(hash, ((SilcClientID *)id)->hash,
691 sizeof(((SilcClientID *)id)->hash));
692 silc_idlist_add_client(id_list, hash, NULL, NULL, id, router, router_sock);
695 /* XXX Adding two ID's with same IP number replaces the old entry thus
696 gives wrong route. Thus, now disabled until figured out a better way
697 to do this or when removed the whole thing. This could be removed
698 because entry->router->connection gives always the most optimal route
699 for the ID anyway (unless new routes (faster perhaps) are established
700 after receiving this ID, this we don't know however). */
701 /* Add route cache for this ID */
702 silc_server_route_add(silc_server_route_hash(
703 ((SilcClientID *)id)->ip.s_addr,
704 server->id->port), ((SilcClientID *)id)->ip.s_addr,
710 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
711 silc_id_render(id, SILC_ID_SERVER),
712 sock->type == SILC_SOCKET_TYPE_SERVER ?
713 "Server" : "Router", sock->hostname));
715 /* As a router we keep information of all global information in our global
716 list. Cell wide information however is kept in the local list. */
717 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
720 /* Add route cache for this ID */
721 silc_server_route_add(silc_server_route_hash(
722 ((SilcServerID *)id)->ip.s_addr,
723 ((SilcServerID *)id)->port),
724 ((SilcServerID *)id)->ip.s_addr,
729 case SILC_ID_CHANNEL:
730 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
738 silc_id_payload_free(idp);
741 /* Received Remove Channel User packet to remove a user from a channel.
742 Routers notify other routers that user has left a channel. Client must
743 not send this packet.. Normal server may send this packet but must not
746 void silc_server_remove_channel_user(SilcServer server,
747 SilcSocketConnection sock,
748 SilcPacketContext *packet)
750 SilcBuffer buffer = packet->buffer;
751 unsigned char *tmp1 = NULL, *tmp2 = NULL;
752 SilcClientID *client_id = NULL;
753 SilcChannelID *channel_id = NULL;
754 SilcChannelEntry channel;
755 SilcClientEntry client;
757 SILC_LOG_DEBUG(("Removing user from channel"));
759 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
760 server->server_type == SILC_SERVER)
763 silc_buffer_unformat(buffer,
764 SILC_STR_UI16_STRING_ALLOC(&tmp1),
765 SILC_STR_UI16_STRING_ALLOC(&tmp2),
771 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
772 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
773 if (!client_id || !channel_id)
776 /* If we are router and this packet is not already broadcast packet
777 we will broadcast it. The sending socket really cannot be router or
778 the router is buggy. If this packet is coming from router then it must
779 have the broadcast flag set already and we won't do anything. */
780 if (!server->standalone && server->server_type == SILC_ROUTER &&
781 sock->type == SILC_SOCKET_TYPE_SERVER &&
782 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
783 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
784 silc_server_packet_send(server, server->router->connection, packet->type,
785 packet->flags | SILC_PACKET_FLAG_BROADCAST,
786 buffer->data, buffer->len, FALSE);
789 /* XXX routers should check server->global_list as well */
790 /* Get channel entry */
791 channel = silc_idlist_find_channel_by_id(server->local_list,
796 /* XXX routers should check server->global_list as well */
797 /* Get client entry */
798 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
802 /* Remove from channel */
803 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
811 silc_free(client_id);
813 silc_free(channel_id);
816 /* Received New Channel packet. Information about new channels in the
817 network are distributed using this packet. Save the information about
820 void silc_server_new_channel(SilcServer server,
821 SilcSocketConnection sock,
822 SilcPacketContext *packet)
825 SilcChannelID *channel_id;
826 unsigned short channel_id_len;
829 SILC_LOG_DEBUG(("Processing New Channel"));
831 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
832 server->server_type == SILC_SERVER ||
833 packet->src_id_type != SILC_ID_SERVER)
837 if (!silc_buffer_unformat(packet->buffer,
838 SILC_STR_UI16_STRING_ALLOC(&channel_name),
839 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
843 if (!channel_name || !id)
846 /* Decode the channel ID */
847 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
852 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
853 silc_id_render(channel_id, SILC_ID_CHANNEL),
856 /* Add the new channel. Add it always to global list since if we receive
857 this packet then it cannot be created by ourselves but some other
858 router hence global channel. */
859 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
860 server->router->connection, NULL);
863 /* Received notify packet. Server can receive notify packets from router.
864 Server then relays the notify messages to clients if needed. */
866 void silc_server_notify(SilcServer server,
867 SilcSocketConnection sock,
868 SilcPacketContext *packet)
870 SilcNotifyPayload payload;
872 SilcArgumentPayload args;
873 SilcChannelID *channel_id;
874 SilcChannelEntry channel;
876 SILC_LOG_DEBUG(("Start"));
878 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
879 packet->src_id_type != SILC_ID_SERVER)
882 /* XXX: For now we expect that the we are normal server and that the
883 sender is router. Server could send (protocol allows it) notify to
884 router but we don't support it yet. */
885 if (server->server_type != SILC_SERVER &&
886 sock->type != SILC_SOCKET_TYPE_ROUTER)
889 payload = silc_notify_payload_parse(packet->buffer);
893 type = silc_notify_get_type(payload);
894 args = silc_notify_get_args(payload);
899 case SILC_NOTIFY_TYPE_JOIN:
901 * Distribute the notify to local clients on the channel
904 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
908 /* Get channel entry */
909 channel = silc_idlist_find_channel_by_id(server->local_list,
912 silc_free(channel_id);
916 /* Send to channel */
917 silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
918 packet->buffer->data,
919 packet->buffer->len, FALSE);
922 case SILC_NOTIFY_TYPE_LEAVE:
925 case SILC_NOTIFY_TYPE_SIGNOFF:
928 /* Ignore rest notify types for now */
929 case SILC_NOTIFY_TYPE_NONE:
930 case SILC_NOTIFY_TYPE_INVITE:
931 case SILC_NOTIFY_TYPE_TOPIC_SET:
932 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
933 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
934 case SILC_NOTIFY_TYPE_MOTD:
940 silc_notify_payload_free(payload);
943 /* Received new channel user packet. Information about new users on a
944 channel are distributed between routers using this packet. The
945 router receiving this will redistribute it and also sent JOIN notify
946 to local clients on the same channel. Normal server sends JOIN notify
947 to its local clients on the channel. */
949 void silc_server_new_channel_user(SilcServer server,
950 SilcSocketConnection sock,
951 SilcPacketContext *packet)
953 unsigned char *tmpid1, *tmpid2;
954 SilcClientID *client_id = NULL;
955 SilcChannelID *channel_id = NULL;
956 unsigned short channel_id_len;
957 unsigned short client_id_len;
958 SilcClientEntry client;
959 SilcChannelEntry channel;
960 SilcChannelClientEntry chl;
962 SilcServerEntry tmpserver, router;
963 SilcSocketConnection router_sock;
967 SILC_LOG_DEBUG(("Start"));
969 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
970 server->server_type != SILC_ROUTER ||
971 packet->src_id_type != SILC_ID_SERVER)
975 if (!silc_buffer_unformat(packet->buffer,
976 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
978 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
983 if (!tmpid1 || !tmpid2)
986 /* Decode the channel ID */
987 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
991 /* Decode the client ID */
992 client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
996 /* If the packet is originated from the one who sent it to us we know
997 that the ID belongs to our cell, unless the sender was router. */
998 tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
999 tmpserver = (SilcServerEntry)sock->user_data;
1001 if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
1002 sock->type == SILC_SOCKET_TYPE_SERVER) {
1003 id_list = server->local_list;
1005 router = sock->user_data;
1007 id_list = server->global_list;
1008 router_sock = (SilcSocketConnection)server->router->connection;
1009 router = server->router;
1013 /* Find the channel */
1014 channel = silc_idlist_find_channel_by_id(id_list, channel_id, NULL);
1016 SILC_LOG_ERROR(("Received channel user for non-existent channel"));
1020 /* If we are router and this packet is not already broadcast packet
1021 we will broadcast it. */
1022 if (!server->standalone && server->server_type == SILC_ROUTER &&
1023 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1024 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1025 silc_server_packet_send(server, server->router->connection, packet->type,
1026 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1027 packet->buffer->data, packet->buffer->len, FALSE);
1030 /* Get client entry */
1031 client = silc_idlist_find_client_by_id(id_list, client_id, NULL);
1033 /* This is new client to us, add entry to ID list */
1034 client = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1035 client_id, router, router_sock);
1040 /* Join the client to the channel by adding it to channel's user list.
1041 Add also the channel to client entry's channels list for fast cross-
1043 chl = silc_calloc(1, sizeof(*chl));
1044 chl->client = client;
1045 chl->channel = channel;
1046 silc_list_add(channel->user_list, chl);
1047 silc_list_add(client->channels, chl);
1049 /* Send JOIN notify to local clients on the channel. As we are router
1050 it is assured that this is sent only to our local clients and locally
1051 connected servers if needed. */
1052 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1053 silc_server_send_notify_to_channel(server, channel, FALSE,
1054 SILC_NOTIFY_TYPE_JOIN,
1055 1, clidp->data, clidp->len);
1056 silc_buffer_free(clidp);
1062 silc_free(client_id);
1064 silc_free(channel_id);