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"));
51 /* Decode destination Client ID */
52 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
54 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
58 /* If the destination belongs to our server we don't have to route
59 the message anywhere but to send it to the local destination. */
60 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
62 /* It exists, now deliver the message to the destination */
63 dst_sock = (SilcSocketConnection)client->connection;
65 /* If we are router and the client has router then the client is in
66 our cell but not directly connected to us. */
67 if (server->server_type == SILC_ROUTER && client->router) {
68 /* We are of course in this case the client's router thus the real
69 "router" of the client is the server who owns the client. Thus
70 we will send the packet to that server. */
71 router = (SilcServerEntry)dst_sock->user_data;
72 idata = (SilcIDListData)router;
74 silc_server_send_private_message(server, dst_sock,
81 /* Seems that client really is directly connected to us */
82 idata = (SilcIDListData)client;
83 silc_server_send_private_message(server, dst_sock,
89 /* Destination belongs to someone not in this server. If we are normal
90 server our action is to send the packet to our router. */
91 if (server->server_type == SILC_SERVER && !server->standalone) {
92 router = server->router;
94 /* Send to primary route */
96 dst_sock = (SilcSocketConnection)router->connection;
97 idata = (SilcIDListData)router;
98 silc_server_send_private_message(server, dst_sock,
100 idata->hmac, packet);
105 /* We are router and we will perform route lookup for the destination
106 and send the message to fastest route. */
107 if (server->server_type == SILC_ROUTER && !server->standalone) {
108 /* Check first that the ID is valid */
109 client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
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);
125 silc_server_send_error(server, sock,
126 "No such nickname: Private message not sent");
129 /* Processes incoming command reply packet. The command reply packet may
130 be destined to one of our clients or it may directly for us. We will
131 call the command reply routine after processing the packet. */
133 void silc_server_command_reply(SilcServer server,
134 SilcSocketConnection sock,
135 SilcPacketContext *packet)
137 SilcBuffer buffer = packet->buffer;
138 SilcClientEntry client = NULL;
139 SilcSocketConnection dst_sock;
140 SilcIDListData idata;
141 SilcClientID *id = NULL;
143 SILC_LOG_DEBUG(("Start"));
145 /* Source must be server or router */
146 if (packet->src_id_type != SILC_ID_SERVER &&
147 sock->type != SILC_SOCKET_TYPE_ROUTER)
150 if (packet->dst_id_type == SILC_ID_CHANNEL)
153 if (packet->dst_id_type == SILC_ID_CLIENT) {
154 /* Destination must be one of ours */
155 id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
156 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
158 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
164 if (packet->dst_id_type == SILC_ID_SERVER) {
165 /* For now this must be for us */
166 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
167 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
172 /* Execute command reply locally for the command */
173 silc_server_command_reply_process(server, sock, buffer);
175 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
176 /* Relay the packet to the client */
178 dst_sock = (SilcSocketConnection)client->connection;
179 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
180 + packet->dst_id_len + packet->padlen);
182 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
183 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
185 idata = (SilcIDListData)client;
188 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
191 /* Send the packet */
192 silc_server_packet_send_real(server, dst_sock, TRUE);
198 /* Process received channel message. The message can be originated from
201 void silc_server_channel_message(SilcServer server,
202 SilcSocketConnection sock,
203 SilcPacketContext *packet)
205 SilcChannelEntry channel = NULL;
206 SilcChannelClientEntry chl;
207 SilcChannelID *id = NULL;
210 SILC_LOG_DEBUG(("Processing channel message"));
213 if (packet->dst_id_type != SILC_ID_CHANNEL) {
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 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
224 SILC_LOG_DEBUG(("Could not find channel"));
229 /* See that this client is on the channel. If the message is coming
230 from router we won't do the check as the message is from client that
231 we don't know about. Also, if the original sender is not client
232 (as it can be server as well) we don't do the check. */
233 sender = silc_id_str2id(packet->src_id, packet->src_id_type);
234 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
235 packet->src_id_type == SILC_ID_CLIENT) {
236 silc_list_start(channel->user_list);
237 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
238 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
241 if (chl == SILC_LIST_END)
245 /* Distribute the packet to our local clients. This will send the
246 packet for further routing as well, if needed. */
247 silc_server_packet_relay_to_channel(server, sock, channel, sender,
249 packet->buffer->data,
250 packet->buffer->len, FALSE);
259 /* Received channel key packet. We distribute the key to all of our locally
260 connected clients on the channel. */
262 void silc_server_channel_key(SilcServer server,
263 SilcSocketConnection sock,
264 SilcPacketContext *packet)
266 SilcBuffer buffer = packet->buffer;
267 SilcChannelEntry channel;
269 if (packet->src_id_type != SILC_ID_SERVER)
272 /* Save the channel key */
273 channel = silc_server_save_channel_key(server, buffer, NULL);
277 /* Distribute the key to everybody who is on the channel. If we are router
278 we will also send it to locally connected servers. */
279 silc_server_send_channel_key(server, sock, channel, FALSE);
282 /* Received packet to replace a ID. This checks that the requested ID
283 exists and replaces it with the new one. */
285 void silc_server_replace_id(SilcServer server,
286 SilcSocketConnection sock,
287 SilcPacketContext *packet)
289 SilcBuffer buffer = packet->buffer;
290 unsigned char *old_id = NULL, *new_id = NULL;
291 SilcIdType old_id_type, new_id_type;
292 unsigned short old_id_len, new_id_len;
293 void *id = NULL, *id2 = NULL;
295 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
296 packet->src_id_type == SILC_ID_CLIENT)
299 SILC_LOG_DEBUG(("Replacing ID"));
301 silc_buffer_unformat(buffer,
302 SILC_STR_UI_SHORT(&old_id_type),
303 SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
304 SILC_STR_UI_SHORT(&new_id_type),
305 SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
308 if (old_id_type != new_id_type)
311 if (old_id_len != silc_id_get_len(old_id_type) ||
312 new_id_len != silc_id_get_len(new_id_type))
315 id = silc_id_str2id(old_id, old_id_type);
319 id2 = silc_id_str2id(new_id, new_id_type);
323 /* If we are router and this packet is not already broadcast packet
324 we will broadcast it. The sending socket really cannot be router or
325 the router is buggy. If this packet is coming from router then it must
326 have the broadcast flag set already and we won't do anything. */
327 if (!server->standalone && server->server_type == SILC_ROUTER &&
328 sock->type == SILC_SOCKET_TYPE_SERVER &&
329 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
330 SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
331 silc_server_packet_send(server, server->router->connection, packet->type,
332 packet->flags | SILC_PACKET_FLAG_BROADCAST,
333 buffer->data, buffer->len, FALSE);
336 /* Replace the old ID */
337 switch(old_id_type) {
340 SilcBuffer nidp, oidp;
341 SilcClientEntry client = NULL;
343 SILC_LOG_DEBUG(("Old Client ID id(%s)",
344 silc_id_render(id, SILC_ID_CLIENT)));
345 SILC_LOG_DEBUG(("New Client ID id(%s)",
346 silc_id_render(id2, SILC_ID_CLIENT)));
348 if ((client = silc_idlist_replace_client_id(server->local_list,
350 if (server->server_type == SILC_ROUTER)
351 client = silc_idlist_replace_client_id(server->global_list, id, id2);
354 oidp = silc_id_payload_encode(id, SILC_ID_CLIENT);
355 nidp = silc_id_payload_encode(id2, SILC_ID_CLIENT);
357 /* Send the NICK_CHANGE notify type to local clients on the channels
358 this client is joined to. */
359 silc_server_send_notify_on_channels(server, client,
360 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
361 oidp->data, oidp->len,
362 nidp->data, nidp->len);
364 silc_buffer_free(nidp);
365 silc_buffer_free(oidp);
371 SILC_LOG_DEBUG(("Old Server ID id(%s)",
372 silc_id_render(id, SILC_ID_CLIENT)));
373 SILC_LOG_DEBUG(("New Server ID id(%s)",
374 silc_id_render(id2, SILC_ID_CLIENT)));
375 if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
376 if (server->server_type == SILC_ROUTER)
377 silc_idlist_replace_server_id(server->global_list, id, id2);
380 case SILC_ID_CHANNEL:
381 /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
401 /* Received New Client packet and processes it. Creates Client ID for the
402 client. Client becomes registered after calling this functions. */
404 SilcClientEntry silc_server_new_client(SilcServer server,
405 SilcSocketConnection sock,
406 SilcPacketContext *packet)
408 SilcBuffer buffer = packet->buffer;
409 SilcClientEntry client;
410 SilcIDCacheEntry cache;
411 SilcClientID *client_id;
413 SilcIDListData idata;
414 char *username = NULL, *realname = NULL, *id_string;
416 SILC_LOG_DEBUG(("Creating new client"));
418 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
421 /* Take client entry */
422 client = (SilcClientEntry)sock->user_data;
423 idata = (SilcIDListData)client;
425 /* Fetch the old client cache entry so that we can update it. */
426 if (!silc_idcache_find_by_context(server->local_list->clients,
427 sock->user_data, &cache)) {
428 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
432 /* Parse incoming packet */
433 silc_buffer_unformat(buffer,
434 SILC_STR_UI16_STRING_ALLOC(&username),
435 SILC_STR_UI16_STRING_ALLOC(&realname),
438 /* Create Client ID */
439 silc_id_create_client_id(server->id, server->rng, server->md5hash,
440 username, &client_id);
442 /* Update client entry */
443 idata->registered = TRUE;
444 client->nickname = strdup(username);
445 client->username = username;
446 client->userinfo = realname;
447 client->id = client_id;
449 /* Update the cache entry */
450 cache->id = (void *)client_id;
451 cache->type = SILC_ID_CLIENT;
452 cache->data = username;
453 silc_idcache_sort_by_data(server->local_list->clients);
455 /* Notify our router about new client on the SILC network */
456 if (!server->standalone)
457 silc_server_send_new_id(server, (SilcSocketConnection)
458 server->router->connection,
459 server->server_type == SILC_ROUTER ? TRUE : FALSE,
460 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
462 /* Send the new client ID to the client. */
463 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
464 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
465 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
466 silc_buffer_format(reply,
467 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
468 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
469 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
471 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
472 reply->data, reply->len, FALSE);
473 silc_free(id_string);
474 silc_buffer_free(reply);
476 /* Send some nice info to the client */
477 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
478 ("Welcome to the SILC Network %s@%s",
479 username, sock->hostname));
480 if (server->server_type == SILC_ROUTER) {
481 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
482 ("There are %d clients on %d servers in SILC "
483 "Network", server->stat.clients,
484 server->stat.servers));
485 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
486 ("There are %d clients on %d server in our cell",
487 server->stat.cell_clients,
488 server->stat.cell_servers));
489 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
490 ("I have %d clients, %d channels, %d servers and "
492 server->stat.my_clients,
493 server->stat.my_channels,
494 server->stat.my_servers,
495 server->stat.my_routers));
496 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
497 ("%d server operators and %d router operators "
499 server->stat.my_server_ops,
500 server->stat.my_router_ops));
502 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
503 ("I have %d clients and %d channels formed",
504 server->stat.my_clients,
505 server->stat.my_channels));
506 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
507 ("%d operators online",
508 server->stat.my_server_ops));
510 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
511 ("Your host is %s, running version %s",
512 server->config->server_info->server_name,
514 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
515 ("Your connection is secured with %s cipher, "
516 "key length %d bits",
517 idata->send_key->cipher->name,
518 idata->send_key->cipher->key_len));
519 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
520 ("Your current nickname is %s",
524 silc_server_send_motd(server, sock);
529 /* Create new server. This processes received New Server packet and
530 saves the received Server ID. The server is our locally connected
531 server thus we save all the information and save it to local list.
532 This funtion can be used by both normal server and router server.
533 If normal server uses this it means that its router has connected
534 to the server. If router uses this it means that one of the cell's
535 servers is connected to the router. */
537 SilcServerEntry silc_server_new_server(SilcServer server,
538 SilcSocketConnection sock,
539 SilcPacketContext *packet)
541 SilcBuffer buffer = packet->buffer;
542 SilcServerEntry new_server;
543 SilcIDCacheEntry cache;
544 SilcServerID *server_id;
545 SilcIDListData idata;
546 unsigned char *server_name, *id_string;
547 unsigned short id_len;
549 SILC_LOG_DEBUG(("Creating new server"));
551 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
552 sock->type != SILC_SOCKET_TYPE_ROUTER)
555 /* Take server entry */
556 new_server = (SilcServerEntry)sock->user_data;
557 idata = (SilcIDListData)new_server;
559 /* Fetch the old server cache entry so that we can update it. */
560 if (!silc_idcache_find_by_context(server->local_list->servers,
561 sock->user_data, &cache)) {
562 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
566 /* Parse the incoming packet */
567 silc_buffer_unformat(buffer,
568 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
569 SILC_STR_UI16_STRING_ALLOC(&server_name),
572 if (id_len > buffer->len) {
573 silc_free(id_string);
574 silc_free(server_name);
579 server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
580 silc_free(id_string);
582 /* Update client entry */
583 idata->registered = TRUE;
584 new_server->server_name = server_name;
585 new_server->id = server_id;
587 /* Update the cache entry */
588 cache->id = (void *)server_id;
589 cache->type = SILC_ID_SERVER;
590 cache->data = server_name;
591 silc_idcache_sort_by_data(server->local_list->servers);
593 /* Distribute the information about new server in the SILC network
594 to our router. If we are normal server we won't send anything
595 since this connection must be our router connection. */
596 if (server->server_type == SILC_ROUTER && !server->standalone &&
597 server->router->connection != sock)
598 silc_server_send_new_id(server, server->router->connection,
599 TRUE, new_server->id, SILC_ID_SERVER,
602 if (server->server_type == SILC_ROUTER)
603 server->stat.cell_servers++;
608 /* Processes incoming New ID packet. New ID Payload is used to distribute
609 information about newly registered clients and servers. */
611 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
612 SilcPacketContext *packet)
614 SilcBuffer buffer = packet->buffer;
616 SilcServerEntry router;
617 SilcSocketConnection router_sock;
620 unsigned char *hash = NULL;
623 SILC_LOG_DEBUG(("Processing new ID"));
625 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
626 server->server_type == SILC_SERVER ||
627 packet->src_id_type != SILC_ID_SERVER)
630 idp = silc_id_payload_parse(buffer);
634 id_type = silc_id_payload_get_type(idp);
636 /* Normal server cannot have other normal server connections */
637 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
640 id = silc_id_payload_get_id(idp);
644 /* If the sender of this packet is server and we are router we need to
645 broadcast this packet to other routers in the network. */
646 if (!server->standalone && server->server_type == SILC_ROUTER &&
647 sock->type == SILC_SOCKET_TYPE_SERVER &&
648 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
649 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
650 silc_server_packet_send(server, server->router->connection,
652 packet->flags | SILC_PACKET_FLAG_BROADCAST,
653 buffer->data, buffer->len, FALSE);
656 if (sock->type == SILC_SOCKET_TYPE_SERVER)
657 id_list = server->local_list;
659 id_list = server->global_list;
662 router = sock->user_data;
667 SilcClientEntry entry;
669 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
670 silc_id_render(id, SILC_ID_CLIENT),
671 sock->type == SILC_SOCKET_TYPE_SERVER ?
672 "Server" : "Router", sock->hostname));
674 /* As a router we keep information of all global information in our
675 global list. Cell wide information however is kept in the local
676 list. The client is put to global list and we will take the hash
677 value of the Client ID and save it to the ID Cache system for fast
678 searching in the future. */
679 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
680 sizeof(unsigned char));
681 memcpy(hash, ((SilcClientID *)id)->hash,
682 sizeof(((SilcClientID *)id)->hash));
683 entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id,
684 router, router_sock);
685 entry->nickname = NULL;
687 if (sock->type == SILC_SOCKET_TYPE_SERVER)
688 server->stat.cell_clients++;
689 server->stat.clients++;
692 /* XXX Adding two ID's with same IP number replaces the old entry thus
693 gives wrong route. Thus, now disabled until figured out a better way
694 to do this or when removed the whole thing. This could be removed
695 because entry->router->connection gives always the most optimal route
696 for the ID anyway (unless new routes (faster perhaps) are established
697 after receiving this ID, this we don't know however). */
698 /* Add route cache for this ID */
699 silc_server_route_add(silc_server_route_hash(
700 ((SilcClientID *)id)->ip.s_addr,
701 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);
717 if (sock->type == SILC_SOCKET_TYPE_SERVER)
718 server->stat.cell_servers++;
719 server->stat.servers++;
722 /* Add route cache for this ID */
723 silc_server_route_add(silc_server_route_hash(
724 ((SilcServerID *)id)->ip.s_addr,
725 ((SilcServerID *)id)->port),
726 ((SilcServerID *)id)->ip.s_addr,
731 case SILC_ID_CHANNEL:
732 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
740 silc_id_payload_free(idp);
743 /* Received Remove Channel User packet to remove a user from a channel.
744 Routers notify other routers that user has left a channel. Client must
745 not send this packet. Normal server may send this packet but must not
748 void silc_server_remove_channel_user(SilcServer server,
749 SilcSocketConnection sock,
750 SilcPacketContext *packet)
752 SilcBuffer buffer = packet->buffer;
753 unsigned char *tmp1 = NULL, *tmp2 = NULL;
754 SilcClientID *client_id = NULL;
755 SilcChannelID *channel_id = NULL;
756 SilcChannelEntry channel;
757 SilcClientEntry client;
759 SILC_LOG_DEBUG(("Removing user from channel"));
761 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
762 server->server_type == SILC_SERVER)
765 silc_buffer_unformat(buffer,
766 SILC_STR_UI16_STRING_ALLOC(&tmp1),
767 SILC_STR_UI16_STRING_ALLOC(&tmp2),
773 client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
774 channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
775 if (!client_id || !channel_id)
778 /* If we are router and this packet is not already broadcast packet
779 we will broadcast it. The sending socket really cannot be router or
780 the router is buggy. If this packet is coming from router then it must
781 have the broadcast flag set already and we won't do anything. */
782 if (!server->standalone && server->server_type == SILC_ROUTER &&
783 sock->type == SILC_SOCKET_TYPE_SERVER &&
784 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
785 SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
786 silc_server_packet_send(server, server->router->connection, packet->type,
787 packet->flags | SILC_PACKET_FLAG_BROADCAST,
788 buffer->data, buffer->len, FALSE);
791 /* Get channel entry */
792 channel = silc_idlist_find_channel_by_id(server->local_list,
795 channel = silc_idlist_find_channel_by_id(server->global_list,
801 /* Get client entry */
802 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
804 client = silc_idlist_find_client_by_id(server->global_list,
810 /* Remove user from channel */
811 silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
819 silc_free(client_id);
821 silc_free(channel_id);
824 /* Received New Channel packet. Information about new channels in the
825 network are distributed using this packet. Save the information about
828 void silc_server_new_channel(SilcServer server,
829 SilcSocketConnection sock,
830 SilcPacketContext *packet)
833 SilcChannelID *channel_id;
834 unsigned short channel_id_len;
837 SILC_LOG_DEBUG(("Processing New Channel"));
839 if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
840 server->server_type == SILC_SERVER ||
841 packet->src_id_type != SILC_ID_SERVER)
845 if (!silc_buffer_unformat(packet->buffer,
846 SILC_STR_UI16_STRING_ALLOC(&channel_name),
847 SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
851 if (!channel_name || !id)
854 /* Decode the channel ID */
855 channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
860 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
861 silc_id_render(channel_id, SILC_ID_CHANNEL),
864 /* Add the new channel. Add it always to global list since if we receive
865 this packet then it cannot be created by ourselves but some other
866 router hence global channel. */
867 silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
868 server->router->connection, NULL);
870 server->stat.channels++;
873 /* Received notify packet. Server can receive notify packets from router.
874 Server then relays the notify messages to clients if needed. */
876 void silc_server_notify(SilcServer server,
877 SilcSocketConnection sock,
878 SilcPacketContext *packet)
880 SilcNotifyPayload payload;
882 SilcArgumentPayload args;
883 SilcChannelID *channel_id;
884 SilcClientID *client_id, *client_id2;
885 SilcChannelEntry channel;
886 SilcClientEntry client;
888 unsigned int tmp_len;
890 SILC_LOG_DEBUG(("Start"));
892 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
893 packet->src_id_type != SILC_ID_SERVER)
896 /* XXX: For now we expect that the we are normal server and that the
897 sender is router. Server could send (protocol allows it) notify to
898 router but we don't support it yet. */
899 if (server->server_type != SILC_SERVER &&
900 sock->type != SILC_SOCKET_TYPE_ROUTER)
903 payload = silc_notify_payload_parse(packet->buffer);
907 type = silc_notify_get_type(payload);
908 args = silc_notify_get_args(payload);
913 case SILC_NOTIFY_TYPE_JOIN:
915 * Distribute the notify to local clients on the channel
917 SILC_LOG_DEBUG(("JOIN notify"));
919 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
923 /* Get channel entry */
924 channel = silc_idlist_find_channel_by_id(server->local_list,
927 silc_free(channel_id);
932 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
934 silc_free(channel_id);
937 client_id = silc_id_payload_parse_id(tmp, tmp_len);
939 /* Send to channel */
940 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
941 FALSE, packet->buffer->data,
942 packet->buffer->len, FALSE);
944 /* If the the client is not in local list we check global list (ie. the
945 channel will be global channel) and if it does not exist then create
946 entry for the client. */
947 client = silc_idlist_find_client_by_id(server->local_list,
950 SilcChannelClientEntry chl;
952 client = silc_idlist_find_client_by_id(server->global_list,
955 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
956 client_id, sock->user_data, sock);
958 /* The channel is global now */
959 channel->global_users = TRUE;
961 /* Now actually JOIN the global client to the channel */
962 chl = silc_calloc(1, sizeof(*chl));
963 chl->client = client;
964 chl->channel = channel;
965 silc_list_add(channel->user_list, chl);
966 silc_list_add(client->channels, chl);
968 silc_free(client_id);
972 case SILC_NOTIFY_TYPE_LEAVE:
974 * Distribute the notify to local clients on the channel
976 SILC_LOG_DEBUG(("LEAVE notify"));
978 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
982 /* Get channel entry */
983 channel = silc_idlist_find_channel_by_id(server->local_list,
986 silc_free(channel_id);
991 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
993 silc_free(channel_id);
996 client_id = silc_id_payload_parse_id(tmp, tmp_len);
998 /* Send to channel */
999 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
1000 FALSE, packet->buffer->data,
1001 packet->buffer->len, FALSE);
1003 /* Get client entry */
1004 client = silc_idlist_find_client_by_id(server->global_list,
1007 client = silc_idlist_find_client_by_id(server->local_list,
1010 silc_free(channel_id);
1014 silc_free(client_id);
1016 /* Remove the user from channel */
1017 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1020 case SILC_NOTIFY_TYPE_SIGNOFF:
1022 * Distribute the notify to local clients on the channel
1024 SILC_LOG_DEBUG(("SIGNOFF notify"));
1027 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1030 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1032 /* Get client entry */
1033 client = silc_idlist_find_client_by_id(server->global_list,
1036 client = silc_idlist_find_client_by_id(server->local_list,
1039 silc_free(client_id);
1043 silc_free(client_id);
1045 /* Remove the client from all channels */
1046 silc_server_remove_from_channels(server, NULL, client);
1048 /* Remove the client entry */
1049 silc_idlist_del_client(server->global_list, client);
1052 case SILC_NOTIFY_TYPE_NICK_CHANGE:
1055 * Distribute the notify to local clients on the channel
1057 unsigned char *id, *id2;
1059 SILC_LOG_DEBUG(("NICK CHANGE notify"));
1061 /* Get old client ID */
1062 id = silc_argument_get_arg_type(args, 1, &tmp_len);
1065 client_id = silc_id_payload_parse_id(id, tmp_len);
1067 /* Get new client ID */
1068 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
1071 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
1073 SILC_LOG_DEBUG(("Old Client ID id(%s)",
1074 silc_id_render(client_id, SILC_ID_CLIENT)));
1075 SILC_LOG_DEBUG(("New Client ID id(%s)",
1076 silc_id_render(client_id2, SILC_ID_CLIENT)));
1078 /* Replace the Client ID */
1079 client = silc_idlist_replace_client_id(server->global_list, client_id,
1082 client = silc_idlist_replace_client_id(server->local_list, client_id,
1086 /* Send the NICK_CHANGE notify type to local clients on the channels
1087 this client is joined to. */
1088 silc_server_send_notify_on_channels(server, client,
1089 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
1093 silc_free(client_id);
1095 silc_free(client_id2);
1098 case SILC_NOTIFY_TYPE_TOPIC_SET:
1100 * Distribute the notify to local clients on the channel
1102 SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
1105 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1107 * Distribute the notify to local clients on the channel
1109 SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
1112 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1114 * Distribute the notify to local clients on the channel
1116 SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
1119 /* Ignore rest notify types for now */
1120 case SILC_NOTIFY_TYPE_NONE:
1121 case SILC_NOTIFY_TYPE_INVITE:
1122 case SILC_NOTIFY_TYPE_MOTD:
1128 silc_notify_payload_free(payload);
1131 /* Received new channel user packet. Information about new users on a
1132 channel are distributed between routers using this packet. The
1133 router receiving this will redistribute it and also sent JOIN notify
1134 to local clients on the same channel. Normal server sends JOIN notify
1135 to its local clients on the channel. */
1137 void silc_server_new_channel_user(SilcServer server,
1138 SilcSocketConnection sock,
1139 SilcPacketContext *packet)
1141 unsigned char *tmpid1, *tmpid2;
1142 SilcClientID *client_id = NULL;
1143 SilcChannelID *channel_id = NULL;
1144 unsigned short channel_id_len;
1145 unsigned short client_id_len;
1146 SilcClientEntry client;
1147 SilcChannelEntry channel;
1148 SilcChannelClientEntry chl;
1151 SILC_LOG_DEBUG(("Start"));
1153 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1154 server->server_type != SILC_ROUTER ||
1155 packet->src_id_type != SILC_ID_SERVER)
1159 if (!silc_buffer_unformat(packet->buffer,
1160 SILC_STR_UI16_NSTRING_ALLOC(&tmpid1,
1162 SILC_STR_UI16_NSTRING_ALLOC(&tmpid2,
1167 if (!tmpid1 || !tmpid2)
1170 /* Decode the channel ID */
1171 channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
1175 /* Decode the client ID */
1176 client_id = silc_id_str2id(tmpid2, SILC_ID_CLIENT);
1180 /* Find the channel */
1181 channel = silc_idlist_find_channel_by_id(server->local_list,
1184 channel = silc_idlist_find_channel_by_id(server->global_list,
1190 /* If we are router and this packet is not already broadcast packet
1191 we will broadcast it. */
1192 if (!server->standalone && server->server_type == SILC_ROUTER &&
1193 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1194 SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1195 silc_server_packet_send(server, server->router->connection, packet->type,
1196 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1197 packet->buffer->data, packet->buffer->len, FALSE);
1200 /* Get client entry */
1201 client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1203 client = silc_idlist_find_client_by_id(server->global_list,
1209 /* Join the client to the channel by adding it to channel's user list.
1210 Add also the channel to client entry's channels list for fast cross-
1212 chl = silc_calloc(1, sizeof(*chl));
1213 chl->client = client;
1214 chl->channel = channel;
1215 silc_list_add(channel->user_list, chl);
1216 silc_list_add(client->channels, chl);
1218 server->stat.chanclients++;
1220 /* Send JOIN notify to local clients on the channel. As we are router
1221 it is assured that this is sent only to our local clients and locally
1222 connected servers if needed. */
1223 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1224 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1225 SILC_NOTIFY_TYPE_JOIN,
1226 1, clidp->data, clidp->len);
1227 silc_buffer_free(clidp);
1233 silc_free(client_id);
1235 silc_free(channel_id);
1240 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1241 that certain ID should be removed. After that the ID will become invalid. */
1243 void silc_server_remove_id(SilcServer server,
1244 SilcSocketConnection sock,
1245 SilcPacketContext *packet)
1250 void *id, *id_entry;
1252 SILC_LOG_DEBUG(("Start"));
1254 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1255 server->server_type == SILC_SERVER ||
1256 packet->src_id_type != SILC_ID_SERVER)
1259 idp = silc_id_payload_parse(packet->buffer);
1263 id_type = silc_id_payload_get_type(idp);
1265 id = silc_id_payload_get_id(idp);
1269 /* If the sender of this packet is server and we are router we need to
1270 broadcast this packet to other routers in the network. */
1271 if (!server->standalone && server->server_type == SILC_ROUTER &&
1272 sock->type == SILC_SOCKET_TYPE_SERVER &&
1273 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1274 SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1275 silc_server_packet_send(server, server->router->connection,
1277 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1278 packet->buffer->data, packet->buffer->len, FALSE);
1281 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1282 id_list = server->local_list;
1284 id_list = server->global_list;
1288 case SILC_ID_CLIENT:
1289 id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id,
1292 /* Remove from channels */
1293 silc_server_remove_from_channels(server, NULL, id_entry);
1295 /* Remove the client entry */
1296 silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1297 server->stat.clients--;
1299 SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1300 silc_id_render(id, SILC_ID_CLIENT),
1301 sock->type == SILC_SOCKET_TYPE_SERVER ?
1302 "Server" : "Router", sock->hostname));
1306 case SILC_ID_SERVER:
1307 id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1310 silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1311 server->stat.servers--;
1313 SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1314 silc_id_render(id, SILC_ID_SERVER),
1315 sock->type == SILC_SOCKET_TYPE_SERVER ?
1316 "Server" : "Router", sock->hostname));
1320 case SILC_ID_CHANNEL:
1321 id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1324 silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1325 server->stat.channels--;
1327 SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1328 silc_id_render(id, SILC_ID_CHANNEL),
1329 sock->type == SILC_SOCKET_TYPE_SERVER ?
1330 "Server" : "Router", sock->hostname));
1339 silc_id_payload_free(idp);