5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2007 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /************************* Types and definitions ****************************/
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
28 SILC_TASK_CALLBACK(silc_server_do_rekey);
29 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
30 static void silc_server_accept_new_connection(SilcNetStatus status,
33 static void silc_server_packet_parse_type(SilcServer server,
34 SilcPacketStream sock,
36 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
40 /************************ Static utility functions **************************/
42 /* SKE public key verification callback */
45 silc_server_verify_key(SilcSKE ske,
46 SilcPublicKey public_key,
48 SilcSKEVerifyCbCompletion completion,
49 void *completion_context)
51 SilcPacketStream sock = context;
52 SilcUnknownEntry entry = silc_packet_get_context(sock);
54 SILC_LOG_DEBUG(("Verifying public key"));
56 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
57 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
58 entry->hostname, entry->ip, entry->port,
59 silc_pkcs_get_type(public_key)));
60 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
65 /* We accept all keys without explicit verification */
66 completion(ske, SILC_SKE_STATUS_OK, completion_context);
70 /************************ Packet engine callbacks ***************************/
72 /* Packet engine callback to receive a packet */
74 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
75 SilcPacketStream stream,
77 void *callback_context,
80 SilcServer server = callback_context;
81 SilcIDListData idata = stream_context;
86 /* Packets we do not handle */
87 switch (packet->type) {
88 case SILC_PACKET_HEARTBEAT:
89 case SILC_PACKET_SUCCESS:
90 case SILC_PACKET_FAILURE:
91 case SILC_PACKET_REJECT:
92 case SILC_PACKET_KEY_EXCHANGE:
93 case SILC_PACKET_KEY_EXCHANGE_1:
94 case SILC_PACKET_KEY_EXCHANGE_2:
95 case SILC_PACKET_REKEY_DONE:
96 case SILC_PACKET_CONNECTION_AUTH:
101 /* Only specific packets can come without source ID present. */
102 if ((!packet->src_id ||
103 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
104 packet->type != SILC_PACKET_NEW_CLIENT &&
105 packet->type != SILC_PACKET_NEW_SERVER &&
106 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
107 packet->type != SILC_PACKET_DISCONNECT)
110 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID
111 and for unregistered connection. */
112 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
113 packet->type == SILC_PACKET_NEW_SERVER) &&
114 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
117 /* Ignore packets from disabled connection */
118 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
119 packet->type != SILC_PACKET_HEARTBEAT &&
120 packet->type != SILC_PACKET_RESUME_ROUTER &&
121 packet->type != SILC_PACKET_REKEY)
124 /* Check that the the current client ID is same as in the client's packet. */
125 if (idata->conn_type == SILC_CONN_CLIENT) {
126 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
127 SilcClientID client_id;
129 if (client->id && packet->src_id &&
130 silc_id_str2id(packet->src_id, packet->src_id_len,
131 packet->src_id_type, &client_id, sizeof(client_id))) {
132 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
133 SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
134 silc_get_packet_name(packet->type)));
140 if (server->server_type == SILC_ROUTER) {
141 /* Route the packet if it is not destined to us. Other ID types but
142 server are handled separately after processing them. */
143 if (packet->dst_id &&
144 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
145 packet->dst_id_type == SILC_ID_SERVER &&
146 idata->conn_type != SILC_CONN_CLIENT &&
147 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
148 SilcPacketStream conn;
149 SilcServerID server_id;
151 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
152 &server_id, sizeof(server_id));
154 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
156 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
157 silc_id_render(&server_id, SILC_ID_SERVER)));
161 silc_server_packet_route(server, conn, packet);
162 silc_packet_free(packet);
167 /* Broadcast packet if it is marked as broadcast packet and it is
168 originated from router and we are router. */
169 if (server->server_type == SILC_ROUTER &&
170 idata->conn_type == SILC_CONN_ROUTER &&
171 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
172 /* Broadcast to our primary route */
173 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
175 /* If we have backup routers then we need to feed all broadcast
176 data to those servers. */
177 silc_server_backup_broadcast(server, stream, packet);
181 silc_server_packet_parse_type(server, stream, packet);
186 /* Packet engine callback to indicate end of stream */
188 static void silc_server_packet_eos(SilcPacketEngine engine,
189 SilcPacketStream stream,
190 void *callback_context,
191 void *stream_context)
193 SilcServer server = callback_context;
194 SilcIDListData idata = silc_packet_get_context(stream);
196 SILC_LOG_DEBUG(("End of stream received"));
201 if (server->router_conn && server->router_conn->sock == stream &&
202 !server->router && server->standalone) {
203 silc_server_create_connections(server);
205 /* If backup disconnected then mark that resuming will not be allowed */
206 if (server->server_type == SILC_ROUTER && !server->backup_router &&
207 idata->conn_type == SILC_CONN_SERVER) {
208 SilcServerEntry server_entry = (SilcServerEntry)idata;
209 if (server_entry->server_type == SILC_BACKUP_ROUTER)
210 server->backup_closed = TRUE;
213 silc_server_free_sock_user_data(server, stream, NULL);
216 silc_server_close_connection(server, stream);
219 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
221 SilcServer server = app_context;
222 SilcPacketStream stream = context;
223 SilcIDListData idata = silc_packet_get_context(stream);
228 if (server->router_conn && server->router_conn->sock == stream &&
229 !server->router && server->standalone) {
230 silc_server_create_connections(server);
232 /* If backup disconnected then mark that resuming will not be allowed */
233 if (server->server_type == SILC_ROUTER && !server->backup_router &&
234 idata->conn_type == SILC_CONN_SERVER) {
235 SilcServerEntry server_entry = (SilcServerEntry)idata;
236 if (server_entry->server_type == SILC_BACKUP_ROUTER)
237 server->backup_closed = TRUE;
240 silc_server_free_sock_user_data(server, stream, NULL);
243 silc_server_close_connection(server, stream);
246 /* Packet engine callback to indicate error */
248 static void silc_server_packet_error(SilcPacketEngine engine,
249 SilcPacketStream stream,
250 SilcPacketError error,
251 void *callback_context,
252 void *stream_context)
254 SilcServer server = callback_context;
255 SilcIDListData idata = silc_packet_get_context(stream);
256 SilcStream sock = silc_packet_stream_get_stream(stream);
263 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
266 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
267 SILC_CONNTYPE_STRING(idata->conn_type),
268 silc_packet_error_string(error)));
270 silc_schedule_task_add_timeout(server->schedule,
271 silc_server_packet_error_timeout,
275 /* Packet stream callbacks */
276 static SilcPacketCallbacks silc_server_stream_cbs =
278 silc_server_packet_receive,
279 silc_server_packet_eos,
280 silc_server_packet_error
283 /* Parses the packet type and calls what ever routines the packet type
284 requires. This is done for all incoming packets. */
286 static void silc_server_packet_parse_type(SilcServer server,
287 SilcPacketStream sock,
290 SilcPacketType type = packet->type;
291 SilcIDListData idata = silc_packet_get_context(sock);
293 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
294 silc_get_packet_name(type), packet->flags));
296 /* Parse the packet type */
298 case SILC_PACKET_NOTIFY:
300 * Received notify packet. Server can receive notify packets from
301 * router. Server then relays the notify messages to clients if needed.
303 if (packet->flags & SILC_PACKET_FLAG_LIST)
304 silc_server_notify_list(server, sock, packet);
306 silc_server_notify(server, sock, packet);
310 * Private Message packets
312 case SILC_PACKET_PRIVATE_MESSAGE:
314 * Received private message packet. The packet is coming from either
317 if (packet->flags & SILC_PACKET_FLAG_LIST)
319 idata->last_receive = time(NULL);
320 silc_server_private_message(server, sock, packet);
326 case SILC_PACKET_CHANNEL_MESSAGE:
328 * Received channel message. Channel messages are special packets
329 * (although probably most common ones) thus they are handled
332 if (packet->flags & SILC_PACKET_FLAG_LIST)
334 idata->last_receive = time(NULL);
335 silc_server_channel_message(server, sock, packet);
341 case SILC_PACKET_COMMAND:
343 * Recived command. Processes the command request and allocates the
344 * command context and calls the command.
346 if (packet->flags & SILC_PACKET_FLAG_LIST)
348 server->stat.commands_received++;
349 silc_server_command_process(server, sock, packet);
352 case SILC_PACKET_COMMAND_REPLY:
354 * Received command reply packet. Received command reply to command. It
355 * may be reply to command sent by us or reply to command sent by client
356 * that we've routed further.
358 if (packet->flags & SILC_PACKET_FLAG_LIST)
360 server->stat.commands_received++;
361 silc_server_command_reply(server, sock, packet);
364 case SILC_PACKET_DISCONNECT:
367 char *message = NULL;
368 const char *hostname, *ip;
370 if (packet->flags & SILC_PACKET_FLAG_LIST)
372 if (silc_buffer_len(&packet->buffer) < 1)
375 status = (SilcStatus)packet->buffer.data[0];
376 if (silc_buffer_len(&packet->buffer) > 1 &&
377 silc_utf8_valid(packet->buffer.data + 1,
378 silc_buffer_len(&packet->buffer) - 1))
379 message = silc_memdup(packet->buffer.data + 1,
380 silc_buffer_len(&packet->buffer) - 1);
382 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
383 NULL, &hostname, &ip, NULL))
386 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
387 silc_get_status_message(status), status,
388 message ? message : ""));
392 /* Do not switch to backup in case of error */
393 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
395 /* If backup disconnected then mark that resuming will not be allowed */
396 if (server->server_type == SILC_ROUTER && !server->backup_router &&
397 idata->conn_type == SILC_CONN_SERVER) {
398 SilcServerEntry server_entry = (SilcServerEntry)idata;
399 if (server_entry->server_type == SILC_BACKUP_ROUTER)
400 server->backup_closed = TRUE;
403 /* Handle the disconnection from our end too */
404 if (SILC_IS_LOCAL(idata))
405 silc_server_free_sock_user_data(server, sock, NULL);
406 silc_server_close_connection(server, sock);
407 server->backup_noswitch = FALSE;
411 case SILC_PACKET_CHANNEL_KEY:
413 * Received key for channel. As channels are created by the router
414 * the keys are as well. We will distribute the key to all of our
415 * locally connected clients on the particular channel. Router
416 * never receives this channel and thus is ignored.
418 if (packet->flags & SILC_PACKET_FLAG_LIST)
420 silc_server_channel_key(server, sock, packet);
423 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
425 * Private message key packet.
427 if (packet->flags & SILC_PACKET_FLAG_LIST)
429 silc_server_private_message_key(server, sock, packet);
432 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
434 * Connection authentication request packet. When we receive this packet
435 * we will send to the other end information about our mandatory
436 * authentication method for the connection. This packet maybe received
439 if (packet->flags & SILC_PACKET_FLAG_LIST)
441 silc_server_connection_auth_request(server, sock, packet);
444 case SILC_PACKET_NEW_ID:
446 * Received New ID packet. This includes some new ID that has been
447 * created. It may be for client, server or channel. This is the way
448 * to distribute information about new registered entities in the
451 if (packet->flags & SILC_PACKET_FLAG_LIST)
452 silc_server_new_id_list(server, sock, packet);
454 silc_server_new_id(server, sock, packet);
457 case SILC_PACKET_NEW_CLIENT:
459 * Received new client packet. This includes client information that
460 * we will use to create initial client ID. After creating new
461 * ID we will send it to the client.
463 if (packet->flags & SILC_PACKET_FLAG_LIST)
465 silc_server_new_client(server, sock, packet);
468 case SILC_PACKET_NEW_SERVER:
470 * Received new server packet. This includes Server ID and some other
471 * information that we may save. This is received after server has
474 if (packet->flags & SILC_PACKET_FLAG_LIST)
476 silc_server_new_server(server, sock, packet);
479 case SILC_PACKET_NEW_CHANNEL:
481 * Received new channel packet. Information about new channel in the
482 * network are distributed using this packet.
484 if (packet->flags & SILC_PACKET_FLAG_LIST)
485 silc_server_new_channel_list(server, sock, packet);
487 silc_server_new_channel(server, sock, packet);
490 case SILC_PACKET_HEARTBEAT:
492 * Received heartbeat.
494 if (packet->flags & SILC_PACKET_FLAG_LIST)
498 case SILC_PACKET_KEY_AGREEMENT:
500 * Received heartbeat.
502 if (packet->flags & SILC_PACKET_FLAG_LIST)
504 silc_server_key_agreement(server, sock, packet);
507 case SILC_PACKET_REKEY:
509 * Received re-key packet. The sender wants to regenerate the session
512 if (packet->flags & SILC_PACKET_FLAG_LIST)
514 silc_server_rekey(server, sock, packet);
517 case SILC_PACKET_FTP:
519 if (packet->flags & SILC_PACKET_FLAG_LIST)
521 silc_server_ftp(server, sock, packet);
524 case SILC_PACKET_RESUME_CLIENT:
526 if (packet->flags & SILC_PACKET_FLAG_LIST)
528 silc_server_resume_client(server, sock, packet);
531 case SILC_PACKET_RESUME_ROUTER:
532 /* Resume router packet received. This packet is received for backup
533 router resuming protocol. */
534 if (packet->flags & SILC_PACKET_FLAG_LIST)
536 silc_server_backup_resume_router(server, sock, packet);
540 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
545 /****************************** Server API **********************************/
547 /* Allocates a new SILC server object. This has to be done before the server
548 can be used. After allocation one must call silc_server_init to initialize
549 the server. The new allocated server object is returned to the new_server
552 SilcBool silc_server_alloc(SilcServer *new_server)
556 SILC_LOG_DEBUG(("Allocating new server object"));
558 server = silc_calloc(1, sizeof(*server));
561 server->server_type = SILC_SERVER;
562 server->standalone = TRUE;
563 server->local_list = silc_calloc(1, sizeof(*server->local_list));
564 if (!server->local_list)
566 server->global_list = silc_calloc(1, sizeof(*server->global_list));
567 if (!server->global_list)
569 server->pending_commands = silc_dlist_init();
570 if (!server->pending_commands)
572 server->listeners = silc_dlist_init();
573 if (!server->listeners)
575 server->repository = silc_skr_alloc();
576 if (!server->repository)
578 server->conns = silc_dlist_init();
581 server->expired_clients = silc_dlist_init();
582 if (!server->expired_clients)
585 *new_server = server;
590 /* Free's the SILC server object. This is called at the very end before
593 void silc_server_free(SilcServer server)
596 SilcIDCacheEntry cache;
597 SilcIDListData idata;
599 SILC_LOG_DEBUG(("Free server %p", server));
604 silc_server_backup_free(server);
605 silc_server_config_unref(&server->config_ref);
607 silc_rng_free(server->rng);
608 if (server->public_key)
609 silc_pkcs_public_key_free(server->public_key);
610 if (server->private_key)
611 silc_pkcs_private_key_free(server->private_key);
612 if (server->pending_commands)
613 silc_dlist_uninit(server->pending_commands);
614 if (server->id_entry) {
615 if (server->id_entry->data.sconn)
616 silc_schedule_task_del_by_context(server->schedule,
617 server->id_entry->data.sconn->sock);
618 silc_idlist_del_server(server->local_list, server->id_entry);
621 /* Delete all channels */
622 if (silc_idcache_get_all(server->local_list->channels, &list)) {
623 silc_list_start(list);
624 while ((cache = silc_list_get(list)))
625 silc_idlist_del_channel(server->local_list, cache->context);
627 if (silc_idcache_get_all(server->global_list->channels, &list)) {
628 silc_list_start(list);
629 while ((cache = silc_list_get(list)))
630 silc_idlist_del_channel(server->global_list, cache->context);
633 /* Delete all clients */
634 if (silc_idcache_get_all(server->local_list->clients, &list)) {
635 silc_list_start(list);
636 while ((cache = silc_list_get(list))) {
637 silc_schedule_task_del_by_context(server->schedule, cache->context);
638 silc_idlist_del_client(server->local_list, cache->context);
641 if (silc_idcache_get_all(server->global_list->clients, &list)) {
642 silc_list_start(list);
643 while ((cache = silc_list_get(list))) {
644 silc_schedule_task_del_by_context(server->schedule, cache->context);
645 silc_idlist_del_client(server->global_list, cache->context);
649 /* Delete all servers */
650 if (silc_idcache_get_all(server->local_list->servers, &list)) {
651 silc_list_start(list);
652 while ((cache = silc_list_get(list))) {
653 idata = (SilcIDListData)cache->context;
655 silc_schedule_task_del_by_context(server->schedule,
657 silc_idlist_del_server(server->local_list, cache->context);
660 if (silc_idcache_get_all(server->global_list->servers, &list)) {
661 while ((cache = silc_list_get(list))) {
662 idata = (SilcIDListData)cache->context;
664 silc_schedule_task_del_by_context(server->schedule,
666 silc_idlist_del_server(server->global_list, cache->context);
670 silc_schedule_task_del_by_context(server->schedule, server);
671 silc_schedule_uninit(server->schedule);
672 server->schedule = NULL;
674 silc_idcache_free(server->local_list->clients);
675 silc_idcache_free(server->local_list->servers);
676 silc_idcache_free(server->local_list->channels);
677 silc_idcache_free(server->global_list->clients);
678 silc_idcache_free(server->global_list->servers);
679 silc_idcache_free(server->global_list->channels);
680 silc_hash_table_free(server->watcher_list);
681 silc_hash_table_free(server->watcher_list_pk);
682 silc_hash_free(server->md5hash);
683 silc_hash_free(server->sha1hash);
685 silc_dlist_uninit(server->listeners);
686 silc_dlist_uninit(server->conns);
687 silc_dlist_uninit(server->expired_clients);
688 silc_skr_free(server->repository);
689 silc_packet_engine_stop(server->packet_engine);
691 silc_free(server->local_list);
692 silc_free(server->global_list);
693 silc_free(server->server_name);
696 silc_hmac_unregister_all();
697 silc_hash_unregister_all();
698 silc_cipher_unregister_all();
699 silc_pkcs_unregister_all();
702 /* Creates a new server listener. */
704 static SilcNetListener
705 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
707 SilcNetListener listener;
710 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
711 server->config->require_reverse_lookup,
713 silc_server_accept_new_connection, server);
715 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
723 /* Adds a secondary listener. */
725 SilcBool silc_server_init_secondary(SilcServer server)
727 SilcServerConfigServerInfoInterface *interface;
728 SilcNetListener listener;
730 for (interface = server->config->server_info->secondary; interface;
731 interface = interface->next) {
732 listener = silc_server_listen(server, interface->server_ip,
736 silc_dlist_add(server->listeners, listener);
742 /* Initializes the entire SILC server. This is called always before running
743 the server. This is called only once at the initialization of the program.
744 This binds the server to its listenning port. After this function returns
745 one should call silc_server_run to start the server. This returns TRUE
746 when everything is ok to run the server. Configuration file must be
747 read and parsed before calling this. */
749 SilcBool silc_server_init(SilcServer server)
752 SilcServerEntry id_entry;
753 SilcNetListener listener;
757 SILC_LOG_DEBUG(("Initializing server"));
759 server->starttime = time(NULL);
761 /* Take config object for us */
762 silc_server_config_ref(&server->config_ref, server->config,
766 /* Set debugging on if configured */
767 if (server->config->debug_string) {
768 silc_log_debug(TRUE);
769 silc_log_set_debug_string(server->config->debug_string);
771 #endif /* SILC_DEBUG */
773 /* Steal public and private key from the config object */
774 server->public_key = server->config->server_info->public_key;
775 server->private_key = server->config->server_info->private_key;
776 server->config->server_info->public_key = NULL;
777 server->config->server_info->private_key = NULL;
779 /* Register all configured ciphers, PKCS and hash functions. */
780 if (!silc_server_config_register_ciphers(server))
781 silc_cipher_register_default();
782 if (!silc_server_config_register_pkcs(server))
783 silc_pkcs_register_default();
784 if (!silc_server_config_register_hashfuncs(server))
785 silc_hash_register_default();
786 if (!silc_server_config_register_hmacs(server))
787 silc_hmac_register_default();
789 /* Initialize random number generator for the server. */
790 server->rng = silc_rng_alloc();
791 silc_rng_init(server->rng);
792 silc_rng_global_init(server->rng);
794 /* Initialize hash functions for server to use */
795 silc_hash_alloc("md5", &server->md5hash);
796 silc_hash_alloc("sha1", &server->sha1hash);
798 /* Initialize the scheduler */
799 server->schedule = silc_schedule_init(server->config->param.connections_max,
801 if (!server->schedule)
804 /* First, register log files configuration for error output */
805 silc_server_config_setlogfiles(server);
807 /* Initialize ID caches */
808 server->local_list->clients =
809 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
811 server->local_list->servers =
812 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
814 server->local_list->channels =
815 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
818 /* These are allocated for normal server as well as these hold some
819 global information that the server has fetched from its router. For
820 router these are used as they are supposed to be used on router. */
821 server->global_list->clients =
822 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
824 server->global_list->servers =
825 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
827 server->global_list->channels =
828 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
831 /* Init watcher lists */
832 server->watcher_list =
833 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
834 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
836 if (!server->watcher_list)
838 server->watcher_list_pk =
839 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
840 silc_hash_public_key_compare, NULL,
842 if (!server->watcher_list_pk)
845 /* Create TCP listener */
846 listener = silc_server_listen(
848 server->config->server_info->primary == NULL ? NULL :
849 server->config->server_info->primary->server_ip,
850 server->config->server_info->primary == NULL ? 0 :
851 server->config->server_info->primary->port);
854 silc_dlist_add(server->listeners, listener);
856 /* Create a Server ID for the server. */
857 port = silc_net_listener_get_port(listener, NULL);
858 ip = silc_net_listener_get_ip(listener, NULL);
859 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
860 server->config->server_info->primary->public_ip :
861 ip[0], port[0], server->rng, &id);
870 server->server_name = server->config->server_info->server_name;
871 server->config->server_info->server_name = NULL;
872 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
873 sizeof(server->id_string), &server->id_string_len);
875 /* Add ourselves to the server list. We don't have a router yet
876 beacuse we haven't established a route yet. It will be done later.
877 For now, NULL is sent as router. This allocates new entry to
880 silc_idlist_add_server(server->local_list, strdup(server->server_name),
882 silc_id_dup(server->id, SILC_ID_SERVER),
885 SILC_LOG_ERROR(("Could not add local server to cache"));
888 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
889 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
890 SILC_CONN_SERVER : SILC_CONN_ROUTER);
891 server->id_entry = id_entry;
893 /* Create secondary TCP listeners */
894 if (silc_server_init_secondary(server) == FALSE)
897 server->listenning = TRUE;
899 /* Create connections to configured routers. */
900 silc_server_create_connections(server);
902 /* If server connections has been configured then we must be router as
903 normal server cannot have server connections, only router connections. */
904 if (server->config->servers) {
905 SilcServerConfigServer *ptr = server->config->servers;
907 server->server_type = SILC_ROUTER;
909 if (ptr->backup_router) {
910 server->server_type = SILC_BACKUP_ROUTER;
911 server->backup_router = TRUE;
912 server->id_entry->server_type = SILC_BACKUP_ROUTER;
919 if (server->server_type != SILC_ROUTER) {
920 server->stat.servers = 1;
921 server->stat.cell_servers = 1;
923 server->stat.routers = 1;
926 /* If we are normal server we'll retrieve network statisticial information
927 once in a while from the router. */
928 if (server->server_type != SILC_ROUTER)
929 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
932 /* Start packet engine */
933 server->packet_engine =
934 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
935 &silc_server_stream_cbs, server);
936 if (!server->packet_engine)
939 /* Register client entry expiration timeout */
940 silc_schedule_task_add_timeout(server->schedule,
941 silc_server_purge_expired_clients, server,
944 /* Initialize HTTP server */
945 silc_server_http_init(server);
947 SILC_LOG_DEBUG(("Server initialized"));
949 /* We are done here, return succesfully */
953 silc_server_config_unref(&server->config_ref);
957 /* Task callback to close a socket connection after rehash */
959 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
961 SilcServer server = app_context;
962 SilcPacketStream sock = context;
963 SilcIDListData idata = silc_packet_get_context(sock);
964 const char *hostname;
967 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
968 NULL, &hostname, NULL, &port);
970 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
971 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
972 silc_schedule_task_del_by_context(server->schedule, sock);
973 silc_server_disconnect_remote(server, sock,
974 SILC_STATUS_ERR_BANNED_FROM_SERVER,
975 "This connection is removed from "
977 silc_server_free_sock_user_data(server, sock, NULL);
980 /* This function basically reads the config file again and switches the config
981 object pointed by the server object. After that, we have to fix various
982 things such as the server_name and the listening ports.
983 Keep in mind that we no longer have the root privileges at this point. */
985 SilcBool silc_server_rehash(SilcServer server)
987 SilcServerConfig newconfig;
989 SILC_LOG_INFO(("Rehashing server"));
991 /* Reset the logging system */
992 silc_log_quick(TRUE);
993 silc_log_flush_all();
995 /* Start the main rehash phase (read again the config file) */
996 newconfig = silc_server_config_alloc(server->config_file, server);
998 SILC_LOG_ERROR(("Rehash FAILED."));
1002 /* Fix the server_name field */
1003 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1004 silc_free(server->server_name);
1006 /* Check server name */
1007 server->server_name =
1008 silc_identifier_check(newconfig->server_info->server_name,
1009 strlen(newconfig->server_info->server_name),
1010 SILC_STRING_LOCALE, 256, NULL);
1011 if (!server->server_name) {
1012 SILC_LOG_ERROR(("Malformed server name string '%s'",
1013 server->config->server_info->server_name));
1017 /* Update the idcache list with a fresh pointer */
1018 silc_free(server->id_entry->server_name);
1019 server->id_entry->server_name = strdup(server->server_name);
1020 silc_idcache_update_by_context(server->local_list->servers,
1021 server->id_entry, NULL,
1022 strdup(server->id_entry->server_name),
1027 silc_server_config_setlogfiles(server);
1029 /* Change new key pair if necessary */
1030 if (newconfig->server_info->public_key &&
1031 !silc_pkcs_public_key_compare(server->public_key,
1032 newconfig->server_info->public_key)) {
1033 silc_pkcs_public_key_free(server->public_key);
1034 silc_pkcs_private_key_free(server->private_key);
1035 server->public_key = newconfig->server_info->public_key;
1036 server->private_key = newconfig->server_info->private_key;
1037 newconfig->server_info->public_key = NULL;
1038 newconfig->server_info->private_key = NULL;
1041 /* Check for unconfigured server and router connections and close
1042 connections that were unconfigured. */
1044 if (server->config->routers) {
1045 SilcServerConfigRouter *ptr;
1046 SilcServerConfigRouter *newptr;
1049 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1052 /* Check whether new config has this one too */
1053 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1054 if (silc_string_compare(newptr->host, ptr->host) &&
1055 newptr->port == ptr->port &&
1056 newptr->initiator == ptr->initiator) {
1062 if (!found && ptr->host) {
1063 /* Remove this connection */
1064 SilcPacketStream sock;
1065 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1066 ptr->host, ptr->port);
1068 silc_schedule_task_add_timeout(server->schedule,
1069 silc_server_rehash_close_connection,
1075 if (server->config->servers) {
1076 SilcServerConfigServer *ptr;
1077 SilcServerConfigServer *newptr;
1080 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1083 /* Check whether new config has this one too */
1084 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1085 if (silc_string_compare(newptr->host, ptr->host)) {
1091 if (!found && ptr->host) {
1092 /* Remove this connection */
1093 SilcPacketStream sock;
1094 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1097 silc_schedule_task_add_timeout(server->schedule,
1098 silc_server_rehash_close_connection,
1104 if (server->config->clients) {
1105 SilcServerConfigClient *ptr;
1106 SilcServerConfigClient *newptr;
1109 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1112 /* Check whether new config has this one too */
1113 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1114 if (silc_string_compare(newptr->host, ptr->host)) {
1120 if (!found && ptr->host) {
1121 /* Remove this connection */
1122 SilcPacketStream sock;
1123 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1126 silc_schedule_task_add_timeout(server->schedule,
1127 silc_server_rehash_close_connection,
1133 /* Create connections after rehash */
1134 silc_server_create_connections(server);
1136 /* Check whether our router status has changed */
1137 if (newconfig->servers) {
1138 SilcServerConfigServer *ptr = newconfig->servers;
1140 server->server_type = SILC_ROUTER;
1142 if (ptr->backup_router) {
1143 server->server_type = SILC_BACKUP_ROUTER;
1144 server->backup_router = TRUE;
1145 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1152 /* Our old config is gone now. We'll unreference our reference made in
1153 silc_server_init and then destroy it since we are destroying it
1154 underneath the application (layer which called silc_server_init). */
1155 silc_server_config_unref(&server->config_ref);
1156 silc_server_config_destroy(server->config);
1158 /* Take new config context */
1159 server->config = newconfig;
1160 silc_server_config_ref(&server->config_ref, server->config, server->config);
1163 /* Set debugging on if configured */
1164 if (server->config->debug_string) {
1165 silc_log_debug(TRUE);
1166 silc_log_set_debug_string(server->config->debug_string);
1168 #endif /* SILC_DEBUG */
1170 SILC_LOG_DEBUG(("Server rehashed"));
1175 /* The heart of the server. This runs the scheduler thus runs the server.
1176 When this returns the server has been stopped and the program will
1179 void silc_server_run(SilcServer server)
1181 SILC_LOG_INFO(("SILC Server started"));
1183 /* Start the scheduler, the heart of the SILC server. When this returns
1184 the program will be terminated. */
1185 silc_schedule(server->schedule);
1188 /* Stops the SILC server. This function is used to shutdown the server.
1189 This is usually called after the scheduler has returned. After stopping
1190 the server one should call silc_server_free. */
1192 void silc_server_stop(SilcServer server)
1195 SilcPacketStream ps;
1196 SilcNetListener listener;
1198 SILC_LOG_INFO(("SILC Server shutting down"));
1200 server->server_shutdown = TRUE;
1202 /* Close all connections */
1203 if (server->packet_engine) {
1204 list = silc_packet_engine_get_streams(server->packet_engine);
1206 silc_dlist_start(list);
1207 while ((ps = silc_dlist_get(list))) {
1208 SilcIDListData idata = silc_packet_get_context(ps);
1210 if (!silc_packet_stream_is_valid(ps))
1214 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1216 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1217 "Server is shutting down");
1218 silc_server_free_sock_user_data(server, ps,
1219 "Server is shutting down");
1221 silc_packet_engine_free_streams_list(list);
1224 /* We are not connected to network anymore */
1225 server->standalone = TRUE;
1227 silc_dlist_start(server->listeners);
1228 while ((listener = silc_dlist_get(server->listeners)))
1229 silc_net_close_listener(listener);
1231 silc_server_http_uninit(server);
1233 /* Cancel any possible retry timeouts */
1234 silc_schedule_task_del_by_callback(server->schedule,
1235 silc_server_connect_router);
1236 silc_schedule_task_del_by_callback(server->schedule,
1237 silc_server_connect_to_router_retry);
1238 silc_schedule_task_del_by_callback(server->schedule,
1239 silc_server_connect_to_router);
1241 silc_schedule_stop(server->schedule);
1243 SILC_LOG_DEBUG(("Server stopped"));
1246 /* Purge expired client entries from the server */
1248 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1250 SilcServer server = context;
1251 SilcClientEntry client;
1253 SilcUInt64 curtime = silc_time();
1255 SILC_LOG_DEBUG(("Expire timeout"));
1257 silc_dlist_start(server->expired_clients);
1258 while ((client = silc_dlist_get(server->expired_clients))) {
1259 if (client->data.status & SILC_IDLIST_STATUS_REGISTERED)
1262 /* For unregistered clients the created timestamp is actually
1263 unregistered timestamp. Make sure client remains in history
1264 at least 500 seconds. */
1265 if (curtime - client->data.created < 500)
1268 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1269 server->local_list : server->global_list);
1271 silc_idlist_del_data(client);
1272 silc_idlist_del_client(id_list, client);
1273 silc_dlist_del(server->expired_clients, client);
1276 silc_schedule_task_add_timeout(server->schedule,
1277 silc_server_purge_expired_clients, server,
1282 /******************************* Connecting *********************************/
1284 /* Free connection context */
1286 void silc_server_connection_free(SilcServerConnection sconn)
1288 SILC_LOG_DEBUG(("Free connection %p", sconn));
1289 silc_dlist_del(sconn->server->conns, sconn);
1290 silc_server_config_unref(&sconn->conn);
1291 silc_free(sconn->remote_host);
1292 silc_free(sconn->backup_replace_ip);
1296 /* Creates connection to a remote router. */
1298 void silc_server_create_connection(SilcServer server,
1301 const char *remote_host, SilcUInt32 port,
1302 SilcServerConnectCallback callback,
1305 SilcServerConnection sconn;
1307 /* Allocate connection object for hold connection specific stuff. */
1308 sconn = silc_calloc(1, sizeof(*sconn));
1311 sconn->remote_host = strdup(remote_host);
1312 sconn->remote_port = port;
1313 sconn->no_reconnect = reconnect == FALSE;
1314 sconn->callback = callback;
1315 sconn->callback_context = context;
1316 sconn->no_conf = dynamic;
1317 sconn->server = server;
1319 SILC_LOG_DEBUG(("Created connection %p", sconn));
1321 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1325 /* Connection authentication completion callback */
1328 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1331 SilcServerConnection sconn = context;
1332 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1333 SilcServer server = entry->server;
1334 SilcServerConfigServer *conn;
1335 SilcServerConfigConnParams *param;
1336 SilcIDListData idata;
1337 SilcServerEntry id_entry = NULL;
1338 unsigned char id[32];
1343 SILC_LOG_DEBUG(("Connection authentication completed"));
1347 if (success == FALSE) {
1348 /* Authentication failed */
1349 /* XXX retry connecting */
1351 silc_server_disconnect_remote(server, sconn->sock,
1352 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1353 if (sconn->callback)
1354 (*sconn->callback)(server, NULL, sconn->callback_context);
1355 silc_server_connection_free(sconn);
1359 /* XXX For now remote is router always */
1360 entry->data.conn_type = SILC_CONN_ROUTER;
1362 SILC_LOG_INFO(("Connected to %s %s",
1363 SILC_CONNTYPE_STRING(entry->data.conn_type),
1364 sconn->remote_host));
1366 /* Create the actual entry for remote entity */
1367 switch (entry->data.conn_type) {
1368 case SILC_CONN_SERVER:
1369 SILC_LOG_DEBUG(("Remote is SILC server"));
1371 /* Add new server. The server must register itself to us before it
1372 becomes registered to SILC network. */
1373 id_entry = silc_idlist_add_server(server->local_list,
1374 strdup(sconn->remote_host),
1375 SILC_SERVER, NULL, NULL, sconn->sock);
1377 silc_server_disconnect_remote(server, sconn->sock,
1378 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1379 if (sconn->callback)
1380 (*sconn->callback)(server, NULL, sconn->callback_context);
1381 silc_server_connection_free(sconn);
1387 server->stat.my_servers++;
1388 if (server->server_type == SILC_ROUTER)
1389 server->stat.servers++;
1390 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1392 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1395 case SILC_CONN_ROUTER:
1396 SILC_LOG_DEBUG(("Remote is SILC router"));
1398 /* Register to network */
1399 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1400 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1401 SILC_STR_UI_SHORT(id_len),
1402 SILC_STR_DATA(id, id_len),
1403 SILC_STR_UI_SHORT(strlen(server->server_name)),
1404 SILC_STR_DATA(server->server_name,
1405 strlen(server->server_name)),
1407 silc_server_disconnect_remote(server, sconn->sock,
1408 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1409 if (sconn->callback)
1410 (*sconn->callback)(server, NULL, sconn->callback_context);
1411 silc_server_connection_free(sconn);
1417 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1419 /* Check that we do not have this ID already */
1420 id_entry = silc_idlist_find_server_by_id(server->local_list,
1421 &remote_id.u.server_id,
1424 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1426 id_entry = silc_idlist_find_server_by_id(server->global_list,
1427 &remote_id.u.server_id,
1430 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1434 SILC_LOG_DEBUG(("New server id(%s)",
1435 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1437 /* Add the connected router to global server list. Router is sent
1438 as NULL since it's local to us. */
1439 id_entry = silc_idlist_add_server(server->global_list,
1440 strdup(sconn->remote_host),
1442 silc_id_dup(&remote_id.u.server_id,
1446 silc_server_disconnect_remote(server, sconn->sock,
1447 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1448 if (sconn->callback)
1449 (*sconn->callback)(server, NULL, sconn->callback_context);
1450 silc_server_connection_free(sconn);
1456 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1457 idata = (SilcIDListData)id_entry;
1458 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1459 SILC_IDLIST_STATUS_LOCAL);
1460 idata->sconn = sconn;
1463 server->stat.my_routers++;
1464 if (server->server_type == SILC_ROUTER)
1465 server->stat.routers++;
1466 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1468 if (!sconn->backup) {
1469 /* Mark this router our primary router if we're still standalone */
1470 if (server->standalone) {
1471 SILC_LOG_DEBUG(("This connection is our primary router"));
1472 server->id_entry->router = id_entry;
1473 server->router = id_entry;
1474 server->router->server_type = SILC_ROUTER;
1475 server->standalone = FALSE;
1476 server->backup_primary = FALSE;
1478 /* Announce data if we are not backup router (unless not as primary
1479 currently). Backup router announces later at the end of
1480 resuming protocol. */
1481 if (server->backup_router && server->server_type == SILC_ROUTER) {
1482 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1484 /* If we are router then announce our possible servers. Backup
1485 router announces also global servers. */
1486 if (server->server_type == SILC_ROUTER)
1487 silc_server_announce_servers(server,
1488 server->backup_router ? TRUE : FALSE,
1489 0, SILC_PRIMARY_ROUTE(server));
1491 /* Announce our clients and channels to the router */
1492 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1493 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1496 /* If we are backup router then this primary router is whom we are
1498 if (server->server_type == SILC_BACKUP_ROUTER) {
1499 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1501 NULL, NULL, &ip, NULL);
1502 silc_server_backup_add(server, server->id_entry, ip,
1503 sconn->remote_port, TRUE);
1507 /* We already have primary router. Disconnect this connection */
1508 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1509 silc_idlist_del_server(server->global_list, id_entry);
1510 silc_server_disconnect_remote(server, sconn->sock,
1511 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1512 if (sconn->callback)
1513 (*sconn->callback)(server, NULL, sconn->callback_context);
1514 silc_server_connection_free(sconn);
1520 /* Add this server to be our backup router */
1521 id_entry->server_type = SILC_BACKUP_ROUTER;
1522 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1523 sconn->backup_replace_port, FALSE);
1529 silc_server_disconnect_remote(server, sconn->sock,
1530 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1531 if (sconn->callback)
1532 (*sconn->callback)(server, NULL, sconn->callback_context);
1533 silc_server_connection_free(sconn);
1538 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1540 conn = sconn->conn.ref_ptr;
1541 param = &server->config->param;
1542 if (conn && conn->param)
1543 param = conn->param;
1545 /* Register rekey timeout */
1546 sconn->rekey_timeout = param->key_exchange_rekey;
1547 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1548 sconn->sock, sconn->rekey_timeout, 0);
1550 /* Set the entry as packet stream context */
1551 silc_packet_set_context(sconn->sock, id_entry);
1553 /* Call the completion callback to indicate that we've connected to
1555 if (sconn && sconn->callback)
1556 (*sconn->callback)(server, id_entry, sconn->callback_context);
1558 if (sconn == server->router_conn)
1559 server->router_conn = NULL;
1564 /* SKE completion callback */
1566 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1567 SilcSKESecurityProperties prop,
1568 SilcSKEKeyMaterial keymat,
1569 SilcSKERekeyMaterial rekey,
1572 SilcPacketStream sock = context;
1573 SilcUnknownEntry entry = silc_packet_get_context(sock);
1574 SilcServerConnection sconn = silc_ske_get_context(ske);
1575 SilcServer server = entry->server;
1576 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1577 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1578 void *auth_data = NULL;
1579 SilcUInt32 auth_data_len = 0;
1580 SilcConnAuth connauth;
1581 SilcCipher send_key, receive_key;
1582 SilcHmac hmac_send, hmac_receive;
1587 if (status != SILC_SKE_STATUS_OK) {
1589 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1590 silc_ske_map_status(status), entry->hostname, entry->ip));
1592 /* XXX retry connecting */
1594 silc_server_disconnect_remote(server, sconn->sock,
1595 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1596 if (sconn->callback)
1597 (*sconn->callback)(server, NULL, sconn->callback_context);
1598 silc_server_connection_free(sconn);
1602 SILC_LOG_DEBUG(("Setting keys into use"));
1604 /* Set the keys into use. The data will be encrypted after this. */
1605 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1606 &hmac_send, &hmac_receive, &hash)) {
1608 /* XXX retry connecting */
1610 /* Error setting keys */
1612 silc_server_disconnect_remote(server, sconn->sock,
1613 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1614 if (sconn->callback)
1615 (*sconn->callback)(server, NULL, sconn->callback_context);
1616 silc_server_connection_free(sconn);
1619 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1620 hmac_receive, FALSE);
1622 SILC_LOG_DEBUG(("Starting connection authentication"));
1624 connauth = silc_connauth_alloc(server->schedule, ske,
1625 server->config->conn_auth_timeout);
1627 /* XXX retry connecting */
1629 /** Error allocating auth protocol */
1631 silc_server_disconnect_remote(server, sconn->sock,
1632 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1633 if (sconn->callback)
1634 (*sconn->callback)(server, NULL, sconn->callback_context);
1635 silc_server_connection_free(sconn);
1639 /* Get authentication method */
1641 if (conn->passphrase) {
1642 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1643 auth_meth = SILC_AUTH_PUBLIC_KEY;
1644 auth_data = server->private_key;
1646 auth_meth = SILC_AUTH_PASSWORD;
1647 auth_data = conn->passphrase;
1648 auth_data_len = conn->passphrase_len;
1651 auth_meth = SILC_AUTH_PUBLIC_KEY;
1652 auth_data = server->private_key;
1656 entry->data.rekey = rekey;
1658 /* Start connection authentication */
1660 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1661 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1662 auth_data, auth_data_len,
1663 silc_server_ke_auth_compl, sconn);
1666 /* Function that is called when the network connection to a router has
1667 been established. This will continue with the key exchange protocol
1668 with the remote router. */
1670 void silc_server_start_key_exchange(SilcServerConnection sconn)
1672 SilcServer server = sconn->server;
1673 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1674 SilcUnknownEntry entry;
1675 SilcSKEParamsStruct params;
1678 /* Cancel any possible retry timeouts */
1679 silc_schedule_task_del_by_context(server->schedule, sconn);
1681 /* Create packet stream */
1682 sconn->sock = silc_packet_stream_create(server->packet_engine,
1683 server->schedule, sconn->stream);
1685 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1686 silc_stream_destroy(sconn->stream);
1687 if (sconn->callback)
1688 (*sconn->callback)(server, NULL, sconn->callback_context);
1689 silc_server_connection_free(sconn);
1692 server->stat.conn_num++;
1694 /* Set source ID to packet stream */
1695 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1697 silc_packet_stream_destroy(sconn->sock);
1698 if (sconn->callback)
1699 (*sconn->callback)(server, NULL, sconn->callback_context);
1700 silc_server_connection_free(sconn);
1704 /* Create entry for remote entity */
1705 entry = silc_calloc(1, sizeof(*entry));
1707 silc_packet_stream_destroy(sconn->sock);
1708 silc_server_connection_free(sconn);
1711 entry->server = server;
1712 silc_packet_set_context(sconn->sock, entry);
1714 /* Set Key Exchange flags from configuration, but fall back to global
1716 memset(¶ms, 0, sizeof(params));
1717 SILC_GET_SKE_FLAGS(conn, params.flags);
1718 if (server->config->param.key_exchange_pfs)
1719 params.flags |= SILC_SKE_SP_FLAG_PFS;
1721 /* Start SILC Key Exchange protocol */
1722 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1723 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1724 server->public_key, server->private_key, sconn);
1727 silc_packet_stream_destroy(sconn->sock);
1728 if (sconn->callback)
1729 (*sconn->callback)(server, NULL, sconn->callback_context);
1730 silc_server_connection_free(sconn);
1733 silc_ske_set_callbacks(ske, silc_server_verify_key,
1734 silc_server_ke_completed, sconn->sock);
1736 /* Start key exchange protocol */
1737 params.version = silc_version_string;
1738 params.timeout_secs = server->config->key_exchange_timeout;
1739 sconn->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1742 /* Timeout callback that will be called to retry connecting to remote
1743 router. This is used by both normal and router server. This will wait
1744 before retrying the connecting. The timeout is generated by exponential
1745 backoff algorithm. */
1747 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1749 SilcServerConnection sconn = context;
1750 SilcServer server = sconn->server;
1751 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1752 SilcServerConfigConnParams *param =
1753 (conn->param ? conn->param : &server->config->param);
1755 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1756 sconn->remote_port));
1758 /* Calculate next timeout */
1759 if (sconn->retry_count >= 1) {
1760 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1761 if (sconn->retry_timeout > param->reconnect_interval_max)
1762 sconn->retry_timeout = param->reconnect_interval_max;
1764 sconn->retry_timeout = param->reconnect_interval;
1766 sconn->retry_count++;
1767 sconn->retry_timeout = sconn->retry_timeout +
1768 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1770 /* If we've reached max retry count, give up. */
1771 if ((sconn->retry_count > param->reconnect_count) &&
1772 !param->reconnect_keep_trying) {
1773 SILC_LOG_ERROR(("Could not connect, giving up"));
1775 if (sconn->callback)
1776 (*sconn->callback)(server, NULL, sconn->callback_context);
1777 silc_server_connection_free(sconn);
1781 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1783 /* We will lookup a fresh pointer later */
1784 silc_server_config_unref(&sconn->conn);
1786 /* Wait before retrying */
1787 silc_schedule_task_del_by_context(server->schedule, sconn);
1788 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1789 sconn, sconn->retry_timeout, 0);
1792 /* Callback for async connection to remote router */
1794 static void silc_server_connection_established(SilcNetStatus status,
1798 SilcServerConnection sconn = context;
1799 SilcServer server = sconn->server;
1801 silc_schedule_task_del_by_context(server->schedule, sconn);
1806 SILC_LOG_DEBUG(("Connection to %s:%d established",
1807 sconn->remote_host, sconn->remote_port));
1809 /* Continue with key exchange protocol */
1810 sconn->stream = stream;
1811 silc_server_start_key_exchange(sconn);
1814 case SILC_NET_UNKNOWN_IP:
1815 case SILC_NET_UNKNOWN_HOST:
1816 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1817 sconn->remote_host, sconn->remote_port,
1818 silc_net_get_error_string(status)));
1820 if (sconn->callback)
1821 (*sconn->callback)(server, NULL, sconn->callback_context);
1822 silc_server_connection_free(sconn);
1826 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1827 sconn->remote_host, sconn->remote_port,
1828 silc_net_get_error_string(status)));
1829 if (!sconn->no_reconnect) {
1830 silc_schedule_task_add_timeout(sconn->server->schedule,
1831 silc_server_connect_to_router_retry,
1833 silc_dlist_del(server->conns, sconn);
1835 if (sconn->callback)
1836 (*sconn->callback)(server, NULL, sconn->callback_context);
1837 silc_server_connection_free(sconn);
1843 /* Generic routine to use connect to a router. */
1845 SILC_TASK_CALLBACK(silc_server_connect_router)
1847 SilcServerConnection sconn = context;
1848 SilcServer server = sconn->server;
1849 SilcServerConfigRouter *rconn;
1851 silc_schedule_task_del_by_context(server->schedule, sconn);
1853 /* Don't connect if we are shutting down. */
1854 if (server->server_shutdown) {
1855 if (sconn->callback)
1856 (*sconn->callback)(server, NULL, sconn->callback_context);
1857 silc_server_connection_free(sconn);
1861 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1862 (sconn->backup ? "backup router" : "router"),
1863 sconn->remote_host, sconn->remote_port));
1865 if (!sconn->no_conf) {
1866 /* Find connection configuration */
1867 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1868 sconn->remote_port);
1870 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1871 (sconn->backup ? "backup router" : "router"),
1872 sconn->remote_host, sconn->remote_port));
1873 silc_server_connection_free(sconn);
1876 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1879 /* Connect to remote host */
1881 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1882 server->config->server_info->primary->server_ip),
1883 sconn->remote_host, sconn->remote_port,
1884 server->schedule, silc_server_connection_established,
1887 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1888 sconn->remote_host, sconn->remote_port));
1889 silc_server_connection_free(sconn);
1893 /* Add to connection list */
1894 silc_dlist_add(server->conns, sconn);
1897 /* This function connects to our primary router or if we are a router this
1898 establishes all our primary routes. This is called at the start of the
1899 server to do authentication and key exchange with our router - called
1902 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1904 SilcServer server = context;
1905 SilcServerConnection sconn;
1906 SilcServerConfigRouter *ptr;
1908 /* Don't connect if we are shutting down. */
1909 if (server->server_shutdown)
1912 SILC_LOG_DEBUG(("We are %s",
1913 (server->server_type == SILC_SERVER ?
1914 "normal server" : server->server_type == SILC_ROUTER ?
1915 "router" : "backup router/normal server")));
1917 if (!server->config->routers) {
1918 /* There wasn't a configured router, we will continue but we don't
1919 have a connection to outside world. We will be standalone server. */
1920 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1921 server->standalone = TRUE;
1925 /* Cancel any possible retry timeouts */
1926 silc_schedule_task_del_by_callback(server->schedule,
1927 silc_server_connect_router);
1928 silc_schedule_task_del_by_callback(server->schedule,
1929 silc_server_connect_to_router_retry);
1931 /* Create the connections to all our routes */
1932 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1934 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1935 ptr->backup_router ? "Backup router" : "Router",
1936 ptr->initiator ? "Initiator" : "Responder",
1937 ptr->host, ptr->port));
1939 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1940 ptr->initiator == FALSE && !server->backup_router &&
1941 !silc_server_config_get_backup_router(server))
1942 server->wait_backup = TRUE;
1944 if (!ptr->initiator)
1946 if (ptr->dynamic_connection)
1949 /* Check whether we are connecting or connected to this host already */
1950 if (silc_server_num_sockets_by_remote(server,
1951 silc_net_is_ip(ptr->host) ?
1953 silc_net_is_ip(ptr->host) ?
1954 NULL : ptr->host, ptr->port,
1955 SILC_CONN_ROUTER)) {
1956 SILC_LOG_DEBUG(("We are already connected to %s:%d",
1957 ptr->host, ptr->port));
1959 /* If we don't have primary router and this connection is our
1960 primary router we are in desync. Reconnect to the primary. */
1961 if (server->standalone && !server->router) {
1963 SilcPacketStream sock;
1964 SilcServerConfigRouter *primary =
1965 silc_server_config_get_primary_router(server);
1968 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1969 ptr->host, ptr->port);
1972 server->backup_noswitch = TRUE;
1973 silc_server_free_sock_user_data(server, sock, NULL);
1974 silc_server_disconnect_remote(server, sock, 0, NULL);
1975 server->backup_noswitch = FALSE;
1976 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1982 /* Allocate connection object for hold connection specific stuff. */
1983 sconn = silc_calloc(1, sizeof(*sconn));
1986 sconn->server = server;
1987 sconn->remote_host = strdup(ptr->host);
1988 sconn->remote_port = ptr->port;
1989 sconn->backup = ptr->backup_router;
1990 if (sconn->backup) {
1991 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1992 sconn->backup_replace_port = ptr->backup_replace_port;
1995 SILC_LOG_DEBUG(("Created connection %p", sconn));
1997 if (!server->router_conn && !sconn->backup)
1998 server->router_conn = sconn;
2001 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2007 /************************ Accepting new connection **************************/
2009 /* After this is called, server don't wait for backup router anymore.
2010 This gets called automatically even after we have backup router
2011 connection established. */
2013 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2015 SilcServer server = context;
2016 server->wait_backup = FALSE;
2019 /* Authentication data callback */
2022 silc_server_accept_get_auth(SilcConnAuth connauth,
2023 SilcConnectionType conn_type,
2024 unsigned char **passphrase,
2025 SilcUInt32 *passphrase_len,
2026 SilcSKR *repository,
2029 SilcPacketStream sock = context;
2030 SilcUnknownEntry entry = silc_packet_get_context(sock);
2031 SilcServer server = entry->server;
2033 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2035 /* Remote end is client */
2036 if (conn_type == SILC_CONN_CLIENT) {
2037 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2041 *passphrase = cconfig->passphrase;
2042 *passphrase_len = cconfig->passphrase_len;
2043 if (cconfig->publickeys)
2044 *repository = server->repository;
2046 entry->data.conn_type = conn_type;
2050 /* Remote end is server */
2051 if (conn_type == SILC_CONN_SERVER) {
2052 SilcServerConfigServer *sconfig;
2054 /* If we are normal server, don't accept the connection */
2055 if (server->server_type == SILC_SERVER)
2058 sconfig = entry->sconfig.ref_ptr;
2062 *passphrase = sconfig->passphrase;
2063 *passphrase_len = sconfig->passphrase_len;
2064 if (sconfig->publickeys)
2065 *repository = server->repository;
2067 entry->data.conn_type = conn_type;
2071 /* Remote end is router */
2072 if (conn_type == SILC_CONN_ROUTER) {
2073 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2077 *passphrase = rconfig->passphrase;
2078 *passphrase_len = rconfig->passphrase_len;
2079 if (rconfig->publickeys)
2080 *repository = server->repository;
2082 entry->data.conn_type = conn_type;
2089 /* Authentication completion callback. */
2092 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2095 SilcPacketStream sock = context;
2096 SilcUnknownEntry entry = silc_packet_get_context(sock);
2097 SilcIDListData idata = (SilcIDListData)entry;
2098 SilcServer server = entry->server;
2099 SilcServerConfigConnParams *param = &server->config->param;
2100 SilcServerConnection sconn;
2102 const char *hostname, *ip;
2106 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2107 NULL, &hostname, &ip, &port);
2109 if (success == FALSE) {
2110 /* Authentication failed */
2111 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2112 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2113 server->stat.auth_failures++;
2114 silc_server_disconnect_remote(server, sock,
2115 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2119 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2121 switch (entry->data.conn_type) {
2122 case SILC_CONN_CLIENT:
2124 SilcClientEntry client;
2125 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2127 /* Verify whether this connection is after all allowed to connect */
2128 if (!silc_server_connection_allowed(server, sock, entry->data.conn_type,
2129 &server->config->param,
2131 silc_connauth_get_ske(connauth))) {
2132 server->stat.auth_failures++;
2136 /* If we are primary router and we have backup router configured
2137 but it has not connected to use yet, do not accept any other
2139 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2140 !server->backup_router) {
2141 SilcServerConfigRouter *router;
2142 router = silc_server_config_get_backup_router(server);
2143 if (router && strcmp(server->config->server_info->primary->server_ip,
2145 silc_server_find_socket_by_host(server,
2147 router->backup_replace_ip, 0)) {
2148 SILC_LOG_INFO(("Will not accept connections because we do "
2149 "not have backup router connection established"));
2150 silc_server_disconnect_remote(server, sock,
2151 SILC_STATUS_ERR_PERM_DENIED,
2152 "We do not have connection to backup "
2153 "router established, try later");
2154 server->stat.auth_failures++;
2156 /* From here on, wait 20 seconds for the backup router to appear. */
2157 silc_schedule_task_add_timeout(server->schedule,
2158 silc_server_backup_router_wait,
2159 (void *)server, 20, 0);
2164 SILC_LOG_DEBUG(("Remote host is client"));
2165 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2168 /* Add the client to the client ID cache. The nickname and Client ID
2169 and other information is created after we have received NEW_CLIENT
2170 packet from client. */
2171 client = silc_idlist_add_client(server->local_list,
2172 NULL, NULL, NULL, NULL, NULL, sock);
2174 SILC_LOG_ERROR(("Could not add new client to cache"));
2175 server->stat.auth_failures++;
2176 silc_server_disconnect_remote(server, sock,
2177 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2180 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2183 server->stat.my_clients++;
2184 server->stat.clients++;
2185 server->stat.cell_clients++;
2187 /* Get connection parameters */
2189 param = conn->param;
2191 if (!param->keepalive_secs)
2192 param->keepalive_secs = server->config->param.keepalive_secs;
2194 if (!param->qos && server->config->param.qos) {
2195 param->qos = server->config->param.qos;
2196 param->qos_rate_limit = server->config->param.qos_rate_limit;
2197 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2198 param->qos_limit_sec = server->config->param.qos_limit_sec;
2199 param->qos_limit_usec = server->config->param.qos_limit_usec;
2202 /* Check if to be anonymous connection */
2203 if (param->anonymous)
2204 client->mode |= SILC_UMODE_ANONYMOUS;
2207 /* Add public key to repository */
2208 if (!silc_server_get_public_key_by_client(server, client, NULL))
2209 silc_skr_add_public_key_simple(server->repository,
2210 entry->data.public_key,
2211 SILC_SKR_USAGE_IDENTIFICATION, client,
2214 id_entry = (void *)client;
2218 case SILC_CONN_SERVER:
2219 case SILC_CONN_ROUTER:
2221 SilcServerEntry new_server;
2222 SilcBool initiator = FALSE;
2223 SilcBool backup_local = FALSE;
2224 SilcBool backup_router = FALSE;
2225 char *backup_replace_ip = NULL;
2226 SilcUInt16 backup_replace_port = 0;
2227 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2228 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2230 /* If we are backup router and this is incoming server connection
2231 and we do not have connection to primary router, do not allow
2233 if (server->server_type == SILC_BACKUP_ROUTER &&
2234 entry->data.conn_type == SILC_CONN_SERVER &&
2235 !SILC_PRIMARY_ROUTE(server)) {
2236 SILC_LOG_INFO(("Will not accept server connection because we do "
2237 "not have primary router connection established"));
2238 silc_server_disconnect_remote(server, sock,
2239 SILC_STATUS_ERR_PERM_DENIED,
2240 "We do not have connection to primary "
2241 "router established, try later");
2242 server->stat.auth_failures++;
2246 if (entry->data.conn_type == SILC_CONN_ROUTER) {
2247 /* Verify whether this connection is after all allowed to connect */
2248 if (!silc_server_connection_allowed(server, sock,
2249 entry->data.conn_type,
2250 &server->config->param,
2251 rconn ? rconn->param : NULL,
2252 silc_connauth_get_ske(connauth))) {
2253 server->stat.auth_failures++;
2259 param = rconn->param;
2261 if (!param->keepalive_secs)
2262 param->keepalive_secs = server->config->param.keepalive_secs;
2264 if (!param->qos && server->config->param.qos) {
2265 param->qos = server->config->param.qos;
2266 param->qos_rate_limit = server->config->param.qos_rate_limit;
2267 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2268 param->qos_limit_sec = server->config->param.qos_limit_sec;
2269 param->qos_limit_usec = server->config->param.qos_limit_usec;
2273 initiator = rconn->initiator;
2274 backup_local = rconn->backup_local;
2275 backup_router = rconn->backup_router;
2276 backup_replace_ip = rconn->backup_replace_ip;
2277 backup_replace_port = rconn->backup_replace_port;
2281 if (entry->data.conn_type == SILC_CONN_SERVER) {
2282 /* Verify whether this connection is after all allowed to connect */
2283 if (!silc_server_connection_allowed(server, sock,
2284 entry->data.conn_type,
2285 &server->config->param,
2286 srvconn ? srvconn->param : NULL,
2287 silc_connauth_get_ske(connauth))) {
2288 server->stat.auth_failures++;
2292 if (srvconn->param) {
2293 param = srvconn->param;
2295 if (!param->keepalive_secs)
2296 param->keepalive_secs = server->config->param.keepalive_secs;
2298 if (!param->qos && server->config->param.qos) {
2299 param->qos = server->config->param.qos;
2300 param->qos_rate_limit = server->config->param.qos_rate_limit;
2301 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2302 param->qos_limit_sec = server->config->param.qos_limit_sec;
2303 param->qos_limit_usec = server->config->param.qos_limit_usec;
2307 backup_router = srvconn->backup_router;
2311 /* If we are primary router and we have backup router configured
2312 but it has not connected to use yet, do not accept any other
2314 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2315 !server->backup_router && !backup_router) {
2316 SilcServerConfigRouter *router;
2317 router = silc_server_config_get_backup_router(server);
2318 if (router && strcmp(server->config->server_info->primary->server_ip,
2320 silc_server_find_socket_by_host(server,
2322 router->backup_replace_ip, 0)) {
2323 SILC_LOG_INFO(("Will not accept connections because we do "
2324 "not have backup router connection established"));
2325 silc_server_disconnect_remote(server, sock,
2326 SILC_STATUS_ERR_PERM_DENIED,
2327 "We do not have connection to backup "
2328 "router established, try later");
2329 server->stat.auth_failures++;
2331 /* From here on, wait 20 seconds for the backup router to appear. */
2332 silc_schedule_task_add_timeout(server->schedule,
2333 silc_server_backup_router_wait,
2334 (void *)server, 20, 0);
2339 SILC_LOG_DEBUG(("Remote host is %s",
2340 entry->data.conn_type == SILC_CONN_SERVER ?
2341 "server" : (backup_router ?
2342 "backup router" : "router")));
2343 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2344 entry->ip, entry->data.conn_type == SILC_CONN_SERVER ?
2345 "server" : (backup_router ?
2346 "backup router" : "router")));
2348 /* Add the server into server cache. The server name and Server ID
2349 is updated after we have received NEW_SERVER packet from the
2350 server. We mark ourselves as router for this server if we really
2353 silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ?
2354 server->local_list : (backup_router ?
2355 server->local_list :
2356 server->global_list)),
2358 (entry->data.conn_type == SILC_CONN_SERVER ?
2359 SILC_SERVER : SILC_ROUTER),
2361 (entry->data.conn_type == SILC_CONN_SERVER ?
2362 server->id_entry : (backup_router ?
2363 server->id_entry : NULL)),
2366 SILC_LOG_ERROR(("Could not add new server to cache"));
2367 silc_server_disconnect_remote(server, sock,
2368 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2369 server->stat.auth_failures++;
2372 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2374 id_entry = (void *)new_server;
2376 /* If the incoming connection is router and marked as backup router
2377 then add it to be one of our backups */
2378 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2379 /* Change it back to SERVER type since that's what it really is. */
2381 entry->data.conn_type = SILC_CONN_SERVER;
2382 new_server->server_type = SILC_BACKUP_ROUTER;
2384 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2385 ("Backup router %s is now online",
2388 /* Remove the backup waiting with timeout */
2389 silc_schedule_task_add_timeout(server->schedule,
2390 silc_server_backup_router_wait,
2391 (void *)server, 10, 0);
2395 if (entry->data.conn_type == SILC_CONN_SERVER) {
2396 server->stat.my_servers++;
2397 server->stat.servers++;
2398 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2400 server->stat.my_routers++;
2401 server->stat.routers++;
2402 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2405 /* Check whether this connection is to be our primary router connection
2406 if we do not already have the primary route. */
2407 if (!backup_router &&
2408 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2409 if (silc_server_config_is_primary_route(server) && !initiator)
2412 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2413 server->standalone = FALSE;
2414 if (!server->id_entry->router) {
2415 server->id_entry->router = id_entry;
2416 server->router = id_entry;
2428 /* Add connection to server->conns so that we know we have connection
2430 sconn = silc_calloc(1, sizeof(*sconn));
2431 sconn->server = server;
2433 sconn->remote_host = strdup(hostname);
2434 sconn->remote_port = port;
2435 silc_dlist_add(server->conns, sconn);
2436 idata->sconn = sconn;
2437 idata->last_receive = time(NULL);
2439 /* Add the common data structure to the ID entry. */
2440 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2441 silc_packet_set_context(sock, id_entry);
2443 /* Connection has been fully established now. Everything is ok. */
2444 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2446 /* Perform Quality of Service */
2448 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2449 param->qos_rate_limit, param->qos_bytes_limit,
2450 param->qos_limit_sec, param->qos_limit_usec);
2452 silc_server_config_unref(&entry->cconfig);
2453 silc_server_config_unref(&entry->sconfig);
2454 silc_server_config_unref(&entry->rconfig);
2458 silc_ske_free(silc_connauth_get_ske(connauth));
2459 silc_connauth_free(connauth);
2462 /* SKE completion callback. We set the new keys into use here. */
2465 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2466 SilcSKESecurityProperties prop,
2467 SilcSKEKeyMaterial keymat,
2468 SilcSKERekeyMaterial rekey,
2471 SilcPacketStream sock = context;
2472 SilcUnknownEntry entry = silc_packet_get_context(sock);
2473 SilcIDListData idata = (SilcIDListData)entry;
2474 SilcServer server = entry->server;
2475 SilcConnAuth connauth;
2476 SilcCipher send_key, receive_key;
2477 SilcHmac hmac_send, hmac_receive;
2484 if (status != SILC_SKE_STATUS_OK) {
2486 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2487 silc_ske_map_status(status), entry->hostname, entry->ip));
2489 silc_server_disconnect_remote(server, sock,
2490 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2494 SILC_LOG_DEBUG(("Setting keys into use"));
2496 /* Set the keys into use. The data will be encrypted after this. */
2497 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2498 &hmac_send, &hmac_receive, &hash)) {
2499 /* Error setting keys */
2501 silc_server_disconnect_remote(server, sock,
2502 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2505 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2506 hmac_receive, FALSE);
2508 idata->rekey = rekey;
2509 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2510 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2511 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2513 SILC_LOG_DEBUG(("Starting connection authentication"));
2514 server->stat.auth_attempts++;
2516 connauth = silc_connauth_alloc(server->schedule, ske,
2517 server->config->conn_auth_timeout);
2519 /** Error allocating auth protocol */
2521 silc_server_disconnect_remote(server, sock,
2522 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2526 /* Start connection authentication */
2528 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2529 silc_server_accept_auth_compl, sock);
2532 /* Accept new TCP connection */
2534 static void silc_server_accept_new_connection(SilcNetStatus status,
2538 SilcServer server = context;
2539 SilcPacketStream packet_stream;
2540 SilcServerConfigClient *cconfig = NULL;
2541 SilcServerConfigServer *sconfig = NULL;
2542 SilcServerConfigRouter *rconfig = NULL;
2543 SilcServerConfigDeny *deny;
2544 SilcUnknownEntry entry;
2546 SilcSKEParamsStruct params;
2547 char *hostname, *ip;
2550 SILC_LOG_DEBUG(("Accepting new connection"));
2552 /* Check for maximum allowed connections */
2553 server->stat.conn_attempts++;
2554 if (silc_dlist_count(server->conns) >
2555 server->config->param.connections_max) {
2556 SILC_LOG_ERROR(("Refusing connection, server is full"));
2557 server->stat.conn_failures++;
2558 silc_stream_destroy(stream);
2562 /* Get hostname, IP and port */
2563 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2564 (const char **)&ip, &port)) {
2565 /* Bad socket stream */
2566 server->stat.conn_failures++;
2567 silc_stream_destroy(stream);
2571 /* Create packet stream */
2572 packet_stream = silc_packet_stream_create(server->packet_engine,
2573 server->schedule, stream);
2574 if (!packet_stream) {
2575 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2576 server->stat.conn_failures++;
2577 silc_stream_destroy(stream);
2580 server->stat.conn_num++;
2582 /* Set source ID to packet stream */
2583 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2586 server->stat.conn_failures++;
2587 silc_packet_stream_destroy(packet_stream);
2591 /* Check whether this connection is denied to connect to us. */
2592 deny = silc_server_config_find_denied(server, ip);
2594 deny = silc_server_config_find_denied(server, hostname);
2596 /* The connection is denied */
2597 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2598 silc_server_disconnect_remote(server, packet_stream,
2599 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2604 /* Check whether we have configured this sort of connection at all. We
2605 have to check all configurations since we don't know what type of
2606 connection this is. */
2607 if (!(cconfig = silc_server_config_find_client(server, ip)))
2608 cconfig = silc_server_config_find_client(server, hostname);
2609 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2610 sconfig = silc_server_config_find_server_conn(server, hostname);
2611 if (server->server_type == SILC_ROUTER)
2612 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2613 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2614 if (!cconfig && !sconfig && !rconfig) {
2615 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2616 server->stat.conn_failures++;
2617 silc_server_disconnect_remote(server, packet_stream,
2618 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2622 /* The connection is allowed */
2623 entry = silc_calloc(1, sizeof(*entry));
2625 server->stat.conn_failures++;
2626 silc_server_disconnect_remote(server, packet_stream,
2627 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2630 entry->hostname = hostname;
2633 entry->server = server;
2634 entry->data.conn_type = SILC_CONN_UNKNOWN;
2635 silc_packet_set_context(packet_stream, entry);
2637 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2638 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2639 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2641 /* Take flags for key exchange. Since we do not know what type of connection
2642 this is, we go through all found configurations and use the global ones
2643 as well. This will result always into strictest key exchange flags. */
2644 memset(¶ms, 0, sizeof(params));
2645 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2646 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2647 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2648 if (server->config->param.key_exchange_pfs)
2649 params.flags |= SILC_SKE_SP_FLAG_PFS;
2651 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2652 server->stat.conn_attempts++;
2654 /* Start SILC Key Exchange protocol */
2655 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2656 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2657 server->public_key, server->private_key,
2660 server->stat.conn_failures++;
2661 silc_server_disconnect_remote(server, packet_stream,
2662 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2665 silc_ske_set_callbacks(ske, silc_server_verify_key,
2666 silc_server_accept_completed, packet_stream);
2668 /* Start key exchange protocol */
2669 params.version = silc_version_string;
2670 params.timeout_secs = server->config->key_exchange_timeout;
2671 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2675 /********************************** Rekey ***********************************/
2677 /* Initiator rekey completion callback */
2679 static void silc_server_rekey_completion(SilcSKE ske,
2680 SilcSKEStatus status,
2681 const SilcSKESecurityProperties prop,
2682 const SilcSKEKeyMaterial keymat,
2683 SilcSKERekeyMaterial rekey,
2686 SilcPacketStream sock = context;
2687 SilcIDListData idata = silc_packet_get_context(sock);
2688 SilcServer server = idata->sconn->server;
2690 idata->sconn->op = NULL;
2691 if (status != SILC_SKE_STATUS_OK) {
2692 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2693 idata->sconn->remote_host));
2697 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2698 idata->sconn->remote_host, idata->sconn->remote_port,
2699 SILC_CONNTYPE_STRING(idata->conn_type)));
2701 /* Save rekey data for next rekey */
2702 idata->rekey = rekey;
2704 /* Register new rekey timeout */
2705 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2706 sock, idata->sconn->rekey_timeout, 0);
2709 /* Rekey callback. Start rekey as initiator */
2711 SILC_TASK_CALLBACK(silc_server_do_rekey)
2713 SilcServer server = app_context;
2714 SilcPacketStream sock = context;
2715 SilcIDListData idata = silc_packet_get_context(sock);
2718 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2720 /* Do not execute rekey with disabled connections */
2721 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2724 /* If another protocol is active do not start rekey */
2725 if (idata->sconn->op) {
2726 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2727 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2732 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2733 idata->sconn->remote_host, idata->sconn->remote_port,
2734 SILC_CONNTYPE_STRING(idata->conn_type)));
2737 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2738 server->public_key, NULL, sock);
2742 /* Set SKE callbacks */
2743 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2746 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2749 /* Responder rekey completion callback */
2752 silc_server_rekey_resp_completion(SilcSKE ske,
2753 SilcSKEStatus status,
2754 const SilcSKESecurityProperties prop,
2755 const SilcSKEKeyMaterial keymat,
2756 SilcSKERekeyMaterial rekey,
2759 SilcPacketStream sock = context;
2760 SilcIDListData idata = silc_packet_get_context(sock);
2762 idata->sconn->op = NULL;
2763 if (status != SILC_SKE_STATUS_OK) {
2764 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2765 idata->sconn->remote_host));
2769 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2770 idata->sconn->remote_host, idata->sconn->remote_port,
2771 SILC_CONNTYPE_STRING(idata->conn_type)));
2773 /* Save rekey data for next rekey */
2774 idata->rekey = rekey;
2777 /* Start rekey as responder */
2779 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2782 SilcIDListData idata = silc_packet_get_context(sock);
2785 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2786 idata->sconn->remote_host, idata->sconn->remote_port,
2787 SILC_CONNTYPE_STRING(idata->conn_type)));
2790 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2791 server->public_key, NULL, sock);
2793 silc_packet_free(packet);
2797 /* Set SKE callbacks */
2798 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2801 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2806 /****************************** Disconnection *******************************/
2808 /* Destroys packet stream. */
2810 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2812 silc_packet_stream_destroy(context);
2815 /* Closes connection to socket connection */
2817 void silc_server_close_connection(SilcServer server,
2818 SilcPacketStream sock)
2820 SilcIDListData idata = silc_packet_get_context(sock);
2822 const char *hostname;
2825 memset(tmp, 0, sizeof(tmp));
2826 // silc_socket_get_error(sock, tmp, sizeof(tmp));
2827 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2828 NULL, &hostname, NULL, &port);
2829 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2830 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
2831 tmp[0] ? tmp : ""));
2833 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2835 if (idata && idata->sconn) {
2836 silc_server_connection_free(idata->sconn);
2837 idata->sconn = NULL;
2840 /* Close connection with timeout */
2841 server->stat.conn_num--;
2842 silc_schedule_task_del_by_all(server->schedule, 0,
2843 silc_server_close_connection_final, sock);
2844 silc_schedule_task_add_timeout(server->schedule,
2845 silc_server_close_connection_final,
2849 /* Sends disconnect message to remote connection and disconnects the
2852 void silc_server_disconnect_remote(SilcServer server,
2853 SilcPacketStream sock,
2854 SilcStatus status, ...)
2856 unsigned char buf[512];
2863 SILC_LOG_DEBUG(("Disconnecting remote host"));
2865 va_start(ap, status);
2866 cp = va_arg(ap, char *);
2868 silc_vsnprintf(buf, sizeof(buf), cp, ap);
2871 /* Send SILC_PACKET_DISCONNECT */
2872 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2873 SILC_STR_UI_CHAR(status),
2874 SILC_STR_UI8_STRING(cp ? buf : NULL),
2877 /* Close connection */
2878 silc_server_close_connection(server, sock);
2881 /* Frees client data and notifies about client's signoff. */
2883 void silc_server_free_client_data(SilcServer server,
2884 SilcPacketStream sock,
2885 SilcClientEntry client,
2887 const char *signoff)
2889 SILC_LOG_DEBUG(("Freeing client %p data", client));
2892 /* Check if anyone is watching this nickname */
2893 if (server->server_type == SILC_ROUTER)
2894 silc_server_check_watcher_list(server, client, NULL,
2895 SILC_NOTIFY_TYPE_SIGNOFF);
2897 /* Send SIGNOFF notify to routers. */
2899 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2900 SILC_BROADCAST(server), client->id,
2904 /* Remove client from all channels */
2906 silc_server_remove_from_channels(server, NULL, client,
2907 TRUE, (char *)signoff, TRUE, FALSE);
2909 silc_server_remove_from_channels(server, NULL, client,
2910 FALSE, NULL, FALSE, FALSE);
2912 /* Remove this client from watcher list if it is */
2913 silc_server_del_from_watcher_list(server, client);
2915 /* Remove client's public key from repository, this will free it too. */
2916 if (client->data.public_key) {
2917 silc_skr_del_public_key(server->repository, client->data.public_key,
2919 client->data.public_key = NULL;
2922 /* Update statistics */
2923 server->stat.my_clients--;
2924 server->stat.clients--;
2925 if (server->stat.cell_clients)
2926 server->stat.cell_clients--;
2927 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2928 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2929 silc_schedule_task_del_by_context(server->schedule, client);
2931 if (client->data.sconn)
2932 silc_server_connection_free(client->data.sconn);
2934 /* We will not delete the client entry right away. We will take it
2935 into history (for WHOWAS command) for 5 minutes, unless we're
2936 shutting down server. */
2937 if (!server->server_shutdown) {
2938 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2940 client->router = NULL;
2941 client->connection = NULL;
2942 client->data.created = silc_time();
2943 silc_dlist_add(server->expired_clients, client);
2945 /* Delete directly since we're shutting down server */
2946 SILC_LOG_DEBUG(("Delete client directly"));
2947 silc_idlist_del_data(client);
2948 silc_idlist_del_client(server->local_list, client);
2952 /* Frees user_data pointer from socket connection object. This also sends
2953 appropriate notify packets to the network to inform about leaving
2956 void silc_server_free_sock_user_data(SilcServer server,
2957 SilcPacketStream sock,
2958 const char *signoff_message)
2960 SilcIDListData idata = silc_packet_get_context(sock);
2964 SILC_LOG_DEBUG(("Start"));
2969 silc_schedule_task_del_by_context(server->schedule, sock);
2971 /* Cancel active protocols */
2973 if (idata->sconn && idata->sconn->op) {
2974 SILC_LOG_DEBUG(("Abort active protocol"));
2975 silc_async_abort(idata->sconn->op, NULL, NULL);
2977 if (idata->conn_type == SILC_CONN_UNKNOWN &&
2978 ((SilcUnknownEntry)idata)->op) {
2979 SILC_LOG_DEBUG(("Abort active protocol"));
2980 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
2984 switch (idata->conn_type) {
2985 case SILC_CONN_CLIENT:
2987 SilcClientEntry client_entry = (SilcClientEntry)idata;
2988 silc_server_free_client_data(server, sock, client_entry, TRUE,
2990 silc_packet_set_context(sock, NULL);
2994 case SILC_CONN_SERVER:
2995 case SILC_CONN_ROUTER:
2997 SilcServerEntry user_data = (SilcServerEntry)idata;
2998 SilcServerEntry backup_router = NULL;
3000 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3003 backup_router = silc_server_backup_get(server, user_data->id);
3005 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3006 backup_router == server->id_entry &&
3007 idata->conn_type != SILC_CONN_ROUTER)
3008 backup_router = NULL;
3010 if (server->server_shutdown || server->backup_noswitch)
3011 backup_router = NULL;
3013 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3014 NULL, NULL, &ip, &port);
3016 /* If this was our primary router connection then we're lost to
3017 the outside world. */
3018 if (server->router == user_data) {
3019 /* Check whether we have a backup router connection */
3020 if (!backup_router || backup_router == user_data) {
3021 if (!server->no_reconnect)
3022 silc_server_create_connections(server);
3023 server->id_entry->router = NULL;
3024 server->router = NULL;
3025 server->standalone = TRUE;
3026 server->backup_primary = FALSE;
3027 backup_router = NULL;
3029 if (server->id_entry != backup_router) {
3030 SILC_LOG_INFO(("New primary router is backup router %s",
3031 backup_router->server_name));
3032 server->id_entry->router = backup_router;
3033 server->router = backup_router;
3034 server->router_connect = time(0);
3035 server->backup_primary = TRUE;
3036 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3038 /* Send START_USE to backup router to indicate we have switched */
3039 silc_server_backup_send_start_use(server,
3040 backup_router->connection,
3043 SILC_LOG_INFO(("We are now new primary router in this cell"));
3044 server->id_entry->router = NULL;
3045 server->router = NULL;
3046 server->standalone = TRUE;
3049 /* We stop here to take a breath */
3052 if (server->backup_router) {
3053 server->server_type = SILC_ROUTER;
3055 /* We'll need to constantly try to reconnect to the primary
3056 router so that we'll see when it comes back online. */
3057 silc_server_create_connection(server, FALSE, FALSE, ip, port,
3058 silc_server_backup_connected,
3062 /* Mark this connection as replaced */
3063 silc_server_backup_replaced_add(server, user_data->id,
3066 } else if (backup_router) {
3067 SILC_LOG_INFO(("Enabling the use of backup router %s",
3068 backup_router->server_name));
3070 /* Mark this connection as replaced */
3071 silc_server_backup_replaced_add(server, user_data->id,
3073 } else if (server->server_type == SILC_SERVER &&
3074 idata->conn_type == SILC_CONN_ROUTER) {
3075 /* Reconnect to the router (backup) */
3076 if (!server->no_reconnect)
3077 silc_server_create_connections(server);
3080 if (user_data->server_name)
3081 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3082 ("Server %s signoff", user_data->server_name));
3084 if (!backup_router) {
3085 /* Remove all servers that are originated from this server, and
3086 remove the clients of those servers too. */
3087 silc_server_remove_servers_by_server(server, user_data, TRUE);
3090 /* Remove the clients that this server owns as they will become
3091 invalid now too. For backup router the server is actually
3092 coming from the primary router, so mark that as the owner
3094 if (server->server_type == SILC_BACKUP_ROUTER &&
3095 sock->type == SILC_CONN_SERVER)
3096 silc_server_remove_clients_by_server(server, server->router,
3100 silc_server_remove_clients_by_server(server, user_data,
3103 /* Remove channels owned by this server */
3104 if (server->server_type == SILC_SERVER)
3105 silc_server_remove_channels_by_server(server, user_data);
3107 /* Enable local server connections that may be disabled */
3108 silc_server_local_servers_toggle_enabled(server, TRUE);
3110 /* Update the client entries of this server to the new backup
3111 router. If we are the backup router we also resolve the real
3112 servers for the clients. After updating is over this also
3113 removes the clients that this server explicitly owns. */
3114 silc_server_update_clients_by_server(server, user_data,
3115 backup_router, TRUE);
3117 /* If we are router and just lost our primary router (now standlaone)
3118 we remove everything that was behind it, since we don't know
3120 if (server->server_type == SILC_ROUTER && server->standalone)
3121 /* Remove all servers that are originated from this server, and
3122 remove the clients of those servers too. */
3123 silc_server_remove_servers_by_server(server, user_data, TRUE);
3125 /* Finally remove the clients that are explicitly owned by this
3126 server. They go down with the server. */
3127 silc_server_remove_clients_by_server(server, user_data,
3130 /* Update our server cache to use the new backup router too. */
3131 silc_server_update_servers_by_server(server, user_data, backup_router);
3132 if (server->server_type == SILC_SERVER)
3133 silc_server_update_channels_by_server(server, user_data,
3136 /* Send notify about primary router going down to local operators */
3137 if (server->backup_router)
3138 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3139 SILC_NOTIFY_TYPE_NONE,
3140 ("%s switched to backup router %s "
3141 "(we are primary router now)",
3142 server->server_name, server->server_name));
3143 else if (server->router)
3144 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3145 SILC_NOTIFY_TYPE_NONE,
3146 ("%s switched to backup router %s",
3147 server->server_name,
3148 server->router->server_name));
3150 server->backup_noswitch = FALSE;
3153 silc_server_connection_free(idata->sconn);
3156 if (idata->conn_type == SILC_CONN_SERVER) {
3157 server->stat.my_servers--;
3158 server->stat.servers--;
3159 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3160 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3161 server->stat.my_routers--;
3162 server->stat.routers--;
3163 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3165 if (server->server_type == SILC_ROUTER)
3166 server->stat.cell_servers--;
3168 /* Free the server entry */
3169 silc_server_backup_del(server, user_data);
3170 silc_server_backup_replaced_del(server, user_data);
3171 silc_idlist_del_data(user_data);
3172 if (!silc_idlist_del_server(server->local_list, user_data))
3173 silc_idlist_del_server(server->global_list, user_data);
3175 if (backup_router && backup_router != server->id_entry) {
3176 /* Announce all of our stuff that was created about 5 minutes ago.
3177 The backup router knows all the other stuff already. */
3178 if (server->server_type == SILC_ROUTER)
3179 silc_server_announce_servers(server, FALSE, time(0) - 300,
3180 backup_router->connection);
3182 /* Announce our clients and channels to the router */
3183 silc_server_announce_clients(server, time(0) - 300,
3184 backup_router->connection);
3185 silc_server_announce_channels(server, time(0) - 300,
3186 backup_router->connection);
3189 silc_packet_set_context(sock, NULL);
3195 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3197 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3200 silc_server_connection_free(idata->sconn);
3201 silc_idlist_del_data(idata);
3203 silc_packet_set_context(sock, NULL);
3209 /* Removes client from all channels it has joined. This is used when client
3210 connection is disconnected. If the client on a channel is last, the
3211 channel is removed as well. This sends the SIGNOFF notify types. */
3213 void silc_server_remove_from_channels(SilcServer server,
3214 SilcPacketStream sock,
3215 SilcClientEntry client,
3217 const char *signoff_message,
3221 SilcChannelEntry channel;
3222 SilcChannelClientEntry chl;
3223 SilcHashTableList htl;
3224 SilcBuffer clidp = NULL;
3229 if (notify && !client->id)
3232 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3233 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3236 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3241 /* Remove the client from all channels. The client is removed from
3242 the channels' user list. */
3243 silc_hash_table_list(client->channels, &htl);
3244 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3245 channel = chl->channel;
3247 /* Remove channel if this is last client leaving the channel, unless
3248 the channel is permanent. */
3249 if (server->server_type != SILC_SERVER &&
3250 silc_hash_table_count(channel->user_list) < 2) {
3251 silc_server_channel_delete(server, channel);
3255 silc_hash_table_del(client->channels, channel);
3256 silc_hash_table_del(channel->user_list, client);
3257 channel->user_count--;
3259 /* If there is no global users on the channel anymore mark the channel
3260 as local channel. Do not check if the removed client is local client. */
3261 if (server->server_type == SILC_SERVER && channel->global_users &&
3262 chl->client->router && !silc_server_channel_has_global(channel))
3263 channel->global_users = FALSE;
3265 memset(chl, 'A', sizeof(*chl));
3268 /* Update statistics */
3269 if (SILC_IS_LOCAL(client))
3270 server->stat.my_chanclients--;
3271 if (server->server_type == SILC_ROUTER) {
3272 server->stat.cell_chanclients--;
3273 server->stat.chanclients--;
3276 /* If there is not at least one local user on the channel then we don't
3277 need the channel entry anymore, we can remove it safely, unless the
3278 channel is permanent channel */
3279 if (server->server_type == SILC_SERVER &&
3280 !silc_server_channel_has_local(channel)) {
3281 /* Notify about leaving client if this channel has global users. */
3282 if (notify && channel->global_users)
3283 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3284 SILC_NOTIFY_TYPE_SIGNOFF,
3285 signoff_message ? 2 : 1,
3286 clidp->data, silc_buffer_len(clidp),
3287 signoff_message, signoff_message ?
3288 strlen(signoff_message) : 0);
3290 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3291 silc_server_channel_delete(server, channel);
3295 /* Send notify to channel about client leaving SILC and channel too */
3297 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3298 SILC_NOTIFY_TYPE_SIGNOFF,
3299 signoff_message ? 2 : 1,
3300 clidp->data, silc_buffer_len(clidp),
3301 signoff_message, signoff_message ?
3302 strlen(signoff_message) : 0);
3304 if (killed && clidp) {
3305 /* Remove the client from channel's invite list */
3306 if (channel->invite_list &&
3307 silc_hash_table_count(channel->invite_list)) {
3309 SilcArgumentPayload iargs;
3310 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3311 silc_buffer_len(clidp), 3);
3312 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3313 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3314 silc_buffer_free(ab);
3315 silc_argument_payload_free(iargs);
3319 /* Don't create keys if we are shutting down */
3320 if (server->server_shutdown)
3323 /* Re-generate channel key if needed */
3324 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3325 if (!silc_server_create_channel_key(server, channel, 0))
3328 /* Send the channel key to the channel. The key of course is not sent
3329 to the client who was removed from the channel. */
3330 silc_server_send_channel_key(server, client->connection, channel,
3331 server->server_type == SILC_ROUTER ?
3332 FALSE : !server->standalone);
3336 silc_hash_table_list_reset(&htl);
3338 silc_buffer_free(clidp);
3341 /* Removes client from one channel. This is used for example when client
3342 calls LEAVE command to remove itself from the channel. Returns TRUE
3343 if channel still exists and FALSE if the channel is removed when
3344 last client leaves the channel. If `notify' is FALSE notify messages
3347 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3348 SilcPacketStream sock,
3349 SilcChannelEntry channel,
3350 SilcClientEntry client,
3353 SilcChannelClientEntry chl;
3356 SILC_LOG_DEBUG(("Removing %s from channel %s",
3357 silc_id_render(client->id, SILC_ID_CLIENT),
3358 channel->channel_name));
3360 /* Get the entry to the channel, if this client is not on the channel
3362 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3365 /* Remove channel if this is last client leaving the channel, unless
3366 the channel is permanent. */
3367 if (server->server_type != SILC_SERVER &&
3368 silc_hash_table_count(channel->user_list) < 2) {
3369 silc_server_channel_delete(server, channel);
3373 silc_hash_table_del(client->channels, channel);
3374 silc_hash_table_del(channel->user_list, client);
3375 channel->user_count--;
3377 /* If there is no global users on the channel anymore mark the channel
3378 as local channel. Do not check if the client is local client. */
3379 if (server->server_type == SILC_SERVER && channel->global_users &&
3380 chl->client->router && !silc_server_channel_has_global(channel))
3381 channel->global_users = FALSE;
3383 memset(chl, 'O', sizeof(*chl));
3386 /* Update statistics */
3387 if (SILC_IS_LOCAL(client))
3388 server->stat.my_chanclients--;
3389 if (server->server_type == SILC_ROUTER) {
3390 server->stat.cell_chanclients--;
3391 server->stat.chanclients--;
3394 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3398 /* If there is not at least one local user on the channel then we don't
3399 need the channel entry anymore, we can remove it safely, unless the
3400 channel is permanent channel */
3401 if (server->server_type == SILC_SERVER &&
3402 !silc_server_channel_has_local(channel)) {
3403 /* Notify about leaving client if this channel has global users. */
3404 if (notify && channel->global_users)
3405 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3406 SILC_NOTIFY_TYPE_LEAVE, 1,
3407 clidp->data, silc_buffer_len(clidp));
3409 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3410 silc_server_channel_delete(server, channel);
3411 silc_buffer_free(clidp);
3415 /* Send notify to channel about client leaving the channel */
3417 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3418 SILC_NOTIFY_TYPE_LEAVE, 1,
3419 clidp->data, silc_buffer_len(clidp));
3421 silc_buffer_free(clidp);
3425 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3426 function may be used only by router. In real SILC network all channels
3427 are created by routers thus this function is never used by normal
3430 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3431 SilcServerID *router_id,
3437 SilcChannelID *channel_id;
3438 SilcChannelEntry entry;
3439 SilcCipher send_key, receive_key;
3442 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3445 cipher = SILC_DEFAULT_CIPHER;
3447 hmac = SILC_DEFAULT_HMAC;
3449 /* Allocate cipher */
3450 if (!silc_cipher_alloc(cipher, &send_key))
3452 if (!silc_cipher_alloc(cipher, &receive_key)) {
3453 silc_cipher_free(send_key);
3458 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3459 silc_cipher_free(send_key);
3460 silc_cipher_free(receive_key);
3464 channel_name = strdup(channel_name);
3466 /* Create the channel ID */
3467 if (!silc_id_create_channel_id(server, router_id, server->rng,
3469 silc_free(channel_name);
3470 silc_cipher_free(send_key);
3471 silc_cipher_free(receive_key);
3472 silc_hmac_free(newhmac);
3476 /* Create the channel */
3477 entry = silc_idlist_add_channel(server->local_list, channel_name,
3478 SILC_CHANNEL_MODE_NONE, channel_id,
3479 NULL, send_key, receive_key, newhmac);
3481 silc_free(channel_name);
3482 silc_cipher_free(send_key);
3483 silc_cipher_free(receive_key);
3484 silc_hmac_free(newhmac);
3485 silc_free(channel_id);
3489 entry->cipher = strdup(cipher);
3490 entry->hmac_name = strdup(hmac);
3492 /* Now create the actual key material */
3493 if (!silc_server_create_channel_key(server, entry,
3494 silc_cipher_get_key_len(send_key) / 8)) {
3495 silc_idlist_del_channel(server->local_list, entry);
3499 /* Notify other routers about the new channel. We send the packet
3500 to our primary route. */
3502 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3503 channel_name, entry->id,
3504 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3507 /* Distribute to backup routers */
3508 if (broadcast && server->server_type == SILC_ROUTER) {
3510 unsigned char cid[32];
3511 SilcUInt32 name_len = strlen(channel_name);
3514 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3515 packet = silc_channel_payload_encode(channel_name, name_len,
3516 cid, id_len, entry->mode);
3517 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3518 packet->data, silc_buffer_len(packet), FALSE,
3520 silc_buffer_free(packet);
3523 server->stat.my_channels++;
3524 if (server->server_type == SILC_ROUTER) {
3525 server->stat.channels++;
3526 server->stat.cell_channels++;
3527 entry->users_resolved = TRUE;
3533 /* Same as above but creates the channel with Channel ID `channel_id. */
3536 silc_server_create_new_channel_with_id(SilcServer server,
3540 SilcChannelID *channel_id,
3543 SilcChannelEntry entry;
3544 SilcCipher send_key, receive_key;
3547 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3550 cipher = SILC_DEFAULT_CIPHER;
3552 hmac = SILC_DEFAULT_HMAC;
3554 /* Allocate cipher */
3555 if (!silc_cipher_alloc(cipher, &send_key))
3557 if (!silc_cipher_alloc(cipher, &receive_key)) {
3558 silc_cipher_free(send_key);
3563 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3564 silc_cipher_free(send_key);
3565 silc_cipher_free(receive_key);
3569 channel_name = strdup(channel_name);
3571 /* Create the channel */
3572 entry = silc_idlist_add_channel(server->local_list, channel_name,
3573 SILC_CHANNEL_MODE_NONE, channel_id,
3574 NULL, send_key, receive_key, newhmac);
3576 silc_cipher_free(send_key);
3577 silc_cipher_free(receive_key);
3578 silc_hmac_free(newhmac);
3579 silc_free(channel_name);
3583 /* Now create the actual key material */
3584 if (!silc_server_create_channel_key(server, entry,
3585 silc_cipher_get_key_len(send_key) / 8)) {
3586 silc_idlist_del_channel(server->local_list, entry);
3590 /* Notify other routers about the new channel. We send the packet
3591 to our primary route. */
3593 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3594 channel_name, entry->id,
3595 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3598 /* Distribute to backup routers */
3599 if (broadcast && server->server_type == SILC_ROUTER) {
3601 unsigned char cid[32];
3602 SilcUInt32 name_len = strlen(channel_name);
3605 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3606 packet = silc_channel_payload_encode(channel_name, name_len,
3607 cid, id_len, entry->mode);
3608 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3609 packet->data, silc_buffer_len(packet), FALSE,
3611 silc_buffer_free(packet);
3614 server->stat.my_channels++;
3615 if (server->server_type == SILC_ROUTER) {
3616 server->stat.channels++;
3617 server->stat.cell_channels++;
3618 entry->users_resolved = TRUE;
3624 /* Channel's key re-key timeout callback. */
3626 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3628 SilcServer server = app_context;
3629 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3633 /* Return now if we are shutting down */
3634 if (server->server_shutdown)
3637 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3640 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3643 /* Generates new channel key. This is used to create the initial channel key
3644 but also to re-generate new key for channel. If `key_len' is provided
3645 it is the bytes of the key length. */
3647 SilcBool silc_server_create_channel_key(SilcServer server,
3648 SilcChannelEntry channel,
3652 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3655 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3656 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3660 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3662 if (!channel->send_key)
3663 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3664 channel->send_key = NULL;
3667 if (!channel->receive_key)
3668 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3669 silc_cipher_free(channel->send_key);
3670 channel->send_key = channel->receive_key = NULL;
3676 else if (channel->key_len)
3677 len = channel->key_len / 8;
3679 len = silc_cipher_get_key_len(channel->send_key) / 8;
3681 /* Create channel key */
3682 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3685 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3686 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3688 /* Remove old key if exists */
3690 memset(channel->key, 0, channel->key_len / 8);
3691 silc_free(channel->key);
3695 channel->key_len = len * 8;
3696 channel->key = silc_memdup(channel_key, len);
3697 memset(channel_key, 0, sizeof(channel_key));
3699 /* Generate HMAC key from the channel key data and set it */
3701 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3702 memset(channel->key, 0, channel->key_len / 8);
3703 silc_free(channel->key);
3704 silc_cipher_free(channel->send_key);
3705 silc_cipher_free(channel->receive_key);
3706 channel->send_key = channel->receive_key = NULL;
3709 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3710 silc_hmac_set_key(channel->hmac, hash,
3711 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3712 memset(hash, 0, sizeof(hash));
3714 if (server->server_type == SILC_ROUTER) {
3715 if (!channel->rekey)
3716 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3717 channel->rekey->channel = channel;
3718 channel->rekey->key_len = key_len;
3719 if (channel->rekey->task)
3720 silc_schedule_task_del(server->schedule, channel->rekey->task);
3722 channel->rekey->task =
3723 silc_schedule_task_add_timeout(server->schedule,
3724 silc_server_channel_key_rekey,
3725 (void *)channel->rekey,
3726 server->config->channel_rekey_secs, 0);
3732 /* Saves the channel key found in the encoded `key_payload' buffer. This
3733 function is used when we receive Channel Key Payload and also when we're
3734 processing JOIN command reply. Returns entry to the channel. */
3736 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3737 SilcBuffer key_payload,
3738 SilcChannelEntry channel)
3740 SilcChannelKeyPayload payload = NULL;
3742 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3746 /* Decode channel key payload */
3747 payload = silc_channel_key_payload_parse(key_payload->data,
3748 silc_buffer_len(key_payload));
3750 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3755 /* Get the channel entry */
3758 /* Get channel ID */
3759 tmp = silc_channel_key_get_id(payload, &tmp_len);
3760 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3765 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3767 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3769 if (server->server_type == SILC_ROUTER)
3770 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3771 silc_id_render(&id, SILC_ID_CHANNEL)));
3777 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3779 tmp = silc_channel_key_get_key(payload, &tmp_len);
3785 cipher = silc_channel_key_get_cipher(payload, NULL);
3791 /* Remove old key if exists */
3793 memset(channel->key, 0, channel->key_len / 8);
3794 silc_free(channel->key);
3795 silc_cipher_free(channel->send_key);
3796 silc_cipher_free(channel->receive_key);
3799 /* Create new cipher */
3800 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3801 channel->send_key = NULL;
3805 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3806 silc_cipher_free(channel->send_key);
3807 channel->send_key = channel->receive_key = NULL;
3812 if (channel->cipher)
3813 silc_free(channel->cipher);
3814 channel->cipher = strdup(cipher);
3817 channel->key_len = tmp_len * 8;
3818 channel->key = silc_memdup(tmp, tmp_len);
3819 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3820 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3822 /* Generate HMAC key from the channel key data and set it */
3824 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3825 memset(channel->key, 0, channel->key_len / 8);
3826 silc_free(channel->key);
3827 silc_cipher_free(channel->send_key);
3828 silc_cipher_free(channel->receive_key);
3829 channel->send_key = channel->receive_key = NULL;
3832 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3833 silc_hmac_set_key(channel->hmac, hash,
3834 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3836 memset(hash, 0, sizeof(hash));
3837 memset(tmp, 0, tmp_len);
3839 if (server->server_type == SILC_ROUTER) {
3840 if (!channel->rekey)
3841 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3842 channel->rekey->channel = channel;
3843 if (channel->rekey->task)
3844 silc_schedule_task_del(server->schedule, channel->rekey->task);
3846 channel->rekey->task =
3847 silc_schedule_task_add_timeout(server->schedule,
3848 silc_server_channel_key_rekey,
3849 (void *)channel->rekey,
3850 server->config->channel_rekey_secs, 0);
3855 silc_channel_key_payload_free(payload);
3860 /* Returns assembled of all servers in the given ID list. The packet's
3861 form is dictated by the New ID payload. */
3863 static void silc_server_announce_get_servers(SilcServer server,
3864 SilcServerEntry remote,
3866 SilcBuffer *servers,
3867 unsigned long creation_time)
3870 SilcIDCacheEntry id_cache;
3871 SilcServerEntry entry;
3874 /* Go through all clients in the list */
3875 if (silc_idcache_get_all(id_list->servers, &list)) {
3876 silc_list_start(list);
3877 while ((id_cache = silc_list_get(list))) {
3878 entry = (SilcServerEntry)id_cache->context;
3880 /* Do not announce the one we've sending our announcements and
3881 do not announce ourself. Also check the creation time if it's
3883 if ((entry == remote) || (entry == server->id_entry) ||
3884 (creation_time && entry->data.created < creation_time))
3887 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3889 *servers = silc_buffer_realloc(*servers,
3891 silc_buffer_truelen((*servers)) +
3892 silc_buffer_len(idp) :
3893 silc_buffer_len(idp)));
3894 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3895 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3896 silc_buffer_pull(*servers, silc_buffer_len(idp));
3897 silc_buffer_free(idp);
3903 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3909 p = silc_notify_payload_encode(notify, argc, ap);
3915 /* This function is used by router to announce existing servers to our
3916 primary router when we've connected to it. If `creation_time' is non-zero
3917 then only the servers that has been created after the `creation_time'
3918 will be announced. */
3920 void silc_server_announce_servers(SilcServer server, SilcBool global,
3921 unsigned long creation_time,
3922 SilcPacketStream remote)
3924 SilcBuffer servers = NULL;
3926 SILC_LOG_DEBUG(("Announcing servers"));
3928 /* Get servers in local list */
3929 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3930 server->local_list, &servers,
3934 /* Get servers in global list */
3935 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3936 server->global_list, &servers,
3940 silc_buffer_push(servers, servers->data - servers->head);
3941 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
3943 /* Send the packet */
3944 silc_server_packet_send(server, remote,
3945 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3946 servers->data, silc_buffer_len(servers));
3948 silc_buffer_free(servers);
3952 /* Returns assembled packet of all clients in the given ID list. The
3953 packet's form is dictated by the New ID Payload. */
3955 static void silc_server_announce_get_clients(SilcServer server,
3957 SilcBuffer *clients,
3959 unsigned long creation_time)
3962 SilcIDCacheEntry id_cache;
3963 SilcClientEntry client;
3966 unsigned char mode[4];
3968 /* Go through all clients in the list */
3969 if (silc_idcache_get_all(id_list->clients, &list)) {
3970 silc_list_start(list);
3971 while ((id_cache = silc_list_get(list))) {
3972 client = (SilcClientEntry)id_cache->context;
3974 if (creation_time && client->data.created < creation_time)
3976 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
3978 if (!client->connection && !client->router)
3981 SILC_LOG_DEBUG(("Announce Client ID %s",
3982 silc_id_render(client->id, SILC_ID_CLIENT)));
3984 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3986 *clients = silc_buffer_realloc(*clients,
3988 silc_buffer_truelen((*clients)) +
3989 silc_buffer_len(idp) :
3990 silc_buffer_len(idp)));
3991 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3992 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
3993 silc_buffer_pull(*clients, silc_buffer_len(idp));
3995 SILC_PUT32_MSB(client->mode, mode);
3997 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3998 2, idp->data, silc_buffer_len(idp),
4000 *umodes = silc_buffer_realloc(*umodes,
4002 silc_buffer_truelen((*umodes)) +
4003 silc_buffer_len(tmp) :
4004 silc_buffer_len(tmp)));
4005 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4006 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4007 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4008 silc_buffer_free(tmp);
4010 silc_buffer_free(idp);
4015 /* This function is used to announce our existing clients to our router
4016 when we've connected to it. If `creation_time' is non-zero then only
4017 the clients that has been created after the `creation_time' will be
4020 void silc_server_announce_clients(SilcServer server,
4021 unsigned long creation_time,
4022 SilcPacketStream remote)
4024 SilcBuffer clients = NULL;
4025 SilcBuffer umodes = NULL;
4027 SILC_LOG_DEBUG(("Announcing clients"));
4029 /* Get clients in local list */
4030 silc_server_announce_get_clients(server, server->local_list,
4031 &clients, &umodes, creation_time);
4033 /* As router we announce our global list as well */
4034 if (server->server_type == SILC_ROUTER)
4035 silc_server_announce_get_clients(server, server->global_list,
4036 &clients, &umodes, creation_time);
4039 silc_buffer_push(clients, clients->data - clients->head);
4040 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4042 /* Send the packet */
4043 silc_server_packet_send(server, remote,
4044 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4045 clients->data, silc_buffer_len(clients));
4047 silc_buffer_free(clients);
4051 silc_buffer_push(umodes, umodes->data - umodes->head);
4052 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4054 /* Send the packet */
4055 silc_server_packet_send(server, remote,
4056 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4057 umodes->data, silc_buffer_len(umodes));
4059 silc_buffer_free(umodes);
4063 /* Returns channel's topic for announcing it */
4065 void silc_server_announce_get_channel_topic(SilcServer server,
4066 SilcChannelEntry channel,
4071 if (channel->topic) {
4072 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4073 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4075 silc_buffer_len(chidp),
4077 strlen(channel->topic));
4078 silc_buffer_free(chidp);
4082 /* Returns channel's invite and ban lists */
4084 void silc_server_announce_get_inviteban(SilcServer server,
4085 SilcChannelEntry channel,
4089 SilcBuffer list, idp, idp2, tmp2;
4091 SilcHashTableList htl;
4092 const unsigned char a[1] = { 0x03 };
4094 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4096 /* Encode invite list */
4097 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4098 list = silc_buffer_alloc_size(2);
4099 type = silc_hash_table_count(channel->invite_list);
4100 SILC_PUT16_MSB(type, list->data);
4101 silc_hash_table_list(channel->invite_list, &htl);
4102 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4103 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4105 silc_hash_table_list_reset(&htl);
4107 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4109 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4110 idp->data, silc_buffer_len(idp),
4111 channel->channel_name,
4112 strlen(channel->channel_name),
4113 idp2->data, silc_buffer_len(idp2),
4115 list->data, silc_buffer_len(list));
4116 silc_buffer_free(idp2);
4117 silc_buffer_free(list);
4120 /* Encode ban list */
4121 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4122 list = silc_buffer_alloc_size(2);
4123 type = silc_hash_table_count(channel->ban_list);
4124 SILC_PUT16_MSB(type, list->data);
4125 silc_hash_table_list(channel->ban_list, &htl);
4126 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4127 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4129 silc_hash_table_list_reset(&htl);
4132 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4133 idp->data, silc_buffer_len(idp),
4135 list->data, silc_buffer_len(list));
4136 silc_buffer_free(list);
4139 silc_buffer_free(idp);
4142 /* Returns assembled packets for channel users of the `channel'. */
4144 void silc_server_announce_get_channel_users(SilcServer server,
4145 SilcChannelEntry channel,
4146 SilcBuffer *channel_modes,
4147 SilcBuffer *channel_users,
4148 SilcBuffer *channel_users_modes)
4150 SilcChannelClientEntry chl;
4151 SilcHashTableList htl;
4152 SilcBuffer chidp, clidp, csidp;
4153 SilcBuffer tmp, fkey = NULL, chpklist;
4155 unsigned char mode[4], ulimit[4];
4158 SILC_LOG_DEBUG(("Start"));
4160 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4161 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4162 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4165 SILC_PUT32_MSB(channel->mode, mode);
4166 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4167 SILC_PUT32_MSB(channel->user_limit, ulimit);
4168 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4169 if (channel->founder_key)
4170 fkey = silc_public_key_payload_encode(channel->founder_key);
4172 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4174 silc_buffer_len(csidp),
4177 hmac, hmac ? strlen(hmac) : 0,
4178 channel->passphrase,
4179 channel->passphrase ?
4180 strlen(channel->passphrase) : 0,
4181 fkey ? fkey->data : NULL,
4182 fkey ? silc_buffer_len(fkey) : 0,
4183 chpklist ? chpklist->data : NULL,
4185 silc_buffer_len(chpklist) : 0,
4187 SILC_CHANNEL_MODE_ULIMIT ?
4190 SILC_CHANNEL_MODE_ULIMIT ?
4191 sizeof(ulimit) : 0));
4192 len = silc_buffer_len(tmp);
4194 silc_buffer_realloc(*channel_modes,
4196 silc_buffer_truelen((*channel_modes)) + len : len));
4197 silc_buffer_pull_tail(*channel_modes,
4198 ((*channel_modes)->end -
4199 (*channel_modes)->data));
4200 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4201 silc_buffer_pull(*channel_modes, len);
4202 silc_buffer_free(tmp);
4203 silc_buffer_free(fkey);
4206 /* Now find all users on the channel */
4207 silc_hash_table_list(channel->user_list, &htl);
4208 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4209 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4211 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4215 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4217 silc_buffer_len(clidp),
4219 silc_buffer_len(chidp));
4220 len = silc_buffer_len(tmp);
4222 silc_buffer_realloc(*channel_users,
4224 silc_buffer_truelen((*channel_users)) + len : len));
4225 silc_buffer_pull_tail(*channel_users,
4226 ((*channel_users)->end -
4227 (*channel_users)->data));
4229 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4230 silc_buffer_pull(*channel_users, len);
4231 silc_buffer_free(tmp);
4233 /* CUMODE notify for mode change on the channel */
4234 SILC_PUT32_MSB(chl->mode, mode);
4235 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4236 fkey = silc_public_key_payload_encode(channel->founder_key);
4237 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4239 silc_buffer_len(csidp),
4242 silc_buffer_len(clidp),
4243 fkey ? fkey->data : NULL,
4244 fkey ? silc_buffer_len(fkey) : 0);
4245 len = silc_buffer_len(tmp);
4246 *channel_users_modes =
4247 silc_buffer_realloc(*channel_users_modes,
4248 (*channel_users_modes ?
4249 silc_buffer_truelen((*channel_users_modes)) +
4251 silc_buffer_pull_tail(*channel_users_modes,
4252 ((*channel_users_modes)->end -
4253 (*channel_users_modes)->data));
4255 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4256 silc_buffer_pull(*channel_users_modes, len);
4257 silc_buffer_free(tmp);
4258 silc_buffer_free(fkey);
4260 silc_buffer_free(clidp);
4262 silc_hash_table_list_reset(&htl);
4263 silc_buffer_free(chidp);
4264 silc_buffer_free(csidp);
4267 /* Returns assembled packets for all channels and users on those channels
4268 from the given ID List. The packets are in the form dictated by the
4269 New Channel and New Channel User payloads. */
4271 void silc_server_announce_get_channels(SilcServer server,
4273 SilcBuffer *channels,
4274 SilcBuffer **channel_modes,
4275 SilcBuffer *channel_users,
4276 SilcBuffer **channel_users_modes,
4277 SilcUInt32 *channel_users_modes_c,
4278 SilcBuffer **channel_topics,
4279 SilcBuffer **channel_invites,
4280 SilcBuffer **channel_bans,
4281 SilcChannelID ***channel_ids,
4282 unsigned long creation_time)
4285 SilcIDCacheEntry id_cache;
4286 SilcChannelEntry channel;
4287 unsigned char cid[32];
4289 SilcUInt16 name_len;
4291 int i = *channel_users_modes_c;
4294 SILC_LOG_DEBUG(("Start"));
4296 /* Go through all channels in the list */
4297 if (silc_idcache_get_all(id_list->channels, &list)) {
4298 silc_list_start(list);
4299 while ((id_cache = silc_list_get(list))) {
4300 channel = (SilcChannelEntry)id_cache->context;
4302 if (creation_time && channel->created < creation_time)
4307 SILC_LOG_DEBUG(("Announce Channel ID %s",
4308 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4310 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4311 name_len = strlen(channel->channel_name);
4314 len = 4 + name_len + id_len + 4;
4316 silc_buffer_realloc(*channels,
4318 silc_buffer_truelen((*channels)) +
4320 silc_buffer_pull_tail(*channels,
4321 ((*channels)->end - (*channels)->data));
4322 silc_buffer_format(*channels,
4323 SILC_STR_UI_SHORT(name_len),
4324 SILC_STR_UI_XNSTRING(channel->channel_name,
4326 SILC_STR_UI_SHORT(id_len),
4327 SILC_STR_UI_XNSTRING(cid, id_len),
4328 SILC_STR_UI_INT(channel->mode),
4330 silc_buffer_pull(*channels, len);
4333 if (creation_time && channel->updated < creation_time)
4339 /* Channel user modes */
4340 *channel_users_modes = silc_realloc(*channel_users_modes,
4341 sizeof(**channel_users_modes) *
4343 (*channel_users_modes)[i] = NULL;
4344 *channel_modes = silc_realloc(*channel_modes,
4345 sizeof(**channel_modes) * (i + 1));
4346 (*channel_modes)[i] = NULL;
4347 *channel_ids = silc_realloc(*channel_ids,
4348 sizeof(**channel_ids) * (i + 1));
4349 (*channel_ids)[i] = NULL;
4350 silc_server_announce_get_channel_users(server, channel,
4351 &(*channel_modes)[i],
4353 &(*channel_users_modes)[i]);
4354 (*channel_ids)[i] = channel->id;
4356 /* Channel's topic */
4357 *channel_topics = silc_realloc(*channel_topics,
4358 sizeof(**channel_topics) * (i + 1));
4359 (*channel_topics)[i] = NULL;
4360 silc_server_announce_get_channel_topic(server, channel,
4361 &(*channel_topics)[i]);
4363 /* Channel's invite and ban list */
4364 *channel_invites = silc_realloc(*channel_invites,
4365 sizeof(**channel_invites) * (i + 1));
4366 (*channel_invites)[i] = NULL;
4367 *channel_bans = silc_realloc(*channel_bans,
4368 sizeof(**channel_bans) * (i + 1));
4369 (*channel_bans)[i] = NULL;
4370 silc_server_announce_get_inviteban(server, channel,
4371 &(*channel_invites)[i],
4372 &(*channel_bans)[i]);
4374 (*channel_users_modes_c)++;
4382 /* This function is used to announce our existing channels to our router
4383 when we've connected to it. This also announces the users on the
4384 channels to the router. If the `creation_time' is non-zero only the
4385 channels that was created after the `creation_time' are announced.
4386 Note that the channel users are still announced even if the `creation_time'
4389 void silc_server_announce_channels(SilcServer server,
4390 unsigned long creation_time,
4391 SilcPacketStream remote)
4393 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4394 SilcBuffer *channel_users_modes = NULL;
4395 SilcBuffer *channel_topics = NULL;
4396 SilcBuffer *channel_invites = NULL;
4397 SilcBuffer *channel_bans = NULL;
4398 SilcUInt32 channel_users_modes_c = 0;
4399 SilcChannelID **channel_ids = NULL;
4401 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4403 /* Get channels and channel users in local list */
4404 silc_server_announce_get_channels(server, server->local_list,
4405 &channels, &channel_modes,
4407 &channel_users_modes,
4408 &channel_users_modes_c,
4412 &channel_ids, creation_time);
4414 /* Get channels and channel users in global list */
4415 if (server->server_type != SILC_SERVER)
4416 silc_server_announce_get_channels(server, server->global_list,
4417 &channels, &channel_modes,
4419 &channel_users_modes,
4420 &channel_users_modes_c,
4424 &channel_ids, creation_time);
4427 silc_buffer_push(channels, channels->data - channels->head);
4428 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4430 /* Send the packet */
4431 silc_server_packet_send(server, remote,
4432 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4433 channels->data, silc_buffer_len(channels));
4435 silc_buffer_free(channels);
4438 if (channel_users) {
4439 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4440 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4441 silc_buffer_len(channel_users));
4443 /* Send the packet */
4444 silc_server_packet_send(server, remote,
4445 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4446 channel_users->data, silc_buffer_len(channel_users));
4448 silc_buffer_free(channel_users);
4451 if (channel_modes) {
4454 for (i = 0; i < channel_users_modes_c; i++) {
4455 if (!channel_modes[i])
4457 silc_buffer_push(channel_modes[i],
4458 channel_modes[i]->data -
4459 channel_modes[i]->head);
4460 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4461 silc_buffer_len(channel_modes[i]));
4462 silc_server_packet_send_dest(server, remote,
4463 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4464 channel_ids[i], SILC_ID_CHANNEL,
4465 channel_modes[i]->data,
4466 silc_buffer_len(channel_modes[i]));
4467 silc_buffer_free(channel_modes[i]);
4469 silc_free(channel_modes);
4472 if (channel_users_modes) {
4475 for (i = 0; i < channel_users_modes_c; i++) {
4476 if (!channel_users_modes[i])
4478 silc_buffer_push(channel_users_modes[i],
4479 channel_users_modes[i]->data -
4480 channel_users_modes[i]->head);
4481 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4482 silc_buffer_len(channel_users_modes[i]));
4483 silc_server_packet_send_dest(server, remote,
4484 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4485 channel_ids[i], SILC_ID_CHANNEL,
4486 channel_users_modes[i]->data,
4487 silc_buffer_len(channel_users_modes[i]));
4488 silc_buffer_free(channel_users_modes[i]);
4490 silc_free(channel_users_modes);
4493 if (channel_topics) {
4496 for (i = 0; i < channel_users_modes_c; i++) {
4497 if (!channel_topics[i])
4500 silc_buffer_push(channel_topics[i],
4501 channel_topics[i]->data -
4502 channel_topics[i]->head);
4503 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4504 silc_buffer_len(channel_topics[i]));
4505 silc_server_packet_send_dest(server, remote,
4506 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4507 channel_ids[i], SILC_ID_CHANNEL,
4508 channel_topics[i]->data,
4509 silc_buffer_len(channel_topics[i]));
4510 silc_buffer_free(channel_topics[i]);
4512 silc_free(channel_topics);
4515 if (channel_invites) {
4518 for (i = 0; i < channel_users_modes_c; i++) {
4519 if (!channel_invites[i])
4522 silc_buffer_push(channel_invites[i],
4523 channel_invites[i]->data -
4524 channel_invites[i]->head);
4525 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4526 silc_buffer_len(channel_invites[i]));
4527 silc_server_packet_send_dest(server, remote,
4528 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4529 channel_ids[i], SILC_ID_CHANNEL,
4530 channel_invites[i]->data,
4531 silc_buffer_len(channel_invites[i]));
4532 silc_buffer_free(channel_invites[i]);
4534 silc_free(channel_invites);
4540 for (i = 0; i < channel_users_modes_c; i++) {
4541 if (!channel_bans[i])
4544 silc_buffer_push(channel_bans[i],
4545 channel_bans[i]->data -
4546 channel_bans[i]->head);
4547 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4548 silc_buffer_len(channel_bans[i]));
4549 silc_server_packet_send_dest(server, remote,
4550 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4551 channel_ids[i], SILC_ID_CHANNEL,
4552 channel_bans[i]->data,
4553 silc_buffer_len(channel_bans[i]));
4554 silc_buffer_free(channel_bans[i]);
4556 silc_free(channel_bans);
4559 silc_free(channel_ids);
4562 /* Announces WATCH list. */
4564 void silc_server_announce_watches(SilcServer server,
4565 SilcPacketStream remote)
4567 SilcHashTableList htl;
4568 SilcBuffer buffer, idp, args, pkp;
4569 SilcClientEntry client;
4572 SILC_LOG_DEBUG(("Announcing watch list"));
4574 /* XXX because way we save the nicks (hash) we cannot announce them. */
4576 /* XXX we should send all public keys in one command if client is
4577 watching more than one key */
4578 silc_hash_table_list(server->watcher_list_pk, &htl);
4579 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4580 if (!client || !client->id)
4583 server->stat.commands_sent++;
4585 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4586 args = silc_buffer_alloc_size(2);
4587 silc_buffer_format(args,
4588 SILC_STR_UI_SHORT(1),
4590 pkp = silc_public_key_payload_encode(key);
4591 args = silc_argument_payload_encode_one(args, pkp->data,
4592 silc_buffer_len(pkp), 0x00);
4593 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4594 ++server->cmd_ident, 2,
4595 1, idp->data, silc_buffer_len(idp),
4597 silc_buffer_len(args));
4600 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4601 buffer->data, silc_buffer_len(buffer));
4603 silc_buffer_free(pkp);
4604 silc_buffer_free(args);
4605 silc_buffer_free(idp);
4606 silc_buffer_free(buffer);
4608 silc_hash_table_list_reset(&htl);
4611 /* Assembles user list and users mode list from the `channel'. */
4613 SilcBool silc_server_get_users_on_channel(SilcServer server,
4614 SilcChannelEntry channel,
4615 SilcBuffer *user_list,
4616 SilcBuffer *mode_list,
4617 SilcUInt32 *user_count)
4619 SilcChannelClientEntry chl;
4620 SilcHashTableList htl;
4621 SilcBuffer client_id_list;
4622 SilcBuffer client_mode_list;
4624 SilcUInt32 list_count = 0, len = 0;
4626 if (!silc_hash_table_count(channel->user_list))
4629 silc_hash_table_list(channel->user_list, &htl);
4630 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4631 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4632 silc_hash_table_list_reset(&htl);
4634 client_id_list = silc_buffer_alloc(len);
4636 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4637 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4638 silc_buffer_pull_tail(client_mode_list,
4639 silc_buffer_truelen(client_mode_list));
4641 silc_hash_table_list(channel->user_list, &htl);
4642 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4644 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4645 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4646 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4647 silc_buffer_free(idp);
4649 /* Client's mode on channel */
4650 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4651 silc_buffer_pull(client_mode_list, 4);
4655 silc_hash_table_list_reset(&htl);
4656 silc_buffer_push(client_id_list,
4657 client_id_list->data - client_id_list->head);
4658 silc_buffer_push(client_mode_list,
4659 client_mode_list->data - client_mode_list->head);
4661 *user_list = client_id_list;
4662 *mode_list = client_mode_list;
4663 *user_count = list_count;
4667 /* Saves users and their modes to the `channel'. */
4669 void silc_server_save_users_on_channel(SilcServer server,
4670 SilcPacketStream sock,
4671 SilcChannelEntry channel,
4672 SilcClientID *noadd,
4673 SilcBuffer user_list,
4674 SilcBuffer mode_list,
4675 SilcUInt32 user_count)
4681 SilcClientEntry client;
4682 SilcIDCacheEntry cache;
4683 SilcChannelClientEntry chl;
4685 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4686 channel->channel_name));
4688 for (i = 0; i < user_count; i++) {
4690 SILC_GET16_MSB(idp_len, user_list->data + 2);
4692 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4694 silc_buffer_pull(user_list, idp_len);
4697 SILC_GET32_MSB(mode, mode_list->data);
4698 silc_buffer_pull(mode_list, 4);
4700 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4705 /* Check if we have this client cached already. */
4706 client = silc_idlist_find_client_by_id(server->local_list,
4708 server->server_type, &cache);
4710 client = silc_idlist_find_client_by_id(server->global_list,
4712 server->server_type, &cache);
4714 /* If router did not find such Client ID in its lists then this must
4715 be bogus client or some router in the net is buggy. */
4716 if (server->server_type != SILC_SERVER)
4719 /* We don't have that client anywhere, add it. The client is added
4720 to global list since server didn't have it in the lists so it must be
4722 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4723 silc_id_dup(&id.u.client_id,
4725 silc_packet_get_context(sock),
4728 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4732 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4735 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4736 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4737 "%s", channel->channel_name));
4741 if (!silc_server_client_on_channel(client, channel, &chl)) {
4742 /* Client was not on the channel, add it. */
4743 chl = silc_calloc(1, sizeof(*chl));
4744 chl->client = client;
4746 chl->channel = channel;
4747 silc_hash_table_add(channel->user_list, chl->client, chl);
4748 silc_hash_table_add(client->channels, chl->channel, chl);
4749 channel->user_count++;
4757 /* Saves channels and channels user modes to the `client'. Removes
4758 the client from those channels that are not sent in the list but
4761 void silc_server_save_user_channels(SilcServer server,
4762 SilcPacketStream sock,
4763 SilcClientEntry client,
4764 SilcBuffer channels,
4765 SilcBuffer channels_user_modes)
4768 SilcUInt32 *chumodes;
4769 SilcChannelPayload entry;
4770 SilcChannelEntry channel;
4771 SilcChannelID channel_id;
4772 SilcChannelClientEntry chl;
4773 SilcHashTable ht = NULL;
4774 SilcHashTableList htl;
4778 if (!channels || !channels_user_modes ||
4779 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4782 ch = silc_channel_payload_parse_list(channels->data,
4783 silc_buffer_len(channels));
4784 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4786 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4787 NULL, NULL, NULL, TRUE);
4788 silc_dlist_start(ch);
4789 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4790 /* Check if we have this channel, and add it if we don't have it.
4791 Also add the client on the channel unless it is there already. */
4792 if (!silc_channel_get_id_parse(entry, &channel_id))
4794 channel = silc_idlist_find_channel_by_id(server->local_list,
4797 channel = silc_idlist_find_channel_by_id(server->global_list,
4800 if (server->server_type != SILC_SERVER) {
4805 /* We don't have that channel anywhere, add it. */
4806 name = silc_channel_get_name(entry, NULL);
4807 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4808 silc_id_dup(&channel_id,
4810 server->router, NULL, NULL, 0);
4817 channel->mode = silc_channel_get_mode(entry);
4819 /* Add the client on the channel */
4820 if (!silc_server_client_on_channel(client, channel, &chl)) {
4821 chl = silc_calloc(1, sizeof(*chl));
4822 chl->client = client;
4823 chl->mode = chumodes[i++];
4824 chl->channel = channel;
4825 silc_hash_table_add(channel->user_list, chl->client, chl);
4826 silc_hash_table_add(client->channels, chl->channel, chl);
4827 channel->user_count++;
4830 chl->mode = chumodes[i++];
4833 silc_hash_table_add(ht, channel, channel);
4835 silc_channel_payload_list_free(ch);
4836 silc_free(chumodes);
4840 /* Go through the list again and remove client from channels that
4841 are no part of the list. */
4843 silc_hash_table_list(client->channels, &htl);
4844 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4845 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4846 silc_hash_table_del(chl->channel->user_list, chl->client);
4847 silc_hash_table_del(chl->client->channels, chl->channel);
4851 silc_hash_table_list_reset(&htl);
4852 silc_hash_table_free(ht);
4854 silc_hash_table_list(client->channels, &htl);
4855 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4856 silc_hash_table_del(chl->channel->user_list, chl->client);
4857 silc_hash_table_del(chl->client->channels, chl->channel);
4860 silc_hash_table_list_reset(&htl);
4864 /* Lookups route to the client indicated by the `id_data'. The connection
4865 object and internal data object is returned. Returns NULL if route
4866 could not be found to the client. If the `client_id' is specified then
4867 it is used and the `id_data' is ignored. */
4870 silc_server_get_client_route(SilcServer server,
4871 unsigned char *id_data,
4873 SilcClientID *client_id,
4874 SilcIDListData *idata,
4875 SilcClientEntry *client_entry)
4877 SilcClientID *id, clid;
4878 SilcClientEntry client;
4880 SILC_LOG_DEBUG(("Start"));
4883 *client_entry = NULL;
4885 /* Decode destination Client ID */
4887 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
4889 id = silc_id_dup(&clid, SILC_ID_CLIENT);
4891 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4894 /* If the destination belongs to our server we don't have to route
4895 the packet anywhere but to send it to the local destination. */
4896 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4900 /* If we are router and the client has router then the client is in
4901 our cell but not directly connected to us. */
4902 if (server->server_type == SILC_ROUTER && client->router) {
4903 /* We are of course in this case the client's router thus the route
4904 to the client is the server who owns the client. So, we will send
4905 the packet to that server. */
4907 *idata = (SilcIDListData)client->router;
4908 return client->router->connection;
4911 /* Seems that client really is directly connected to us */
4913 *idata = (SilcIDListData)client;
4915 *client_entry = client;
4916 return client->connection;
4919 /* Destination belongs to someone not in this server. If we are normal
4920 server our action is to send the packet to our router. */
4921 if (server->server_type != SILC_ROUTER && !server->standalone) {
4924 *idata = (SilcIDListData)server->router;
4925 return SILC_PRIMARY_ROUTE(server);
4928 /* We are router and we will perform route lookup for the destination
4929 and send the packet to fastest route. */
4930 if (server->server_type == SILC_ROUTER && !server->standalone) {
4931 /* Check first that the ID is valid */
4932 client = silc_idlist_find_client_by_id(server->global_list, id,
4935 SilcPacketStream dst_sock;
4937 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4940 if (idata && dst_sock)
4941 *idata = silc_packet_get_context(dst_sock);
4950 /* Encodes and returns channel list of channels the `client' has joined.
4951 Secret channels are not put to the list. */
4953 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4954 SilcClientEntry client,
4955 SilcBool get_private,
4956 SilcBool get_secret,
4957 SilcBuffer *user_mode_list)
4959 SilcBuffer buffer = NULL;
4960 SilcChannelEntry channel;
4961 SilcChannelClientEntry chl;
4962 SilcHashTableList htl;
4963 unsigned char cid[32];
4965 SilcUInt16 name_len;
4969 *user_mode_list = NULL;
4971 silc_hash_table_list(client->channels, &htl);
4972 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4973 channel = chl->channel;
4975 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4977 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4980 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4981 name_len = strlen(channel->channel_name);
4983 len = 4 + name_len + id_len + 4;
4984 buffer = silc_buffer_realloc(buffer,
4986 silc_buffer_truelen(buffer) + len : len));
4987 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4988 silc_buffer_format(buffer,
4989 SILC_STR_UI_SHORT(name_len),
4990 SILC_STR_DATA(channel->channel_name, name_len),
4991 SILC_STR_UI_SHORT(id_len),
4992 SILC_STR_DATA(cid, id_len),
4993 SILC_STR_UI_INT(chl->channel->mode),
4995 silc_buffer_pull(buffer, len);
4997 if (user_mode_list) {
4999 silc_buffer_realloc(*user_mode_list,
5001 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5002 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5003 (*user_mode_list)->data));
5004 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5005 silc_buffer_pull(*user_mode_list, 4);
5008 silc_hash_table_list_reset(&htl);
5011 silc_buffer_push(buffer, buffer->data - buffer->head);
5012 if (user_mode_list && *user_mode_list)
5013 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5014 (*user_mode_list)->head));
5019 /* Task callback used to retrieve network statistical information from
5020 router server once in a while. */
5022 SILC_TASK_CALLBACK(silc_server_get_stats)
5024 SilcServer server = (SilcServer)context;
5025 SilcBuffer idp, packet;
5027 if (!server->standalone) {
5028 SILC_LOG_DEBUG(("Retrieving stats from router"));
5029 server->stat.commands_sent++;
5030 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5032 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5033 ++server->cmd_ident, 1,
5035 silc_buffer_len(idp));
5036 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5037 SILC_PACKET_COMMAND, 0, packet->data,
5038 silc_buffer_len(packet));
5039 silc_buffer_free(packet);
5040 silc_buffer_free(idp);
5044 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,