5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * This is the actual SILC server than handles everything relating to
22 * servicing the SILC connections. This is also a SILC router as a router
23 * is also normal server.
27 #include "serverincludes.h"
28 #include "server_internal.h"
30 /* Static prototypes */
31 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
32 SILC_TASK_CALLBACK(silc_server_connect_router);
33 SILC_TASK_CALLBACK(silc_server_connect_to_router);
34 SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
35 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
36 SILC_TASK_CALLBACK(silc_server_accept_new_connection);
37 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second);
38 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final);
39 SILC_TASK_CALLBACK(silc_server_packet_process);
40 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
41 SILC_TASK_CALLBACK(silc_server_close_connection_final);
42 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout);
43 SILC_TASK_CALLBACK(silc_server_timeout_remote);
44 SILC_TASK_CALLBACK(silc_server_channel_key_rekey);
45 SILC_TASK_CALLBACK(silc_server_failure_callback);
46 SILC_TASK_CALLBACK(silc_server_rekey_callback);
47 SILC_TASK_CALLBACK(silc_server_get_stats);
49 /* Allocates a new SILC server object. This has to be done before the server
50 can be used. After allocation one must call silc_server_init to initialize
51 the server. The new allocated server object is returned to the new_server
54 int silc_server_alloc(SilcServer *new_server)
58 SILC_LOG_DEBUG(("Allocating new server object"));
60 server = silc_calloc(1, sizeof(*server));
61 server->server_type = SILC_SERVER;
62 server->standalone = TRUE;
63 server->local_list = silc_calloc(1, sizeof(*server->local_list));
64 server->global_list = silc_calloc(1, sizeof(*server->global_list));
65 server->pending_commands = silc_dlist_init();
67 server->sim = silc_dlist_init();
75 /* Free's the SILC server object. This is called at the very end before
78 void silc_server_free(SilcServer server)
87 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
88 silc_dlist_del(server->sim, sim);
91 silc_dlist_uninit(server->sim);
95 silc_server_config_unref(&server->config_ref);
97 silc_rng_free(server->rng);
99 silc_pkcs_free(server->pkcs);
100 if (server->public_key)
101 silc_pkcs_public_key_free(server->public_key);
102 if (server->private_key)
103 silc_pkcs_private_key_free(server->private_key);
104 if (server->pending_commands)
105 silc_dlist_uninit(server->pending_commands);
106 if (server->id_entry)
107 silc_idlist_del_server(server->local_list, server->id_entry);
109 silc_idcache_free(server->local_list->clients);
110 silc_idcache_free(server->local_list->servers);
111 silc_idcache_free(server->local_list->channels);
112 silc_idcache_free(server->global_list->clients);
113 silc_idcache_free(server->global_list->servers);
114 silc_idcache_free(server->global_list->channels);
115 silc_hash_table_free(server->watcher_list);
117 silc_hash_free(server->md5hash);
118 silc_hash_free(server->sha1hash);
119 silc_hmac_unregister_all();
120 silc_hash_unregister_all();
121 silc_cipher_unregister_all();
122 silc_pkcs_unregister_all();
124 silc_free(server->local_list);
125 silc_free(server->global_list);
126 silc_free(server->server_name);
127 silc_free(server->id_string);
128 silc_free(server->purge_i);
129 silc_free(server->purge_g);
133 /* Creates a new server listener. */
135 static bool silc_server_listen(SilcServer server, const char *server_ip,
136 SilcUInt16 port, int *sock)
138 *sock = silc_net_create_server(port, server_ip);
140 SILC_LOG_ERROR(("Could not create server listener: %s on %hu",
147 /* Adds a secondary listener. */
149 bool silc_server_init_secondary(SilcServer server)
151 int sock = 0, sock_list[server->config->param.connections_max];
152 SilcSocketConnection newsocket = NULL;
153 SilcServerConfigServerInfoInterface *interface;
155 for (interface = server->config->server_info->secondary; interface;
156 interface = interface->next, sock++) {
158 if (!silc_server_listen(server,
159 interface->server_ip, interface->port, &sock_list[sock]))
162 /* Set socket to non-blocking mode */
163 silc_net_set_socket_nonblock(sock_list[sock]);
165 /* Add ourselves also to the socket table. The entry allocated above
166 is sent as argument for fast referencing in the future. */
167 silc_socket_alloc(sock_list[sock],
168 SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
169 server->sockets[sock_list[sock]] = newsocket;
171 /* Perform name and address lookups to resolve the listenning address
173 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
175 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
177 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
178 newsocket->hostname ? newsocket->hostname :
179 newsocket->ip ? newsocket->ip : ""));
180 server->stat.conn_failures++;
183 if (!newsocket->hostname)
184 newsocket->hostname = strdup(newsocket->ip);
186 newsocket->port = silc_net_get_local_port(sock);
188 newsocket->user_data = (void *)server->id_entry;
189 silc_schedule_task_add(server->schedule, sock_list[sock],
190 silc_server_accept_new_connection,
191 (void *)server, 0, 0,
193 SILC_TASK_PRI_NORMAL);
199 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
203 /* Initializes the entire SILC server. This is called always before running
204 the server. This is called only once at the initialization of the program.
205 This binds the server to its listenning port. After this function returns
206 one should call silc_server_run to start the server. This returns TRUE
207 when everything is ok to run the server. Configuration file must be
208 read and parsed before calling this. */
210 bool silc_server_init(SilcServer server)
214 SilcServerEntry id_entry;
215 SilcIDListPurge purge;
216 SilcSocketConnection newsocket = NULL;
218 SILC_LOG_DEBUG(("Initializing server"));
220 server->starttime = time(NULL);
222 /* Take config object for us */
223 silc_server_config_ref(&server->config_ref, server->config,
226 /* Steal public and private key from the config object */
227 server->public_key = server->config->server_info->public_key;
228 server->private_key = server->config->server_info->private_key;
229 server->config->server_info->public_key = NULL;
230 server->config->server_info->private_key = NULL;
232 /* Register all configured ciphers, PKCS and hash functions. */
233 if (!silc_server_config_register_ciphers(server))
234 silc_cipher_register_default();
235 if (!silc_server_config_register_pkcs(server))
236 silc_pkcs_register_default();
237 if (!silc_server_config_register_hashfuncs(server))
238 silc_hash_register_default();
239 if (!silc_server_config_register_hmacs(server))
240 silc_hmac_register_default();
242 /* Initialize random number generator for the server. */
243 server->rng = silc_rng_alloc();
244 silc_rng_init(server->rng);
245 silc_rng_global_init(server->rng);
247 /* Initialize hash functions for server to use */
248 silc_hash_alloc("md5", &server->md5hash);
249 silc_hash_alloc("sha1", &server->sha1hash);
251 /* Allocate PKCS context for local public and private keys */
252 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
254 silc_pkcs_public_key_set(server->pkcs, server->public_key);
255 silc_pkcs_private_key_set(server->pkcs, server->private_key);
257 /* Initialize the scheduler */
258 server->schedule = silc_schedule_init(server->config->param.connections_max);
259 if (!server->schedule)
262 /* First, register log files configuration for error output */
263 silc_server_config_setlogfiles(server);
265 /* Initialize ID caches */
266 server->local_list->clients =
267 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
268 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
269 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
271 /* These are allocated for normal server as well as these hold some
272 global information that the server has fetched from its router. For
273 router these are used as they are supposed to be used on router. */
274 server->global_list->clients =
275 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
276 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
277 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
279 /* Init watcher list */
280 server->watcher_list =
281 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
282 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
284 if (!server->watcher_list)
287 /* Create a listening server */
288 if (!silc_server_listen(server,
289 server->config->server_info->primary == NULL ? NULL :
290 server->config->server_info->primary->server_ip,
291 server->config->server_info->primary == NULL ? 0 :
292 server->config->server_info->primary->port,
296 /* Set socket to non-blocking mode */
297 silc_net_set_socket_nonblock(sock);
300 /* Allocate the entire socket list that is used in server. Eventually
301 all connections will have entry in this table (it is a table of
302 pointers to the actual object that is allocated individually
304 server->sockets = silc_calloc(server->config->param.connections_max,
305 sizeof(*server->sockets));
306 if (!server->sockets)
309 /* Add ourselves also to the socket table. The entry allocated above
310 is sent as argument for fast referencing in the future. */
311 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
312 server->sockets[sock] = newsocket;
314 /* Perform name and address lookups to resolve the listenning address
316 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
318 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
320 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
321 newsocket->hostname ? newsocket->hostname :
322 newsocket->ip ? newsocket->ip : ""));
323 server->stat.conn_failures++;
326 if (!newsocket->hostname)
327 newsocket->hostname = strdup(newsocket->ip);
329 newsocket->port = silc_net_get_local_port(sock);
331 /* Create a Server ID for the server. */
332 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
337 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
338 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
339 server->id_type = SILC_ID_SERVER;
340 server->server_name = server->config->server_info->server_name;
341 server->config->server_info->server_name = NULL;
343 /* Add ourselves to the server list. We don't have a router yet
344 beacuse we haven't established a route yet. It will be done later.
345 For now, NULL is sent as router. This allocates new entry to
348 silc_idlist_add_server(server->local_list, strdup(server->server_name),
349 server->server_type, server->id, NULL, NULL);
351 SILC_LOG_ERROR(("Could not add ourselves to cache"));
354 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
356 /* Put the allocated socket pointer also to the entry allocated above
357 for fast back-referencing to the socket list. */
358 newsocket->user_data = (void *)id_entry;
359 id_entry->connection = (void *)newsocket;
360 server->id_entry = id_entry;
362 /* Register protocols */
363 silc_server_protocols_register();
365 /* Add the first task to the scheduler. This is task that is executed by
366 timeout. It expires as soon as the caller calls silc_server_run. This
367 task performs authentication protocol and key exchange with our
369 silc_schedule_task_add(server->schedule, 0,
370 silc_server_connect_to_router,
371 (void *)server, 0, 1,
373 SILC_TASK_PRI_NORMAL);
375 /* Add listener task to the scheduler. This task receives new connections
376 to the server. This task remains on the queue until the end of the
378 silc_schedule_task_add(server->schedule, sock,
379 silc_server_accept_new_connection,
380 (void *)server, 0, 0,
382 SILC_TASK_PRI_NORMAL);
384 if (silc_server_init_secondary(server) == FALSE)
387 server->listenning = TRUE;
389 /* If server connections has been configured then we must be router as
390 normal server cannot have server connections, only router connections. */
391 if (server->config->servers) {
392 SilcServerConfigServer *ptr = server->config->servers;
394 server->server_type = SILC_ROUTER;
396 if (ptr->backup_router) {
397 server->server_type = SILC_BACKUP_ROUTER;
398 server->backup_router = TRUE;
399 server->id_entry->server_type = SILC_BACKUP_ROUTER;
406 /* Register the ID Cache purge task. This periodically purges the ID cache
407 and removes the expired cache entries. */
409 /* Clients local list */
410 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
411 purge->cache = server->local_list->clients;
412 purge->schedule = server->schedule;
413 purge->timeout = 600;
414 silc_schedule_task_add(purge->schedule, 0,
416 (void *)purge, purge->timeout, 0,
417 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
419 /* Clients global list */
420 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
421 purge->cache = server->global_list->clients;
422 purge->schedule = server->schedule;
423 purge->timeout = 300;
424 silc_schedule_task_add(purge->schedule, 0,
426 (void *)purge, purge->timeout, 0,
427 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
429 /* If we are normal server we'll retrieve network statisticial information
430 once in a while from the router. */
431 if (server->server_type == SILC_SERVER)
432 silc_schedule_task_add(purge->schedule, 0, silc_server_get_stats,
433 server, 10, 0, SILC_TASK_TIMEOUT,
436 if (server->server_type == SILC_ROUTER)
437 server->stat.routers++;
439 SILC_LOG_DEBUG(("Server initialized"));
441 /* We are done here, return succesfully */
445 silc_server_config_unref(&server->config_ref);
446 silc_net_close_server(sock);
450 /* This function basically reads the config file again and switches the config
451 object pointed by the server object. After that, we have to fix various
452 things such as the server_name and the listening ports.
453 Keep in mind that we no longer have the root privileges at this point. */
455 bool silc_server_rehash(SilcServer server)
457 SilcServerConfig newconfig;
459 SILC_LOG_INFO(("Rehashing server"));
461 /* Reset the logging system */
462 silc_log_quick = TRUE;
463 silc_log_flush_all();
465 /* Start the main rehash phase (read again the config file) */
466 newconfig = silc_server_config_alloc(server->config_file);
468 SILC_LOG_ERROR(("Rehash FAILED."));
472 /* Reinit scheduler if necessary */
473 if (newconfig->param.connections_max > server->config->param.connections_max)
474 if (!silc_schedule_reinit(server->schedule,
475 newconfig->param.connections_max))
478 /* Fix the server_name field */
479 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
480 silc_free(server->server_name);
481 server->server_name = newconfig->server_info->server_name;
482 newconfig->server_info->server_name = NULL;
484 /* Update the idcache list with a fresh pointer */
485 silc_free(server->id_entry->server_name);
486 server->id_entry->server_name = strdup(server->server_name);
487 if (!silc_idcache_del_by_context(server->local_list->servers,
490 if (!silc_idcache_add(server->local_list->servers,
491 server->id_entry->server_name,
492 server->id_entry->id, server->id_entry, 0, NULL))
497 silc_server_config_setlogfiles(server);
499 /* Change new key pair if necessary */
500 if (newconfig->server_info->public_key &&
501 !silc_pkcs_public_key_compare(server->public_key,
502 newconfig->server_info->public_key)) {
503 silc_pkcs_public_key_free(server->public_key);
504 silc_pkcs_private_key_free(server->private_key);
505 server->public_key = newconfig->server_info->public_key;
506 server->private_key = newconfig->server_info->private_key;
507 newconfig->server_info->public_key = NULL;
508 newconfig->server_info->private_key = NULL;
510 /* Allocate PKCS context for local public and private keys */
511 silc_pkcs_free(server->pkcs);
512 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
514 silc_pkcs_public_key_set(server->pkcs, server->public_key);
515 silc_pkcs_private_key_set(server->pkcs, server->private_key);
518 /* Go through all configured routers after rehash */
519 silc_schedule_task_add(server->schedule, 0,
520 silc_server_connect_to_router,
521 (void *)server, 0, 1,
523 SILC_TASK_PRI_NORMAL);
525 /* Check whether our router status has changed */
526 if (newconfig->servers) {
527 SilcServerConfigServer *ptr = newconfig->servers;
529 server->server_type = SILC_ROUTER;
531 if (ptr->backup_router) {
532 server->server_type = SILC_BACKUP_ROUTER;
533 server->backup_router = TRUE;
534 server->id_entry->server_type = SILC_BACKUP_ROUTER;
541 /* Our old config is gone now. We'll unreference our reference made in
542 silc_server_init and then destroy it since we are destroying it
543 underneath the application (layer which called silc_server_init). */
544 silc_server_config_unref(&server->config_ref);
545 silc_server_config_destroy(server->config);
547 /* Take new config context */
548 server->config = newconfig;
549 silc_server_config_ref(&server->config_ref, server->config, server->config);
551 SILC_LOG_DEBUG(("Server rehashed"));
556 /* The heart of the server. This runs the scheduler thus runs the server.
557 When this returns the server has been stopped and the program will
560 void silc_server_run(SilcServer server)
562 SILC_LOG_INFO(("SILC Server started"));
564 /* Start the scheduler, the heart of the SILC server. When this returns
565 the program will be terminated. */
566 silc_schedule(server->schedule);
569 /* Stops the SILC server. This function is used to shutdown the server.
570 This is usually called after the scheduler has returned. After stopping
571 the server one should call silc_server_free. */
573 void silc_server_stop(SilcServer server)
575 SILC_LOG_DEBUG(("Stopping server"));
577 if (server->schedule) {
580 for (i = 0; i < server->config->param.connections_max; i++) {
581 if (!server->sockets[i])
583 silc_socket_free(server->sockets[i]);
585 silc_free(server->sockets);
586 server->sockets = NULL;
588 silc_schedule_stop(server->schedule);
589 silc_schedule_uninit(server->schedule);
590 server->schedule = NULL;
593 silc_server_protocols_unregister();
595 SILC_LOG_DEBUG(("Server stopped"));
598 /* Function that is called when the network connection to a router has
599 been established. This will continue with the key exchange protocol
600 with the remote router. */
602 void silc_server_start_key_exchange(SilcServer server,
603 SilcServerConnection sconn,
606 SilcSocketConnection newsocket;
607 SilcProtocol protocol;
608 SilcServerKEInternalContext *proto_ctx;
609 SilcServerConfigRouter *conn =
610 (SilcServerConfigRouter *) sconn->conn.ref_ptr;
613 /* Cancel any possible retry timeouts */
614 silc_schedule_task_del_by_callback(server->schedule,
615 silc_server_connect_to_router_retry);
617 /* Set socket options */
618 silc_net_set_socket_nonblock(sock);
619 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
621 /* Create socket connection for the connection. Even though we
622 know that we are connecting to a router we will mark the socket
623 to be unknown connection until we have executed authentication
625 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
626 server->sockets[sock] = newsocket;
627 newsocket->hostname = strdup(sconn->remote_host);
628 newsocket->ip = strdup(sconn->remote_host);
629 newsocket->port = sconn->remote_port;
630 sconn->sock = newsocket;
632 /* Allocate internal protocol context. This is sent as context
634 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
635 proto_ctx->server = (void *)server;
636 proto_ctx->context = (void *)sconn;
637 proto_ctx->sock = newsocket;
638 proto_ctx->rng = server->rng;
639 proto_ctx->responder = FALSE;
641 /* Set Key Exchange flags from configuration, but fall back to global
643 SILC_GET_SKE_FLAGS(conn, proto_ctx);
644 if (server->config->param.key_exchange_pfs)
645 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
647 /* Perform key exchange protocol. silc_server_connect_to_router_second
648 will be called after the protocol is finished. */
649 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
650 &protocol, proto_ctx,
651 silc_server_connect_to_router_second);
652 newsocket->protocol = protocol;
654 /* Register a timeout task that will be executed if the protocol
655 is not executed within set limit. */
656 proto_ctx->timeout_task =
657 silc_schedule_task_add(server->schedule, sock,
658 silc_server_timeout_remote,
659 server, server->config->key_exchange_timeout, 0,
663 /* Register the connection for network input and output. This sets
664 that scheduler will listen for incoming packets for this connection
665 and sets that outgoing packets may be sent to this connection as
666 well. However, this doesn't set the scheduler for outgoing traffic,
667 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
668 later when outgoing data is available. */
669 context = (void *)server;
670 SILC_REGISTER_CONNECTION_FOR_IO(sock);
672 /* Run the protocol */
673 silc_protocol_execute(protocol, server->schedule, 0, 0);
676 /* Timeout callback that will be called to retry connecting to remote
677 router. This is used by both normal and router server. This will wait
678 before retrying the connecting. The timeout is generated by exponential
679 backoff algorithm. */
681 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
683 SilcServerConnection sconn = (SilcServerConnection)context;
684 SilcServer server = sconn->server;
685 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
686 SilcServerConfigConnParams *param =
687 (conn->param ? conn->param : &server->config->param);
689 SILC_LOG_INFO(("Retrying connecting to a router"));
691 /* Calculate next timeout */
692 if (sconn->retry_count >= 1) {
693 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
694 if (sconn->retry_timeout > param->reconnect_interval_max)
695 sconn->retry_timeout = param->reconnect_interval_max;
697 sconn->retry_timeout = param->reconnect_interval;
699 sconn->retry_count++;
700 sconn->retry_timeout = sconn->retry_timeout +
701 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
703 /* If we've reached max retry count, give up. */
704 if ((sconn->retry_count > param->reconnect_count) &&
705 !param->reconnect_keep_trying) {
706 SILC_LOG_ERROR(("Could not connect to router, giving up"));
707 silc_server_config_unref(&sconn->conn);
708 silc_free(sconn->remote_host);
709 silc_free(sconn->backup_replace_ip);
714 /* We will lookup a fresh pointer later */
715 silc_server_config_unref(&sconn->conn);
717 /* Wait one before retrying */
718 silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
719 context, sconn->retry_timeout, 0,
720 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
723 /* Generic routine to use connect to a router. */
725 SILC_TASK_CALLBACK(silc_server_connect_router)
727 SilcServerConnection sconn = (SilcServerConnection)context;
728 SilcServer server = sconn->server;
729 SilcServerConfigRouter *rconn;
732 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
733 (sconn->backup ? "backup router" : "router"),
734 sconn->remote_host, sconn->remote_port));
736 server->router_connect = time(NULL);
737 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
740 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
741 (sconn->backup ? "backup router" : "router"),
742 sconn->remote_host, sconn->remote_port));
743 silc_free(sconn->remote_host);
744 silc_free(sconn->backup_replace_ip);
748 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
750 /* Connect to remote host */
751 sock = silc_net_create_connection(
752 (!server->config->server_info->primary ? NULL :
753 server->config->server_info->primary->server_ip),
754 sconn->remote_port, sconn->remote_host);
756 SILC_LOG_ERROR(("Could not connect to router %s:%d",
757 sconn->remote_host, sconn->remote_port));
758 if (!sconn->no_reconnect)
759 silc_schedule_task_add(server->schedule, 0,
760 silc_server_connect_to_router_retry,
761 context, 0, 1, SILC_TASK_TIMEOUT,
762 SILC_TASK_PRI_NORMAL);
764 silc_server_config_unref(&sconn->conn);
768 /* Continue with key exchange protocol */
769 silc_server_start_key_exchange(server, sconn, sock);
772 /* This function connects to our primary router or if we are a router this
773 establishes all our primary routes. This is called at the start of the
774 server to do authentication and key exchange with our router - called
777 SILC_TASK_CALLBACK(silc_server_connect_to_router)
779 SilcServer server = (SilcServer)context;
780 SilcServerConnection sconn;
781 SilcServerConfigRouter *ptr;
783 SILC_LOG_DEBUG(("Connecting to router(s)"));
785 if (server->server_type == SILC_SERVER) {
786 SILC_LOG_DEBUG(("We are normal server"));
787 } else if (server->server_type == SILC_ROUTER) {
788 SILC_LOG_DEBUG(("We are router"));
790 SILC_LOG_DEBUG(("We are backup router/normal server"));
793 if (!server->config->routers) {
794 /* There wasn't a configured router, we will continue but we don't
795 have a connection to outside world. We will be standalone server. */
796 SILC_LOG_DEBUG(("No router(s), server will be standalone"));
797 server->standalone = TRUE;
801 /* Cancel any possible retry timeouts */
802 silc_schedule_task_del_by_callback(server->schedule,
803 silc_server_connect_router);
804 silc_schedule_task_del_by_callback(server->schedule,
805 silc_server_connect_to_router_retry);
807 /* Create the connections to all our routes */
808 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
810 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
811 ptr->backup_router ? "Backup router" : "Router",
812 ptr->initiator ? "Initiator" : "Responder",
813 ptr->host, ptr->port));
815 if (ptr->initiator) {
816 /* Check whether we are connected to this host already */
817 if (silc_server_num_sockets_by_remote(server,
818 silc_net_is_ip(ptr->host) ?
820 silc_net_is_ip(ptr->host) ?
821 NULL : ptr->host, ptr->port,
822 SILC_SOCKET_TYPE_ROUTER)) {
823 SILC_LOG_DEBUG(("We are already connected to this router"));
827 /* Allocate connection object for hold connection specific stuff. */
828 sconn = silc_calloc(1, sizeof(*sconn));
829 sconn->server = server;
830 sconn->remote_host = strdup(ptr->host);
831 sconn->remote_port = ptr->port;
832 sconn->backup = ptr->backup_router;
834 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
835 sconn->backup_replace_port = ptr->backup_replace_port;
838 if (!server->router_conn && !sconn->backup)
839 server->router_conn = sconn;
841 silc_schedule_task_add(server->schedule, 0,
842 silc_server_connect_router,
843 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
844 SILC_TASK_PRI_NORMAL);
849 /* Second part of connecting to router(s). Key exchange protocol has been
850 executed and now we will execute authentication protocol. */
852 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
854 SilcProtocol protocol = (SilcProtocol)context;
855 SilcServerKEInternalContext *ctx =
856 (SilcServerKEInternalContext *)protocol->context;
857 SilcServer server = (SilcServer)ctx->server;
858 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
859 SilcSocketConnection sock = ctx->sock;
860 SilcServerConnAuthInternalContext *proto_ctx;
861 SilcServerConfigRouter *conn = NULL;
863 SILC_LOG_DEBUG(("Start"));
865 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
866 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
867 /* Error occured during protocol */
868 silc_protocol_free(protocol);
869 sock->protocol = NULL;
870 silc_ske_free_key_material(ctx->keymat);
872 silc_packet_context_free(ctx->packet);
874 silc_ske_free(ctx->ske);
875 silc_free(ctx->dest_id);
877 silc_server_config_unref(&sconn->conn);
878 silc_free(sconn->remote_host);
879 silc_free(sconn->backup_replace_ip);
881 silc_schedule_task_del_by_callback(server->schedule,
882 silc_server_failure_callback);
883 silc_server_disconnect_remote(server, sock,
884 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
888 /* We now have the key material as the result of the key exchange
889 protocol. Take the key material into use. Free the raw key material
890 as soon as we've set them into use. */
891 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
892 ctx->sock, ctx->keymat,
893 ctx->ske->prop->cipher,
894 ctx->ske->prop->pkcs,
895 ctx->ske->prop->hash,
896 ctx->ske->prop->hmac,
897 ctx->ske->prop->group,
899 silc_protocol_free(protocol);
900 sock->protocol = NULL;
901 silc_ske_free_key_material(ctx->keymat);
903 silc_packet_context_free(ctx->packet);
905 silc_ske_free(ctx->ske);
906 silc_free(ctx->dest_id);
908 silc_server_config_unref(&sconn->conn);
909 silc_free(sconn->remote_host);
910 silc_free(sconn->backup_replace_ip);
912 silc_schedule_task_del_by_callback(server->schedule,
913 silc_server_failure_callback);
914 silc_server_disconnect_remote(server, sock,
915 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
918 silc_ske_free_key_material(ctx->keymat);
920 /* Allocate internal context for the authentication protocol. This
921 is sent as context for the protocol. */
922 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
923 proto_ctx->server = (void *)server;
924 proto_ctx->context = (void *)sconn;
925 proto_ctx->sock = sock;
926 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
927 proto_ctx->dest_id_type = ctx->dest_id_type;
928 proto_ctx->dest_id = ctx->dest_id;
930 /* Resolve the authentication method used in this connection. Check if
931 we find a match from user configured connections */
932 if (!sconn->conn.ref_ptr)
933 conn = silc_server_config_find_router_conn(server, sock->hostname,
936 conn = sconn->conn.ref_ptr;
939 /* Match found. Use the configured authentication method. Take only
940 the passphrase, since for public key auth we automatically use
941 our local key pair. */
942 if (conn->passphrase) {
943 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
944 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
946 proto_ctx->auth_data = strdup(conn->passphrase);
947 proto_ctx->auth_data_len = strlen(conn->passphrase);
948 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
950 } else if (conn->publickeys) {
951 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
953 proto_ctx->auth_meth = SILC_AUTH_NONE;
956 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
957 sock->hostname, sock->ip, sock->port));
958 silc_protocol_free(protocol);
959 sock->protocol = NULL;
961 silc_packet_context_free(ctx->packet);
963 silc_ske_free(ctx->ske);
964 silc_free(ctx->dest_id);
966 silc_server_config_unref(&sconn->conn);
967 silc_free(sconn->remote_host);
968 silc_free(sconn->backup_replace_ip);
970 silc_schedule_task_del_by_callback(server->schedule,
971 silc_server_failure_callback);
972 silc_server_disconnect_remote(server, sock,
973 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
977 /* Free old protocol as it is finished now */
978 silc_protocol_free(protocol);
980 silc_packet_context_free(ctx->packet);
982 sock->protocol = NULL;
984 /* Allocate the authentication protocol. This is allocated here
985 but we won't start it yet. We will be receiving party of this
986 protocol thus we will wait that connecting party will make
988 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
989 &sock->protocol, proto_ctx,
990 silc_server_connect_to_router_final);
992 /* Register timeout task. If the protocol is not executed inside
993 this timelimit the connection will be terminated. */
994 proto_ctx->timeout_task =
995 silc_schedule_task_add(server->schedule, sock->sock,
996 silc_server_timeout_remote,
998 server->config->conn_auth_timeout, 0,
1002 /* Run the protocol */
1003 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1006 /* Finalizes the connection to router. Registers a server task to the
1007 queue so that we can accept new connections. */
1009 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
1011 SilcProtocol protocol = (SilcProtocol)context;
1012 SilcServerConnAuthInternalContext *ctx =
1013 (SilcServerConnAuthInternalContext *)protocol->context;
1014 SilcServer server = (SilcServer)ctx->server;
1015 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1016 SilcSocketConnection sock = ctx->sock;
1017 SilcServerEntry id_entry;
1019 SilcServerHBContext hb_context;
1020 unsigned char *id_string;
1022 SilcIDListData idata;
1023 SilcServerConfigRouter *conn = NULL;
1024 SilcServerConfigConnParams *param = NULL;
1026 SILC_LOG_DEBUG(("Start"));
1028 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1029 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1030 /* Error occured during protocol */
1031 silc_free(ctx->dest_id);
1032 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1037 /* Add a task to the queue. This task receives new connections to the
1038 server. This task remains on the queue until the end of the program. */
1039 if (!server->listenning && !sconn->backup) {
1040 silc_schedule_task_add(server->schedule, server->sock,
1041 silc_server_accept_new_connection,
1042 (void *)server, 0, 0,
1044 SILC_TASK_PRI_NORMAL);
1045 server->listenning = TRUE;
1048 /* Send NEW_SERVER packet to the router. We will become registered
1049 to the SILC network after sending this packet. */
1050 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
1051 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
1052 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
1053 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1054 silc_buffer_format(packet,
1055 SILC_STR_UI_SHORT(id_len),
1056 SILC_STR_UI_XNSTRING(id_string, id_len),
1057 SILC_STR_UI_SHORT(strlen(server->server_name)),
1058 SILC_STR_UI_XNSTRING(server->server_name,
1059 strlen(server->server_name)),
1062 /* Send the packet */
1063 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
1064 packet->data, packet->len, TRUE);
1065 silc_buffer_free(packet);
1066 silc_free(id_string);
1068 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
1070 /* Check that we do not have this ID already */
1071 id_entry = silc_idlist_find_server_by_id(server->local_list,
1072 ctx->dest_id, TRUE, NULL);
1074 silc_idcache_del_by_context(server->local_list->servers, id_entry);
1076 id_entry = silc_idlist_find_server_by_id(server->global_list,
1077 ctx->dest_id, TRUE, NULL);
1079 silc_idcache_del_by_context(server->global_list->servers, id_entry);
1082 SILC_LOG_DEBUG(("New server id(%s)",
1083 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
1085 /* Add the connected router to global server list */
1086 id_entry = silc_idlist_add_server(server->global_list,
1087 strdup(sock->hostname),
1088 SILC_ROUTER, ctx->dest_id, NULL, sock);
1090 silc_free(ctx->dest_id);
1091 SILC_LOG_ERROR(("Cannot add new server entry to cache"));
1092 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1097 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1098 silc_free(sock->user_data);
1099 sock->user_data = (void *)id_entry;
1100 sock->type = SILC_SOCKET_TYPE_ROUTER;
1101 idata = (SilcIDListData)sock->user_data;
1102 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1104 conn = sconn->conn.ref_ptr;
1105 param = &server->config->param;
1106 if (conn && conn->param)
1107 param = conn->param;
1109 /* Perform keepalive. The `hb_context' will be freed automatically
1110 when finally calling the silc_socket_free function. */
1111 hb_context = silc_calloc(1, sizeof(*hb_context));
1112 hb_context->server = server;
1113 silc_socket_set_heartbeat(sock, param->keepalive_secs, hb_context,
1114 silc_server_perform_heartbeat,
1117 /* Register re-key timeout */
1118 idata->rekey->timeout = param->key_exchange_rekey;
1119 idata->rekey->context = (void *)server;
1120 silc_schedule_task_add(server->schedule, sock->sock,
1121 silc_server_rekey_callback,
1122 (void *)sock, idata->rekey->timeout, 0,
1123 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1125 if (!sconn->backup) {
1126 /* Mark this router our primary router if we're still standalone */
1127 if (server->standalone) {
1128 server->id_entry->router = id_entry;
1129 server->router = id_entry;
1130 server->standalone = FALSE;
1132 /* If we are router then announce our possible servers. */
1133 if (server->server_type == SILC_ROUTER)
1134 silc_server_announce_servers(server, FALSE, 0,
1135 server->router->connection);
1137 /* Announce our clients and channels to the router */
1138 silc_server_announce_clients(server, 0, server->router->connection);
1139 silc_server_announce_channels(server, 0, server->router->connection);
1141 #ifdef BACKUP_SINGLE_ROUTER
1142 /* If we are backup router then this primary router is whom we are
1144 if (server->server_type == SILC_BACKUP_ROUTER)
1145 silc_server_backup_add(server, server->id_entry, sock->ip, 0, TRUE);
1146 #endif /* BACKUP_SINGLE_ROUTER */
1149 /* Add this server to be our backup router */
1150 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1151 sconn->backup_replace_port, FALSE);
1154 sock->protocol = NULL;
1156 /* Call the completion callback to indicate that we've connected to
1158 if (sconn->callback)
1159 (*sconn->callback)(server, id_entry, sconn->callback_context);
1162 /* Free the temporary connection data context */
1164 silc_server_config_unref(&sconn->conn);
1165 silc_free(sconn->remote_host);
1166 silc_free(sconn->backup_replace_ip);
1169 if (sconn == server->router_conn)
1170 server->router_conn = NULL;
1172 /* Free the protocol object */
1173 if (sock->protocol == protocol)
1174 sock->protocol = NULL;
1175 silc_protocol_free(protocol);
1177 silc_packet_context_free(ctx->packet);
1179 silc_ske_free(ctx->ske);
1180 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1181 silc_free(ctx->auth_data);
1185 /* Host lookup callback that is called after the incoming connection's
1186 IP and FQDN lookup is performed. This will actually check the acceptance
1187 of the incoming connection and will register the key exchange protocol
1188 for this connection. */
1191 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1194 SilcServerKEInternalContext *proto_ctx =
1195 (SilcServerKEInternalContext *)context;
1196 SilcServer server = (SilcServer)proto_ctx->server;
1197 SilcServerConfigClient *cconfig = NULL;
1198 SilcServerConfigServer *sconfig = NULL;
1199 SilcServerConfigRouter *rconfig = NULL;
1200 SilcServerConfigDeny *deny;
1203 context = (void *)server;
1205 SILC_LOG_DEBUG(("Start"));
1207 /* Check whether we could resolve both IP and FQDN. */
1208 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1209 server->config->require_reverse_lookup)) {
1210 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1211 sock->hostname ? sock->hostname :
1212 sock->ip ? sock->ip : ""));
1213 server->stat.conn_failures++;
1214 silc_server_disconnect_remote(server, sock,
1215 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1216 "Unknown host or IP");
1217 silc_free(proto_ctx);
1221 /* Register the connection for network input and output. This sets
1222 that scheduler will listen for incoming packets for this connection
1223 and sets that outgoing packets may be sent to this connection as well.
1224 However, this doesn't set the scheduler for outgoing traffic, it
1225 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1226 later when outgoing data is available. */
1227 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1229 SILC_LOG_INFO(("Incoming connection %s (%s)", sock->hostname,
1232 /* Listenning port */
1233 port = server->sockets[(SilcUInt32)proto_ctx->context]->port;
1235 /* Check whether this connection is denied to connect to us. */
1236 deny = silc_server_config_find_denied(server, sock->ip);
1238 deny = silc_server_config_find_denied(server, sock->hostname);
1240 /* The connection is denied */
1241 SILC_LOG_INFO(("Connection %s (%s) is denied",
1242 sock->hostname, sock->ip));
1243 silc_server_disconnect_remote(server, sock,
1244 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1246 server->stat.conn_failures++;
1247 silc_free(proto_ctx);
1251 /* Check whether we have configured this sort of connection at all. We
1252 have to check all configurations since we don't know what type of
1253 connection this is. */
1254 if (!(cconfig = silc_server_config_find_client(server, sock->ip)))
1255 cconfig = silc_server_config_find_client(server, sock->hostname);
1256 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1257 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1258 if (server->server_type == SILC_ROUTER) {
1259 if (!(rconfig = silc_server_config_find_router_conn(server,
1260 sock->ip, sock->port)))
1261 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1264 if (!cconfig && !sconfig && !rconfig) {
1265 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1267 silc_server_disconnect_remote(server, sock,
1268 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
1269 server->stat.conn_failures++;
1270 silc_free(proto_ctx);
1274 /* The connection is allowed */
1276 /* Set internal context for key exchange protocol. This is
1277 sent as context for the protocol. */
1278 proto_ctx->sock = sock;
1279 proto_ctx->rng = server->rng;
1280 proto_ctx->responder = TRUE;
1281 silc_server_config_ref(&proto_ctx->cconfig, server->config, cconfig);
1282 silc_server_config_ref(&proto_ctx->sconfig, server->config, sconfig);
1283 silc_server_config_ref(&proto_ctx->rconfig, server->config, rconfig);
1285 /* Take flags for key exchange. Since we do not know what type of connection
1286 this is, we go through all found configurations and use the global ones
1287 as well. This will result always into strictest key exchange flags. */
1288 SILC_GET_SKE_FLAGS(cconfig, proto_ctx);
1289 SILC_GET_SKE_FLAGS(sconfig, proto_ctx);
1290 SILC_GET_SKE_FLAGS(rconfig, proto_ctx);
1291 if (server->config->param.key_exchange_pfs)
1292 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
1294 /* Prepare the connection for key exchange protocol. We allocate the
1295 protocol but will not start it yet. The connector will be the
1296 initiator of the protocol thus we will wait for initiation from
1297 there before we start the protocol. */
1298 server->stat.auth_attempts++;
1299 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1300 &sock->protocol, proto_ctx,
1301 silc_server_accept_new_connection_second);
1303 /* Register a timeout task that will be executed if the connector
1304 will not start the key exchange protocol within specified timeout
1305 and the connection will be closed. */
1306 proto_ctx->timeout_task =
1307 silc_schedule_task_add(server->schedule, sock->sock,
1308 silc_server_timeout_remote,
1310 server->config->key_exchange_timeout, 0,
1315 /* Accepts new connections to the server. Accepting new connections are
1316 done in three parts to make it async. */
1318 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1320 SilcServer server = (SilcServer)context;
1321 SilcSocketConnection newsocket;
1322 SilcServerKEInternalContext *proto_ctx;
1325 SILC_LOG_DEBUG(("Accepting new connection"));
1327 server->stat.conn_attempts++;
1329 sock = silc_net_accept_connection(fd);
1331 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1332 server->stat.conn_failures++;
1336 /* Check for maximum allowed connections */
1337 if (sock > server->config->param.connections_max) {
1338 SILC_LOG_ERROR(("Refusing connection, server is full"));
1339 server->stat.conn_failures++;
1340 silc_net_close_connection(sock);
1344 /* Set socket options */
1345 silc_net_set_socket_nonblock(sock);
1346 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1348 /* We don't create a ID yet, since we don't know what type of connection
1349 this is yet. But, we do add the connection to the socket table. */
1350 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1351 server->sockets[sock] = newsocket;
1353 /* Perform asynchronous host lookup. This will lookup the IP and the
1354 FQDN of the remote connection. After the lookup is done the connection
1355 is accepted further. */
1356 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1357 proto_ctx->server = server;
1358 proto_ctx->context = (void *)fd;
1359 silc_socket_host_lookup(newsocket, TRUE,
1360 silc_server_accept_new_connection_lookup,
1361 (void *)proto_ctx, server->schedule);
1364 /* Second part of accepting new connection. Key exchange protocol has been
1365 performed and now it is time to do little connection authentication
1366 protocol to figure out whether this connection is client or server
1367 and whether it has right to access this server (especially server
1368 connections needs to be authenticated). */
1370 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1372 SilcProtocol protocol = (SilcProtocol)context;
1373 SilcServerKEInternalContext *ctx =
1374 (SilcServerKEInternalContext *)protocol->context;
1375 SilcServer server = (SilcServer)ctx->server;
1376 SilcSocketConnection sock = ctx->sock;
1377 SilcServerConnAuthInternalContext *proto_ctx;
1379 SILC_LOG_DEBUG(("Start"));
1381 if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
1382 (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
1383 /* Error occured during protocol */
1384 silc_protocol_free(protocol);
1385 sock->protocol = NULL;
1386 silc_ske_free_key_material(ctx->keymat);
1388 silc_packet_context_free(ctx->packet);
1390 silc_ske_free(ctx->ske);
1391 silc_free(ctx->dest_id);
1392 silc_server_config_unref(&ctx->cconfig);
1393 silc_server_config_unref(&ctx->sconfig);
1394 silc_server_config_unref(&ctx->rconfig);
1396 silc_schedule_task_del_by_callback(server->schedule,
1397 silc_server_failure_callback);
1398 silc_server_disconnect_remote(server, sock,
1399 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
1401 server->stat.auth_failures++;
1405 /* We now have the key material as the result of the key exchange
1406 protocol. Take the key material into use. Free the raw key material
1407 as soon as we've set them into use. */
1408 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1409 ctx->sock, ctx->keymat,
1410 ctx->ske->prop->cipher,
1411 ctx->ske->prop->pkcs,
1412 ctx->ske->prop->hash,
1413 ctx->ske->prop->hmac,
1414 ctx->ske->prop->group,
1416 silc_protocol_free(protocol);
1417 sock->protocol = NULL;
1418 silc_ske_free_key_material(ctx->keymat);
1420 silc_packet_context_free(ctx->packet);
1422 silc_ske_free(ctx->ske);
1423 silc_free(ctx->dest_id);
1424 silc_server_config_unref(&ctx->cconfig);
1425 silc_server_config_unref(&ctx->sconfig);
1426 silc_server_config_unref(&ctx->rconfig);
1428 silc_schedule_task_del_by_callback(server->schedule,
1429 silc_server_failure_callback);
1430 silc_server_disconnect_remote(server, sock,
1431 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1432 server->stat.auth_failures++;
1435 silc_ske_free_key_material(ctx->keymat);
1437 /* Allocate internal context for the authentication protocol. This
1438 is sent as context for the protocol. */
1439 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1440 proto_ctx->server = (void *)server;
1441 proto_ctx->sock = sock;
1442 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1443 proto_ctx->responder = TRUE;
1444 proto_ctx->dest_id_type = ctx->dest_id_type;
1445 proto_ctx->dest_id = ctx->dest_id;
1446 proto_ctx->cconfig = ctx->cconfig;
1447 proto_ctx->sconfig = ctx->sconfig;
1448 proto_ctx->rconfig = ctx->rconfig;
1450 /* Free old protocol as it is finished now */
1451 silc_protocol_free(protocol);
1453 silc_packet_context_free(ctx->packet);
1455 sock->protocol = NULL;
1457 /* Allocate the authentication protocol. This is allocated here
1458 but we won't start it yet. We will be receiving party of this
1459 protocol thus we will wait that connecting party will make
1460 their first move. */
1461 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1462 &sock->protocol, proto_ctx,
1463 silc_server_accept_new_connection_final);
1465 /* Register timeout task. If the protocol is not executed inside
1466 this timelimit the connection will be terminated. */
1467 proto_ctx->timeout_task =
1468 silc_schedule_task_add(server->schedule, sock->sock,
1469 silc_server_timeout_remote,
1471 server->config->conn_auth_timeout, 0,
1476 /* Final part of accepting new connection. The connection has now
1477 been authenticated and keys has been exchanged. We also know whether
1478 this is client or server connection. */
1480 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1482 SilcProtocol protocol = (SilcProtocol)context;
1483 SilcServerConnAuthInternalContext *ctx =
1484 (SilcServerConnAuthInternalContext *)protocol->context;
1485 SilcServer server = (SilcServer)ctx->server;
1486 SilcSocketConnection sock = ctx->sock;
1487 SilcServerHBContext hb_context;
1488 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1490 SilcUInt32 hearbeat_timeout = server->config->param.keepalive_secs;
1492 SILC_LOG_DEBUG(("Start"));
1494 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1495 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1496 /* Error occured during protocol */
1497 silc_protocol_free(protocol);
1498 sock->protocol = NULL;
1500 silc_packet_context_free(ctx->packet);
1502 silc_ske_free(ctx->ske);
1503 silc_free(ctx->dest_id);
1504 silc_server_config_unref(&ctx->cconfig);
1505 silc_server_config_unref(&ctx->sconfig);
1506 silc_server_config_unref(&ctx->rconfig);
1508 silc_schedule_task_del_by_callback(server->schedule,
1509 silc_server_failure_callback);
1510 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1512 server->stat.auth_failures++;
1516 entry->data.last_receive = time(NULL);
1518 switch (ctx->conn_type) {
1519 case SILC_SOCKET_TYPE_CLIENT:
1521 SilcClientEntry client;
1522 SilcServerConfigClient *conn = ctx->cconfig.ref_ptr;
1524 /* Verify whether this connection is after all allowed to connect */
1525 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1526 &server->config->param,
1527 conn->param, ctx->ske)) {
1528 server->stat.auth_failures++;
1532 SILC_LOG_DEBUG(("Remote host is client"));
1533 SILC_LOG_INFO(("Connection %s (%s) is client", sock->hostname,
1536 /* Add the client to the client ID cache. The nickname and Client ID
1537 and other information is created after we have received NEW_CLIENT
1538 packet from client. */
1539 client = silc_idlist_add_client(server->local_list,
1540 NULL, NULL, NULL, NULL, NULL, sock, 0);
1542 SILC_LOG_ERROR(("Could not add new client to cache"));
1543 silc_free(sock->user_data);
1544 silc_server_disconnect_remote(server, sock,
1545 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1546 server->stat.auth_failures++;
1551 server->stat.my_clients++;
1552 server->stat.clients++;
1553 server->stat.cell_clients++;
1555 /* Get connection parameters */
1557 if (conn->param->keepalive_secs)
1558 hearbeat_timeout = conn->param->keepalive_secs;
1561 id_entry = (void *)client;
1564 case SILC_SOCKET_TYPE_SERVER:
1565 case SILC_SOCKET_TYPE_ROUTER:
1567 SilcServerEntry new_server;
1568 bool initiator = FALSE;
1569 bool backup_local = FALSE;
1570 bool backup_router = FALSE;
1571 char *backup_replace_ip = NULL;
1572 SilcUInt16 backup_replace_port = 0;
1573 SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
1574 SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
1576 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1577 /* Verify whether this connection is after all allowed to connect */
1578 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1579 &server->config->param,
1580 rconn ? rconn->param : NULL,
1582 server->stat.auth_failures++;
1588 if (rconn->param->keepalive_secs)
1589 hearbeat_timeout = rconn->param->keepalive_secs;
1592 initiator = rconn->initiator;
1593 backup_local = rconn->backup_local;
1594 backup_router = rconn->backup_router;
1595 backup_replace_ip = rconn->backup_replace_ip;
1596 backup_replace_port = rconn->backup_replace_port;
1600 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
1601 /* Verify whether this connection is after all allowed to connect */
1602 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1603 &server->config->param,
1604 sconn ? sconn->param : NULL,
1606 server->stat.auth_failures++;
1611 if (sconn->param->keepalive_secs)
1612 hearbeat_timeout = sconn->param->keepalive_secs;
1615 backup_router = sconn->backup_router;
1619 SILC_LOG_DEBUG(("Remote host is %s",
1620 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1621 "server" : (backup_router ?
1622 "backup router" : "router")));
1623 SILC_LOG_INFO(("Connection %s (%s) is %s", sock->hostname,
1624 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1625 "server" : (backup_router ?
1626 "backup router" : "router")));
1628 /* Add the server into server cache. The server name and Server ID
1629 is updated after we have received NEW_SERVER packet from the
1630 server. We mark ourselves as router for this server if we really
1633 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1634 server->local_list : (backup_router ?
1635 server->local_list :
1636 server->global_list)),
1638 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1639 SILC_SERVER : SILC_ROUTER),
1641 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1642 server->id_entry : (backup_router ?
1643 server->id_entry : NULL)),
1646 SILC_LOG_ERROR(("Could not add new server to cache"));
1647 silc_free(sock->user_data);
1648 silc_server_disconnect_remote(server, sock,
1649 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1650 server->stat.auth_failures++;
1655 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
1656 server->stat.my_servers++;
1658 server->stat.my_routers++;
1659 server->stat.routers++;
1661 server->stat.servers++;
1663 id_entry = (void *)new_server;
1665 /* If the incoming connection is router and marked as backup router
1666 then add it to be one of our backups */
1667 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
1668 silc_server_backup_add(server, new_server, backup_replace_ip,
1669 backup_replace_port, backup_local);
1671 /* Change it back to SERVER type since that's what it really is. */
1673 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1675 new_server->server_type = SILC_BACKUP_ROUTER;
1678 /* Check whether this connection is to be our primary router connection
1679 if we do not already have the primary route. */
1680 if (!backup_router &&
1681 server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1682 if (silc_server_config_is_primary_route(server) && !initiator)
1685 SILC_LOG_DEBUG(("We are not standalone server anymore"));
1686 server->standalone = FALSE;
1687 if (!server->id_entry->router) {
1688 server->id_entry->router = id_entry;
1689 server->router = id_entry;
1700 sock->type = ctx->conn_type;
1702 /* Add the common data structure to the ID entry. */
1703 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1705 /* Add to sockets internal pointer for fast referencing */
1706 silc_free(sock->user_data);
1707 sock->user_data = id_entry;
1709 /* Connection has been fully established now. Everything is ok. */
1710 SILC_LOG_DEBUG(("New connection authenticated"));
1712 /* Perform keepalive. The `hb_context' will be freed automatically
1713 when finally calling the silc_socket_free function. */
1714 hb_context = silc_calloc(1, sizeof(*hb_context));
1715 hb_context->server = server;
1716 silc_socket_set_heartbeat(sock, hearbeat_timeout, hb_context,
1717 silc_server_perform_heartbeat,
1721 silc_schedule_task_del_by_callback(server->schedule,
1722 silc_server_failure_callback);
1723 silc_protocol_free(protocol);
1725 silc_packet_context_free(ctx->packet);
1727 silc_ske_free(ctx->ske);
1728 silc_free(ctx->dest_id);
1729 silc_server_config_unref(&ctx->cconfig);
1730 silc_server_config_unref(&ctx->sconfig);
1731 silc_server_config_unref(&ctx->rconfig);
1733 sock->protocol = NULL;
1736 /* This function is used to read packets from network and send packets to
1737 network. This is usually a generic task. */
1739 SILC_TASK_CALLBACK(silc_server_packet_process)
1741 SilcServer server = (SilcServer)context;
1742 SilcSocketConnection sock = server->sockets[fd];
1743 SilcIDListData idata;
1744 SilcCipher cipher = NULL;
1745 SilcHmac hmac = NULL;
1746 SilcUInt32 sequence = 0;
1752 SILC_LOG_DEBUG(("Processing packet"));
1754 /* Packet sending */
1756 if (type == SILC_TASK_WRITE) {
1757 /* Do not send data to disconnected connection */
1758 if (SILC_IS_DISCONNECTED(sock))
1761 server->stat.packets_sent++;
1763 /* Send the packet */
1764 ret = silc_packet_send(sock, TRUE);
1766 /* If returned -2 could not write to connection now, will do
1772 SILC_LOG_ERROR(("Error sending packet to connection "
1773 "%s:%d [%s]", sock->hostname, sock->port,
1774 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1775 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1776 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1781 /* The packet has been sent and now it is time to set the connection
1782 back to only for input. When there is again some outgoing data
1783 available for this connection it will be set for output as well.
1784 This call clears the output setting and sets it only for input. */
1785 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1786 SILC_UNSET_OUTBUF_PENDING(sock);
1788 silc_buffer_clear(sock->outbuf);
1792 /* Packet receiving */
1794 /* Read some data from connection */
1795 ret = silc_packet_receive(sock);
1799 SILC_LOG_ERROR(("Error receiving packet from connection "
1800 "%s:%d [%s] %s", sock->hostname, sock->port,
1801 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1802 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1803 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1804 "Router"), strerror(errno)));
1810 SILC_LOG_DEBUG(("Read EOF"));
1812 /* If connection is disconnecting already we will finally
1813 close the connection */
1814 if (SILC_IS_DISCONNECTING(sock)) {
1815 if (sock->user_data)
1816 silc_server_free_sock_user_data(server, sock, NULL);
1817 silc_server_close_connection(server, sock);
1821 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1822 SILC_SET_DISCONNECTING(sock);
1824 if (sock->user_data) {
1826 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
1827 silc_server_free_sock_user_data(server, sock, tmp);
1829 silc_server_free_sock_user_data(server, sock, NULL);
1830 } else if (server->router_conn && server->router_conn->sock == sock &&
1831 !server->router && server->standalone)
1832 silc_schedule_task_add(server->schedule, 0,
1833 silc_server_connect_to_router,
1836 SILC_TASK_PRI_NORMAL);
1838 silc_server_close_connection(server, sock);
1842 /* If connection is disconnecting or disconnected we will ignore
1844 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1845 SILC_LOG_DEBUG(("Ignoring read data from disconnected connection"));
1849 server->stat.packets_received++;
1851 /* Get keys and stuff from ID entry */
1852 idata = (SilcIDListData)sock->user_data;
1854 cipher = idata->receive_key;
1855 hmac = idata->hmac_receive;
1856 sequence = idata->psn_receive;
1859 /* Process the packet. This will call the parser that will then
1860 decrypt and parse the packet. */
1861 ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1862 TRUE : FALSE, cipher, hmac, sequence,
1863 silc_server_packet_parse, server);
1865 /* If this socket connection is not authenticated yet and the packet
1866 processing failed we will drop the connection since it can be
1867 a malicious flooder. */
1868 if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
1869 (!sock->protocol || sock->protocol->protocol->type ==
1870 SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
1871 SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
1872 SILC_SET_DISCONNECTING(sock);
1874 if (sock->user_data)
1875 silc_server_free_sock_user_data(server, sock, NULL);
1876 silc_server_close_connection(server, sock);
1880 /* Parses whole packet, received earlier. */
1882 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1884 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1885 SilcServer server = (SilcServer)parse_ctx->context;
1886 SilcSocketConnection sock = parse_ctx->sock;
1887 SilcPacketContext *packet = parse_ctx->packet;
1888 SilcIDListData idata = (SilcIDListData)sock->user_data;
1891 SILC_LOG_DEBUG(("Start"));
1893 /* Parse the packet */
1894 if (parse_ctx->normal)
1895 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1897 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1899 /* If entry is disabled ignore what we got. */
1900 if (ret != SILC_PACKET_RESUME_ROUTER &&
1901 idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1902 SILC_LOG_DEBUG(("Connection is disabled"));
1906 if (ret == SILC_PACKET_NONE)
1909 /* Check that the the current client ID is same as in the client's packet. */
1910 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1911 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1912 if (client && client->id) {
1913 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1914 packet->src_id_type);
1915 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1923 if (server->server_type == SILC_ROUTER) {
1924 /* Route the packet if it is not destined to us. Other ID types but
1925 server are handled separately after processing them. */
1926 if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1927 packet->dst_id_type == SILC_ID_SERVER &&
1928 sock->type != SILC_SOCKET_TYPE_CLIENT &&
1929 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1931 /* Route the packet to fastest route for the destination ID */
1932 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1933 packet->dst_id_type);
1936 silc_server_packet_route(server,
1937 silc_server_route_get(server, id,
1938 packet->dst_id_type),
1945 /* Parse the incoming packet type */
1946 silc_server_packet_parse_type(server, sock, packet);
1948 if (server->server_type == SILC_ROUTER) {
1949 /* Broadcast packet if it is marked as broadcast packet and it is
1950 originated from router and we are router. */
1951 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1952 packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1953 !server->standalone) {
1954 /* Broadcast to our primary route */
1955 silc_server_packet_broadcast(server, server->router->connection, packet);
1957 /* If we have backup routers then we need to feed all broadcast
1958 data to those servers. */
1959 silc_server_backup_broadcast(server, sock, packet);
1964 silc_packet_context_free(packet);
1965 silc_free(parse_ctx);
1968 /* Parser callback called by silc_packet_receive_process. This merely
1969 registers timeout that will handle the actual parsing when appropriate. */
1971 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1974 SilcServer server = (SilcServer)context;
1975 SilcSocketConnection sock = parser_context->sock;
1976 SilcIDListData idata = (SilcIDListData)sock->user_data;
1979 idata->psn_receive = parser_context->packet->sequence + 1;
1981 /* If protocol for this connection is key exchange or rekey then we'll
1982 process all packets synchronously, since there might be packets in
1983 queue that we are not able to decrypt without first processing the
1984 packets before them. */
1985 if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1986 parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1987 (sock->protocol && sock->protocol->protocol &&
1988 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1989 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1990 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1993 /* Reprocess data since we'll return FALSE here. This is because
1994 the idata->receive_key might have become valid in the last packet
1995 and we want to call this processor with valid cipher. */
1997 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1998 TRUE : FALSE, idata->receive_key,
1999 idata->hmac_receive, idata->psn_receive,
2000 silc_server_packet_parse, server);
2002 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
2003 TRUE : FALSE, NULL, NULL, 0,
2004 silc_server_packet_parse, server);
2008 switch (sock->type) {
2009 case SILC_SOCKET_TYPE_UNKNOWN:
2010 case SILC_SOCKET_TYPE_CLIENT:
2011 /* Parse the packet with timeout */
2012 silc_schedule_task_add(server->schedule, sock->sock,
2013 silc_server_packet_parse_real,
2014 (void *)parser_context, 0, 100000,
2016 SILC_TASK_PRI_NORMAL);
2018 case SILC_SOCKET_TYPE_SERVER:
2019 case SILC_SOCKET_TYPE_ROUTER:
2020 /* Packets from servers are parsed immediately */
2021 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
2031 /* Parses the packet type and calls what ever routines the packet type
2032 requires. This is done for all incoming packets. */
2034 void silc_server_packet_parse_type(SilcServer server,
2035 SilcSocketConnection sock,
2036 SilcPacketContext *packet)
2038 SilcPacketType type = packet->type;
2039 SilcIDListData idata = (SilcIDListData)sock->user_data;
2041 SILC_LOG_DEBUG(("Parsing packet type %d", type));
2043 /* Parse the packet type */
2045 case SILC_PACKET_DISCONNECT:
2048 char *message = NULL;
2050 SILC_LOG_DEBUG(("Disconnect packet"));
2052 if (packet->flags & SILC_PACKET_FLAG_LIST)
2054 if (packet->buffer->len < 1)
2057 status = (SilcStatus)packet->buffer->data[0];
2058 if (packet->buffer->len > 1 &&
2059 silc_utf8_valid(packet->buffer->data + 1, packet->buffer->len - 1))
2060 message = silc_memdup(packet->buffer->data, packet->buffer->len);
2062 SILC_LOG_ERROR(("Disconnected by %s (%s): %s (%d) %s",
2063 sock->ip, sock->hostname,
2064 silc_get_status_message(status), status,
2065 message ? message : ""));
2070 case SILC_PACKET_SUCCESS:
2072 * Success received for something. For now we can have only
2073 * one protocol for connection executing at once hence this
2074 * success message is for whatever protocol is executing currently.
2076 SILC_LOG_DEBUG(("Success packet"));
2077 if (packet->flags & SILC_PACKET_FLAG_LIST)
2080 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2083 case SILC_PACKET_FAILURE:
2085 * Failure received for something. For now we can have only
2086 * one protocol for connection executing at once hence this
2087 * failure message is for whatever protocol is executing currently.
2089 SILC_LOG_DEBUG(("Failure packet"));
2090 if (packet->flags & SILC_PACKET_FLAG_LIST)
2092 if (sock->protocol) {
2093 SilcServerFailureContext f;
2094 f = silc_calloc(1, sizeof(*f));
2098 /* We will wait 5 seconds to process this failure packet */
2099 silc_schedule_task_add(server->schedule, sock->sock,
2100 silc_server_failure_callback, (void *)f, 5, 0,
2101 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2105 case SILC_PACKET_REJECT:
2106 SILC_LOG_DEBUG(("Reject packet"));
2107 if (packet->flags & SILC_PACKET_FLAG_LIST)
2112 case SILC_PACKET_NOTIFY:
2114 * Received notify packet. Server can receive notify packets from
2115 * router. Server then relays the notify messages to clients if needed.
2117 SILC_LOG_DEBUG(("Notify packet"));
2118 if (packet->flags & SILC_PACKET_FLAG_LIST)
2119 silc_server_notify_list(server, sock, packet);
2121 silc_server_notify(server, sock, packet);
2127 case SILC_PACKET_CHANNEL_MESSAGE:
2129 * Received channel message. Channel messages are special packets
2130 * (although probably most common ones) thus they are handled
2133 SILC_LOG_DEBUG(("Channel Message packet"));
2134 if (packet->flags & SILC_PACKET_FLAG_LIST)
2136 idata->last_receive = time(NULL);
2137 silc_server_channel_message(server, sock, packet);
2140 case SILC_PACKET_CHANNEL_KEY:
2142 * Received key for channel. As channels are created by the router
2143 * the keys are as well. We will distribute the key to all of our
2144 * locally connected clients on the particular channel. Router
2145 * never receives this channel and thus is ignored.
2147 SILC_LOG_DEBUG(("Channel Key packet"));
2148 if (packet->flags & SILC_PACKET_FLAG_LIST)
2150 silc_server_channel_key(server, sock, packet);
2156 case SILC_PACKET_COMMAND:
2158 * Recived command. Processes the command request and allocates the
2159 * command context and calls the command.
2161 SILC_LOG_DEBUG(("Command packet"));
2162 if (packet->flags & SILC_PACKET_FLAG_LIST)
2164 silc_server_command_process(server, sock, packet);
2167 case SILC_PACKET_COMMAND_REPLY:
2169 * Received command reply packet. Received command reply to command. It
2170 * may be reply to command sent by us or reply to command sent by client
2171 * that we've routed further.
2173 SILC_LOG_DEBUG(("Command Reply packet"));
2174 if (packet->flags & SILC_PACKET_FLAG_LIST)
2176 silc_server_command_reply(server, sock, packet);
2180 * Private Message packets
2182 case SILC_PACKET_PRIVATE_MESSAGE:
2184 * Received private message packet. The packet is coming from either
2187 SILC_LOG_DEBUG(("Private Message packet"));
2188 if (packet->flags & SILC_PACKET_FLAG_LIST)
2190 idata->last_receive = time(NULL);
2191 silc_server_private_message(server, sock, packet);
2194 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
2196 * Private message key packet.
2198 if (packet->flags & SILC_PACKET_FLAG_LIST)
2200 silc_server_private_message_key(server, sock, packet);
2204 * Key Exchange protocol packets
2206 case SILC_PACKET_KEY_EXCHANGE:
2207 SILC_LOG_DEBUG(("KE packet"));
2208 if (packet->flags & SILC_PACKET_FLAG_LIST)
2211 if (sock->protocol && sock->protocol->protocol &&
2212 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
2213 SilcServerKEInternalContext *proto_ctx =
2214 (SilcServerKEInternalContext *)sock->protocol->context;
2216 proto_ctx->packet = silc_packet_context_dup(packet);
2218 /* Let the protocol handle the packet */
2219 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
2221 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
2222 "protocol active, packet dropped."));
2226 case SILC_PACKET_KEY_EXCHANGE_1:
2227 SILC_LOG_DEBUG(("KE 1 packet"));
2228 if (packet->flags & SILC_PACKET_FLAG_LIST)
2231 if (sock->protocol && sock->protocol->protocol &&
2232 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2233 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2235 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2236 SilcServerRekeyInternalContext *proto_ctx =
2237 (SilcServerRekeyInternalContext *)sock->protocol->context;
2239 if (proto_ctx->packet)
2240 silc_packet_context_free(proto_ctx->packet);
2242 proto_ctx->packet = silc_packet_context_dup(packet);
2244 /* Let the protocol handle the packet */
2245 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2247 SilcServerKEInternalContext *proto_ctx =
2248 (SilcServerKEInternalContext *)sock->protocol->context;
2250 if (proto_ctx->packet)
2251 silc_packet_context_free(proto_ctx->packet);
2253 proto_ctx->packet = silc_packet_context_dup(packet);
2254 proto_ctx->dest_id_type = packet->src_id_type;
2255 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2256 packet->src_id_type);
2257 if (!proto_ctx->dest_id)
2260 /* Let the protocol handle the packet */
2261 silc_protocol_execute(sock->protocol, server->schedule,
2265 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
2266 "protocol active, packet dropped."));
2270 case SILC_PACKET_KEY_EXCHANGE_2:
2271 SILC_LOG_DEBUG(("KE 2 packet"));
2272 if (packet->flags & SILC_PACKET_FLAG_LIST)
2275 if (sock->protocol && sock->protocol->protocol &&
2276 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2277 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2279 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2280 SilcServerRekeyInternalContext *proto_ctx =
2281 (SilcServerRekeyInternalContext *)sock->protocol->context;
2283 if (proto_ctx->packet)
2284 silc_packet_context_free(proto_ctx->packet);
2286 proto_ctx->packet = silc_packet_context_dup(packet);
2288 /* Let the protocol handle the packet */
2289 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2291 SilcServerKEInternalContext *proto_ctx =
2292 (SilcServerKEInternalContext *)sock->protocol->context;
2294 if (proto_ctx->packet)
2295 silc_packet_context_free(proto_ctx->packet);
2297 proto_ctx->packet = silc_packet_context_dup(packet);
2298 proto_ctx->dest_id_type = packet->src_id_type;
2299 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2300 packet->src_id_type);
2301 if (!proto_ctx->dest_id)
2304 /* Let the protocol handle the packet */
2305 silc_protocol_execute(sock->protocol, server->schedule,
2309 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2310 "protocol active, packet dropped."));
2314 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2316 * Connection authentication request packet. When we receive this packet
2317 * we will send to the other end information about our mandatory
2318 * authentication method for the connection. This packet maybe received
2321 SILC_LOG_DEBUG(("Connection authentication request packet"));
2322 if (packet->flags & SILC_PACKET_FLAG_LIST)
2324 silc_server_connection_auth_request(server, sock, packet);
2328 * Connection Authentication protocol packets
2330 case SILC_PACKET_CONNECTION_AUTH:
2331 /* Start of the authentication protocol. We receive here the
2332 authentication data and will verify it. */
2333 SILC_LOG_DEBUG(("Connection auth packet"));
2334 if (packet->flags & SILC_PACKET_FLAG_LIST)
2337 if (sock->protocol && sock->protocol->protocol->type
2338 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2340 SilcServerConnAuthInternalContext *proto_ctx =
2341 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2343 proto_ctx->packet = silc_packet_context_dup(packet);
2345 /* Let the protocol handle the packet */
2346 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2348 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2349 "protocol active, packet dropped."));
2353 case SILC_PACKET_NEW_ID:
2355 * Received New ID packet. This includes some new ID that has been
2356 * created. It may be for client, server or channel. This is the way
2357 * to distribute information about new registered entities in the
2360 SILC_LOG_DEBUG(("New ID packet"));
2361 if (packet->flags & SILC_PACKET_FLAG_LIST)
2362 silc_server_new_id_list(server, sock, packet);
2364 silc_server_new_id(server, sock, packet);
2367 case SILC_PACKET_NEW_CLIENT:
2369 * Received new client packet. This includes client information that
2370 * we will use to create initial client ID. After creating new
2371 * ID we will send it to the client.
2373 SILC_LOG_DEBUG(("New Client packet"));
2374 if (packet->flags & SILC_PACKET_FLAG_LIST)
2376 silc_server_new_client(server, sock, packet);
2379 case SILC_PACKET_NEW_SERVER:
2381 * Received new server packet. This includes Server ID and some other
2382 * information that we may save. This is received after server has
2385 SILC_LOG_DEBUG(("New Server packet"));
2386 if (packet->flags & SILC_PACKET_FLAG_LIST)
2388 silc_server_new_server(server, sock, packet);
2391 case SILC_PACKET_NEW_CHANNEL:
2393 * Received new channel packet. Information about new channel in the
2394 * network are distributed using this packet.
2396 SILC_LOG_DEBUG(("New Channel packet"));
2397 if (packet->flags & SILC_PACKET_FLAG_LIST)
2398 silc_server_new_channel_list(server, sock, packet);
2400 silc_server_new_channel(server, sock, packet);
2403 case SILC_PACKET_HEARTBEAT:
2405 * Received heartbeat.
2407 SILC_LOG_DEBUG(("Heartbeat packet"));
2408 if (packet->flags & SILC_PACKET_FLAG_LIST)
2412 case SILC_PACKET_KEY_AGREEMENT:
2414 * Received heartbeat.
2416 SILC_LOG_DEBUG(("Key agreement packet"));
2417 if (packet->flags & SILC_PACKET_FLAG_LIST)
2419 silc_server_key_agreement(server, sock, packet);
2422 case SILC_PACKET_REKEY:
2424 * Received re-key packet. The sender wants to regenerate the session
2427 SILC_LOG_DEBUG(("Re-key packet"));
2428 if (packet->flags & SILC_PACKET_FLAG_LIST)
2430 silc_server_rekey(server, sock, packet);
2433 case SILC_PACKET_REKEY_DONE:
2435 * The re-key is done.
2437 SILC_LOG_DEBUG(("Re-key done packet"));
2438 if (packet->flags & SILC_PACKET_FLAG_LIST)
2441 if (sock->protocol && sock->protocol->protocol &&
2442 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2444 SilcServerRekeyInternalContext *proto_ctx =
2445 (SilcServerRekeyInternalContext *)sock->protocol->context;
2447 if (proto_ctx->packet)
2448 silc_packet_context_free(proto_ctx->packet);
2450 proto_ctx->packet = silc_packet_context_dup(packet);
2452 /* Let the protocol handle the packet */
2453 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2455 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2456 "protocol active, packet dropped."));
2460 case SILC_PACKET_FTP:
2462 SILC_LOG_DEBUG(("FTP packet"));
2463 if (packet->flags & SILC_PACKET_FLAG_LIST)
2465 silc_server_ftp(server, sock, packet);
2468 case SILC_PACKET_RESUME_CLIENT:
2470 SILC_LOG_DEBUG(("Resume Client packet"));
2471 if (packet->flags & SILC_PACKET_FLAG_LIST)
2473 silc_server_resume_client(server, sock, packet);
2476 case SILC_PACKET_RESUME_ROUTER:
2477 /* Resume router packet received. This packet is received for backup
2478 router resuming protocol. */
2479 SILC_LOG_DEBUG(("Resume router packet"));
2480 if (packet->flags & SILC_PACKET_FLAG_LIST)
2482 silc_server_backup_resume_router(server, sock, packet);
2486 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2492 /* Creates connection to a remote router. */
2494 void silc_server_create_connection(SilcServer server,
2495 const char *remote_host, SilcUInt32 port)
2497 SilcServerConnection sconn;
2499 /* Allocate connection object for hold connection specific stuff. */
2500 sconn = silc_calloc(1, sizeof(*sconn));
2501 sconn->server = server;
2502 sconn->remote_host = strdup(remote_host);
2503 sconn->remote_port = port;
2504 sconn->no_reconnect = TRUE;
2506 silc_schedule_task_add(server->schedule, 0,
2507 silc_server_connect_router,
2508 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
2509 SILC_TASK_PRI_NORMAL);
2512 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2514 silc_socket_free((SilcSocketConnection)context);
2517 /* Closes connection to socket connection */
2519 void silc_server_close_connection(SilcServer server,
2520 SilcSocketConnection sock)
2522 if (!server->sockets[sock->sock])
2525 SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2527 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2528 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2529 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2532 /* We won't listen for this connection anymore */
2533 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2535 /* Unregister all tasks */
2536 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2538 /* Close the actual connection */
2539 silc_net_close_connection(sock->sock);
2540 server->sockets[sock->sock] = NULL;
2542 /* If sock->user_data is NULL then we'll check for active protocols
2543 here since the silc_server_free_sock_user_data has not been called
2544 for this connection. */
2545 if (!sock->user_data) {
2546 /* If any protocol is active cancel its execution. It will call
2547 the final callback which will finalize the disconnection. */
2548 if (sock->protocol) {
2549 silc_protocol_cancel(sock->protocol, server->schedule);
2550 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2551 silc_protocol_execute_final(sock->protocol, server->schedule);
2552 sock->protocol = NULL;
2557 silc_schedule_task_add(server->schedule, 0,
2558 silc_server_close_connection_final,
2559 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
2560 SILC_TASK_PRI_NORMAL);
2563 /* Sends disconnect message to remote connection and disconnects the
2566 void silc_server_disconnect_remote(SilcServer server,
2567 SilcSocketConnection sock,
2568 SilcStatus status, ...)
2571 unsigned char buf[512];
2579 memset(buf, 0, sizeof(buf));
2580 va_start(ap, status);
2581 cp = va_arg(ap, char *);
2583 vsnprintf(buf, sizeof(buf) - 1, cp, ap);
2588 SILC_LOG_DEBUG(("Disconnecting remote host"));
2590 /* Notify remote end that the conversation is over. The notify message
2591 is tried to be sent immediately. */
2595 len += silc_utf8_encoded_len(buf, strlen(buf), SILC_STRING_ASCII);
2597 buffer = silc_buffer_alloc_size(len);
2601 buffer->data[0] = status;
2603 silc_utf8_encode(buf, strlen(buf), SILC_STRING_ASCII, buffer->data + 1,
2605 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
2606 buffer->data, buffer->len, TRUE);
2607 silc_buffer_free(buffer);
2610 silc_server_packet_queue_purge(server, sock);
2612 /* Mark the connection to be disconnected */
2613 SILC_SET_DISCONNECTED(sock);
2614 silc_server_close_connection(server, sock);
2619 SilcClientEntry client;
2620 } *FreeClientInternal;
2622 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2624 FreeClientInternal i = (FreeClientInternal)context;
2626 silc_idlist_del_data(i->client);
2627 silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2631 /* Frees client data and notifies about client's signoff. */
2633 void silc_server_free_client_data(SilcServer server,
2634 SilcSocketConnection sock,
2635 SilcClientEntry client,
2637 const char *signoff)
2639 FreeClientInternal i = silc_calloc(1, sizeof(*i));
2641 /* If there is pending outgoing data for the client then purge it
2642 to the network before removing the client entry. */
2643 silc_server_packet_queue_purge(server, sock);
2646 /* Check if anyone is watching this nickname */
2647 if (server->server_type == SILC_ROUTER)
2648 silc_server_check_watcher_list(server, client, NULL,
2649 SILC_NOTIFY_TYPE_SIGNOFF);
2651 /* Send SIGNOFF notify to routers. */
2652 if (notify && !server->standalone && server->router)
2653 silc_server_send_notify_signoff(server, server->router->connection,
2654 server->server_type == SILC_SERVER ?
2655 FALSE : TRUE, client->id, signoff);
2657 /* Remove client from all channels */
2659 silc_server_remove_from_channels(server, NULL, client,
2660 TRUE, (char *)signoff, TRUE);
2662 silc_server_remove_from_channels(server, NULL, client,
2663 FALSE, NULL, FALSE);
2665 /* Remove this client from watcher list if it is */
2666 silc_server_del_from_watcher_list(server, client);
2669 /* Update statistics */
2670 server->stat.my_clients--;
2671 server->stat.clients--;
2672 if (server->stat.cell_clients)
2673 server->stat.cell_clients--;
2674 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2675 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2676 silc_schedule_task_del_by_context(server->schedule, client);
2678 /* We will not delete the client entry right away. We will take it
2679 into history (for WHOWAS command) for 5 minutes */
2682 silc_schedule_task_add(server->schedule, 0,
2683 silc_server_free_client_data_timeout,
2685 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2686 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2688 client->router = NULL;
2689 client->connection = NULL;
2692 /* Frees user_data pointer from socket connection object. This also sends
2693 appropriate notify packets to the network to inform about leaving
2696 void silc_server_free_sock_user_data(SilcServer server,
2697 SilcSocketConnection sock,
2698 const char *signoff_message)
2700 SILC_LOG_DEBUG(("Start"));
2702 switch (sock->type) {
2703 case SILC_SOCKET_TYPE_CLIENT:
2705 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2706 silc_server_free_client_data(server, sock, user_data, TRUE,
2710 case SILC_SOCKET_TYPE_SERVER:
2711 case SILC_SOCKET_TYPE_ROUTER:
2713 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2714 SilcServerEntry backup_router = NULL;
2717 backup_router = silc_server_backup_get(server, user_data->id);
2719 /* If this was our primary router connection then we're lost to
2720 the outside world. */
2721 if (server->router == user_data) {
2722 /* Check whether we have a backup router connection */
2723 if (!backup_router || backup_router == user_data) {
2724 silc_schedule_task_add(server->schedule, 0,
2725 silc_server_connect_to_router,
2728 SILC_TASK_PRI_NORMAL);
2730 server->id_entry->router = NULL;
2731 server->router = NULL;
2732 server->standalone = TRUE;
2733 backup_router = NULL;
2735 SILC_LOG_INFO(("New primary router is backup router %s",
2736 backup_router->server_name));
2737 SILC_LOG_DEBUG(("New primary router is backup router %s",
2738 backup_router->server_name));
2739 #ifdef BACKUP_SINGLE_ROUTER
2740 if (server->id_entry != backup_router) {
2741 #endif /* BACKUP_SINGLE_ROUTER */
2742 server->id_entry->router = backup_router;
2743 server->router = backup_router;
2744 server->router_connect = time(0);
2745 server->backup_primary = TRUE;
2746 #ifdef BACKUP_SINGLE_ROUTER
2748 server->id_entry->router = NULL;
2749 server->router = NULL;
2750 server->standalone = TRUE;
2752 #endif /* BACKUP_SINGLE_ROUTER */
2754 if (server->server_type == SILC_BACKUP_ROUTER) {
2755 server->server_type = SILC_ROUTER;
2757 /* We'll need to constantly try to reconnect to the primary
2758 router so that we'll see when it comes back online. */
2759 silc_server_backup_reconnect(server, sock->ip, sock->port,
2760 silc_server_backup_connected,
2764 /* Mark this connection as replaced */
2765 silc_server_backup_replaced_add(server, user_data->id,
2768 } else if (backup_router) {
2769 SILC_LOG_INFO(("Enabling the use of backup router %s",
2770 backup_router->server_name));
2771 SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2772 backup_router->server_name));
2774 /* Mark this connection as replaced */
2775 silc_server_backup_replaced_add(server, user_data->id,
2779 if (!backup_router) {
2780 /* Free all client entries that this server owns as they will
2781 become invalid now as well. */
2783 silc_server_remove_clients_by_server(server, user_data, TRUE);
2784 if (server->server_type == SILC_SERVER)
2785 silc_server_remove_channels_by_server(server, user_data);
2787 /* Update the client entries of this server to the new backup
2788 router. This also removes the clients that *really* was owned
2789 by the primary router and went down with the router. */
2790 silc_server_update_clients_by_server(server, user_data, backup_router,
2792 silc_server_update_servers_by_server(server, user_data, backup_router);
2793 if (server->server_type == SILC_SERVER)
2794 silc_server_update_channels_by_server(server, user_data,
2798 /* Free the server entry */
2799 silc_server_backup_del(server, user_data);
2800 silc_server_backup_replaced_del(server, user_data);
2801 silc_idlist_del_data(user_data);
2802 if (!silc_idlist_del_server(server->local_list, user_data))
2803 silc_idlist_del_server(server->global_list, user_data);
2804 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2805 server->stat.my_servers--;
2807 server->stat.my_routers--;
2808 server->stat.routers--;
2810 server->stat.servers--;
2811 if (server->server_type == SILC_ROUTER)
2812 server->stat.cell_servers--;
2814 if (backup_router) {
2815 /* Announce all of our stuff that was created about 5 minutes ago.
2816 The backup router knows all the other stuff already. */
2817 if (server->server_type == SILC_ROUTER)
2818 silc_server_announce_servers(server, FALSE, time(0) - 300,
2819 backup_router->connection);
2821 /* Announce our clients and channels to the router */
2822 silc_server_announce_clients(server, time(0) - 300,
2823 backup_router->connection);
2824 silc_server_announce_channels(server, time(0) - 300,
2825 backup_router->connection);
2831 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2833 silc_idlist_del_data(user_data);
2834 silc_free(user_data);
2839 /* If any protocol is active cancel its execution */
2840 if (sock->protocol) {
2841 silc_protocol_cancel(sock->protocol, server->schedule);
2842 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2843 silc_protocol_execute_final(sock->protocol, server->schedule);
2844 sock->protocol = NULL;
2847 sock->user_data = NULL;
2850 /* Removes client from all channels it has joined. This is used when client
2851 connection is disconnected. If the client on a channel is last, the
2852 channel is removed as well. This sends the SIGNOFF notify types. */
2854 void silc_server_remove_from_channels(SilcServer server,
2855 SilcSocketConnection sock,
2856 SilcClientEntry client,
2858 const char *signoff_message,
2861 SilcChannelEntry channel;
2862 SilcChannelClientEntry chl;
2863 SilcHashTableList htl;
2866 SILC_LOG_DEBUG(("Start"));
2868 if (!client || !client->id)
2871 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2875 /* Remove the client from all channels. The client is removed from
2876 the channels' user list. */
2877 silc_hash_table_list(client->channels, &htl);
2878 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2879 channel = chl->channel;
2881 /* Remove channel if this is last client leaving the channel, unless
2882 the channel is permanent. */
2883 if (server->server_type == SILC_ROUTER &&
2884 silc_hash_table_count(channel->user_list) < 2) {
2885 silc_server_channel_delete(server, channel);
2889 silc_hash_table_del(client->channels, channel);
2890 silc_hash_table_del(channel->user_list, chl->client);
2891 channel->user_count--;
2893 /* If there is no global users on the channel anymore mark the channel
2894 as local channel. Do not check if the removed client is local client. */
2895 if (server->server_type != SILC_ROUTER && channel->global_users &&
2896 chl->client->router && !silc_server_channel_has_global(channel))
2897 channel->global_users = FALSE;
2901 /* Update statistics */
2902 if (client->connection)
2903 server->stat.my_chanclients--;
2904 if (server->server_type == SILC_ROUTER) {
2905 server->stat.cell_chanclients--;
2906 server->stat.chanclients--;
2909 /* If there is not at least one local user on the channel then we don't
2910 need the channel entry anymore, we can remove it safely, unless the
2911 channel is permanent channel */
2912 if (server->server_type != SILC_ROUTER &&
2913 !silc_server_channel_has_local(channel)) {
2914 /* Notify about leaving client if this channel has global users. */
2915 if (notify && channel->global_users)
2916 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2917 SILC_NOTIFY_TYPE_SIGNOFF,
2918 signoff_message ? 2 : 1,
2919 clidp->data, clidp->len,
2920 signoff_message, signoff_message ?
2921 strlen(signoff_message) : 0);
2923 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2924 silc_server_channel_delete(server, channel);
2928 /* Send notify to channel about client leaving SILC and channel too */
2930 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2931 SILC_NOTIFY_TYPE_SIGNOFF,
2932 signoff_message ? 2 : 1,
2933 clidp->data, clidp->len,
2934 signoff_message, signoff_message ?
2935 strlen(signoff_message) : 0);
2937 /* Re-generate channel key if needed */
2938 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2939 if (!silc_server_create_channel_key(server, channel, 0))
2942 /* Send the channel key to the channel. The key of course is not sent
2943 to the client who was removed from the channel. */
2944 silc_server_send_channel_key(server, client->connection, channel,
2945 server->server_type == SILC_ROUTER ?
2946 FALSE : !server->standalone);
2950 silc_hash_table_list_reset(&htl);
2951 silc_buffer_free(clidp);
2954 /* Removes client from one channel. This is used for example when client
2955 calls LEAVE command to remove itself from the channel. Returns TRUE
2956 if channel still exists and FALSE if the channel is removed when
2957 last client leaves the channel. If `notify' is FALSE notify messages
2960 bool silc_server_remove_from_one_channel(SilcServer server,
2961 SilcSocketConnection sock,
2962 SilcChannelEntry channel,
2963 SilcClientEntry client,
2966 SilcChannelClientEntry chl;
2969 SILC_LOG_DEBUG(("Removing %s from channel %s",
2970 silc_id_render(client->id, SILC_ID_CLIENT),
2971 channel->channel_name));
2973 /* Get the entry to the channel, if this client is not on the channel
2975 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2978 /* Remove channel if this is last client leaving the channel, unless
2979 the channel is permanent. */
2980 if (server->server_type == SILC_ROUTER &&
2981 silc_hash_table_count(channel->user_list) < 2) {
2982 silc_server_channel_delete(server, channel);
2986 silc_hash_table_del(client->channels, chl->channel);
2987 silc_hash_table_del(channel->user_list, chl->client);
2988 channel->user_count--;
2990 /* If there is no global users on the channel anymore mark the channel
2991 as local channel. Do not check if the client is local client. */
2992 if (server->server_type != SILC_ROUTER && channel->global_users &&
2993 chl->client->router && !silc_server_channel_has_global(channel))
2994 channel->global_users = FALSE;
2998 /* Update statistics */
2999 if (client->connection)
3000 server->stat.my_chanclients--;
3001 if (server->server_type == SILC_ROUTER) {
3002 server->stat.cell_chanclients--;
3003 server->stat.chanclients--;
3006 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3010 /* If there is not at least one local user on the channel then we don't
3011 need the channel entry anymore, we can remove it safely, unless the
3012 channel is permanent channel */
3013 if (server->server_type != SILC_ROUTER &&
3014 !silc_server_channel_has_local(channel)) {
3015 /* Notify about leaving client if this channel has global users. */
3016 if (notify && channel->global_users)
3017 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
3018 SILC_NOTIFY_TYPE_LEAVE, 1,
3019 clidp->data, clidp->len);
3021 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3022 silc_server_channel_delete(server, channel);
3023 silc_buffer_free(clidp);
3027 /* Send notify to channel about client leaving the channel */
3029 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
3030 SILC_NOTIFY_TYPE_LEAVE, 1,
3031 clidp->data, clidp->len);
3033 silc_buffer_free(clidp);
3037 /* Timeout callback. This is called if connection is idle or for some
3038 other reason is not responding within some period of time. This
3039 disconnects the remote end. */
3041 SILC_TASK_CALLBACK(silc_server_timeout_remote)
3043 SilcServer server = (SilcServer)context;
3044 SilcSocketConnection sock = server->sockets[fd];
3045 SilcProtocolType protocol = 0;
3047 SILC_LOG_DEBUG(("Start"));
3052 SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
3053 sock->hostname, sock->ip));
3055 /* If we have protocol active we must assure that we call the protocol's
3056 final callback so that all the memory is freed. */
3057 if (sock->protocol) {
3058 protocol = sock->protocol->protocol->type;
3059 silc_protocol_cancel(sock->protocol, server->schedule);
3060 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3061 silc_protocol_execute_final(sock->protocol, server->schedule);
3062 sock->protocol = NULL;
3066 if (sock->user_data)
3067 silc_server_free_sock_user_data(server, sock, NULL);
3069 silc_server_disconnect_remote(server, sock,
3071 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3072 SILC_STATUS_ERR_AUTH_FAILED :
3073 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3074 "Connection timeout");
3077 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3078 function may be used only by router. In real SILC network all channels
3079 are created by routers thus this function is never used by normal
3082 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3083 SilcServerID *router_id,
3089 SilcChannelID *channel_id;
3090 SilcChannelEntry entry;
3094 SILC_LOG_DEBUG(("Creating new channel"));
3097 cipher = SILC_DEFAULT_CIPHER;
3099 hmac = SILC_DEFAULT_HMAC;
3101 /* Allocate cipher */
3102 if (!silc_cipher_alloc(cipher, &key))
3106 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3107 silc_cipher_free(key);
3111 channel_name = strdup(channel_name);
3113 /* Create the channel ID */
3114 if (!silc_id_create_channel_id(server, router_id, server->rng,
3116 silc_free(channel_name);
3117 silc_cipher_free(key);
3118 silc_hmac_free(newhmac);
3122 /* Create the channel */
3123 entry = silc_idlist_add_channel(server->local_list, channel_name,
3124 SILC_CHANNEL_MODE_NONE, channel_id,
3125 NULL, key, newhmac, 0);
3127 silc_free(channel_name);
3128 silc_cipher_free(key);
3129 silc_hmac_free(newhmac);
3130 silc_free(channel_id);
3134 entry->cipher = strdup(cipher);
3135 entry->hmac_name = strdup(hmac);
3137 /* Now create the actual key material */
3138 if (!silc_server_create_channel_key(server, entry,
3139 silc_cipher_get_key_len(key) / 8)) {
3140 silc_idlist_del_channel(server->local_list, entry);
3144 /* Notify other routers about the new channel. We send the packet
3145 to our primary route. */
3146 if (broadcast && server->standalone == FALSE)
3147 silc_server_send_new_channel(server, server->router->connection, TRUE,
3148 channel_name, entry->id,
3149 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3152 /* Distribute to backup routers */
3153 if (broadcast && server->server_type == SILC_ROUTER) {
3156 SilcUInt32 name_len = strlen(channel_name);
3157 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
3158 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
3160 packet = silc_channel_payload_encode(channel_name, name_len,
3161 cid, channel_id_len, entry->mode);
3162 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3163 packet->data, packet->len, FALSE, TRUE);
3165 silc_buffer_free(packet);
3168 server->stat.my_channels++;
3169 if (server->server_type == SILC_ROUTER) {
3170 server->stat.channels++;
3171 server->stat.cell_channels++;
3172 entry->users_resolved = TRUE;
3178 /* Same as above but creates the channel with Channel ID `channel_id. */
3181 silc_server_create_new_channel_with_id(SilcServer server,
3185 SilcChannelID *channel_id,
3188 SilcChannelEntry entry;
3192 SILC_LOG_DEBUG(("Creating new channel"));
3195 cipher = SILC_DEFAULT_CIPHER;
3197 hmac = SILC_DEFAULT_HMAC;
3199 /* Allocate cipher */
3200 if (!silc_cipher_alloc(cipher, &key))
3204 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3205 silc_cipher_free(key);
3209 channel_name = strdup(channel_name);
3211 /* Create the channel */
3212 entry = silc_idlist_add_channel(server->local_list, channel_name,
3213 SILC_CHANNEL_MODE_NONE, channel_id,
3214 NULL, key, newhmac, 0);
3216 silc_cipher_free(key);
3217 silc_hmac_free(newhmac);
3218 silc_free(channel_name);
3222 /* Now create the actual key material */
3223 if (!silc_server_create_channel_key(server, entry,
3224 silc_cipher_get_key_len(key) / 8)) {
3225 silc_idlist_del_channel(server->local_list, entry);
3229 /* Notify other routers about the new channel. We send the packet
3230 to our primary route. */
3231 if (broadcast && server->standalone == FALSE)
3232 silc_server_send_new_channel(server, server->router->connection, TRUE,
3233 channel_name, entry->id,
3234 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3237 /* Distribute to backup routers */
3238 if (broadcast && server->server_type == SILC_ROUTER) {
3241 SilcUInt32 name_len = strlen(channel_name);
3242 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
3243 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
3245 packet = silc_channel_payload_encode(channel_name, name_len,
3246 cid, channel_id_len, entry->mode);
3247 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3248 packet->data, packet->len, FALSE, TRUE);
3250 silc_buffer_free(packet);
3253 server->stat.my_channels++;
3254 if (server->server_type == SILC_ROUTER) {
3255 server->stat.channels++;
3256 server->stat.cell_channels++;
3257 entry->users_resolved = TRUE;
3263 /* Channel's key re-key timeout callback. */
3265 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3267 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3268 SilcServer server = (SilcServer)rekey->context;
3272 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3275 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3278 /* Generates new channel key. This is used to create the initial channel key
3279 but also to re-generate new key for channel. If `key_len' is provided
3280 it is the bytes of the key length. */
3282 bool silc_server_create_channel_key(SilcServer server,
3283 SilcChannelEntry channel,
3287 unsigned char channel_key[32], hash[32];
3290 SILC_LOG_DEBUG(("Generating channel key"));
3292 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3293 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3297 if (!channel->channel_key)
3298 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
3299 channel->channel_key = NULL;
3305 else if (channel->key_len)
3306 len = channel->key_len / 8;
3308 len = silc_cipher_get_key_len(channel->channel_key) / 8;
3310 /* Create channel key */
3311 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3314 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
3316 /* Remove old key if exists */
3318 memset(channel->key, 0, channel->key_len / 8);
3319 silc_free(channel->key);
3323 channel->key_len = len * 8;
3324 channel->key = silc_memdup(channel_key, len);
3325 memset(channel_key, 0, sizeof(channel_key));
3327 /* Generate HMAC key from the channel key data and set it */
3329 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3330 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3331 silc_hmac_set_key(channel->hmac, hash,
3332 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3333 memset(hash, 0, sizeof(hash));
3335 if (server->server_type == SILC_ROUTER) {
3336 if (!channel->rekey)
3337 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3338 channel->rekey->context = (void *)server;
3339 channel->rekey->channel = channel;
3340 channel->rekey->key_len = key_len;
3341 if (channel->rekey->task)
3342 silc_schedule_task_del(server->schedule, channel->rekey->task);
3344 channel->rekey->task =
3345 silc_schedule_task_add(server->schedule, 0,
3346 silc_server_channel_key_rekey,
3347 (void *)channel->rekey,
3348 server->config->channel_rekey_secs, 0,
3350 SILC_TASK_PRI_NORMAL);
3356 /* Saves the channel key found in the encoded `key_payload' buffer. This
3357 function is used when we receive Channel Key Payload and also when we're
3358 processing JOIN command reply. Returns entry to the channel. */
3360 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3361 SilcBuffer key_payload,
3362 SilcChannelEntry channel)
3364 SilcChannelKeyPayload payload = NULL;
3365 SilcChannelID *id = NULL;
3366 unsigned char *tmp, hash[32];
3370 SILC_LOG_DEBUG(("Start"));
3372 /* Decode channel key payload */
3373 payload = silc_channel_key_payload_parse(key_payload->data,
3376 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3381 /* Get the channel entry */
3384 /* Get channel ID */
3385 tmp = silc_channel_key_get_id(payload, &tmp_len);
3386 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
3392 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
3394 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
3396 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3397 silc_id_render(id, SILC_ID_CHANNEL)));
3403 tmp = silc_channel_key_get_key(payload, &tmp_len);
3409 cipher = silc_channel_key_get_cipher(payload, NULL);
3415 /* Remove old key if exists */
3417 memset(channel->key, 0, channel->key_len / 8);
3418 silc_free(channel->key);
3419 silc_cipher_free(channel->channel_key);
3422 /* Create new cipher */
3423 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3424 channel->channel_key = NULL;
3429 if (channel->cipher)
3430 silc_free(channel->cipher);
3431 channel->cipher = strdup(cipher);
3434 channel->key_len = tmp_len * 8;
3435 channel->key = silc_memdup(tmp, tmp_len);
3436 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3438 /* Generate HMAC key from the channel key data and set it */
3440 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3441 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3442 silc_hmac_set_key(channel->hmac, hash,
3443 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3445 memset(hash, 0, sizeof(hash));
3446 memset(tmp, 0, tmp_len);
3448 if (server->server_type == SILC_ROUTER) {
3449 if (!channel->rekey)
3450 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3451 channel->rekey->context = (void *)server;
3452 channel->rekey->channel = channel;
3453 if (channel->rekey->task)
3454 silc_schedule_task_del(server->schedule, channel->rekey->task);
3456 channel->rekey->task =
3457 silc_schedule_task_add(server->schedule, 0,
3458 silc_server_channel_key_rekey,
3459 (void *)channel->rekey,
3460 server->config->channel_rekey_secs, 0,
3462 SILC_TASK_PRI_NORMAL);
3468 silc_channel_key_payload_free(payload);
3473 /* Heartbeat callback. This function is set as argument for the
3474 silc_socket_set_heartbeat function. The library will call this function
3475 at the set time interval. */
3477 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3480 SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3482 SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
3484 /* Send the heartbeat */
3485 silc_server_send_heartbeat(hb->server, sock);
3488 /* Returns assembled of all servers in the given ID list. The packet's
3489 form is dictated by the New ID payload. */
3491 static void silc_server_announce_get_servers(SilcServer server,
3492 SilcServerEntry remote,
3494 SilcBuffer *servers,
3495 unsigned long creation_time)
3497 SilcIDCacheList list;
3498 SilcIDCacheEntry id_cache;
3499 SilcServerEntry entry;
3502 /* Go through all clients in the list */
3503 if (silc_idcache_get_all(id_list->servers, &list)) {
3504 if (silc_idcache_list_first(list, &id_cache)) {
3506 entry = (SilcServerEntry)id_cache->context;
3508 /* Do not announce the one we've sending our announcements and
3509 do not announce ourself. Also check the creation time if it's
3511 if ((entry == remote) || (entry == server->id_entry) ||
3512 (creation_time && entry->data.created < creation_time)) {
3513 if (!silc_idcache_list_next(list, &id_cache))
3518 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3520 *servers = silc_buffer_realloc(*servers,
3522 (*servers)->truelen + idp->len :
3524 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3525 silc_buffer_put(*servers, idp->data, idp->len);
3526 silc_buffer_pull(*servers, idp->len);
3527 silc_buffer_free(idp);
3529 if (!silc_idcache_list_next(list, &id_cache))
3534 silc_idcache_list_free(list);
3539 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3545 p = silc_notify_payload_encode(notify, argc, ap);
3551 /* This function is used by router to announce existing servers to our
3552 primary router when we've connected to it. If `creation_time' is non-zero
3553 then only the servers that has been created after the `creation_time'
3554 will be announced. */
3556 void silc_server_announce_servers(SilcServer server, bool global,
3557 unsigned long creation_time,
3558 SilcSocketConnection remote)
3560 SilcBuffer servers = NULL;
3562 SILC_LOG_DEBUG(("Announcing servers"));
3564 /* Get servers in local list */
3565 silc_server_announce_get_servers(server, remote->user_data,
3566 server->local_list, &servers,
3570 /* Get servers in global list */
3571 silc_server_announce_get_servers(server, remote->user_data,
3572 server->global_list, &servers,
3576 silc_buffer_push(servers, servers->data - servers->head);
3577 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3579 /* Send the packet */
3580 silc_server_packet_send(server, remote,
3581 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3582 servers->data, servers->len, TRUE);
3584 silc_buffer_free(servers);
3588 /* Returns assembled packet of all clients in the given ID list. The
3589 packet's form is dictated by the New ID Payload. */
3591 static void silc_server_announce_get_clients(SilcServer server,
3593 SilcBuffer *clients,
3595 unsigned long creation_time)
3597 SilcIDCacheList list;
3598 SilcIDCacheEntry id_cache;
3599 SilcClientEntry client;
3602 unsigned char mode[4];
3604 /* Go through all clients in the list */
3605 if (silc_idcache_get_all(id_list->clients, &list)) {
3606 if (silc_idcache_list_first(list, &id_cache)) {
3608 client = (SilcClientEntry)id_cache->context;
3610 if (creation_time && client->data.created < creation_time) {
3611 if (!silc_idcache_list_next(list, &id_cache))
3616 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3618 *clients = silc_buffer_realloc(*clients,
3620 (*clients)->truelen + idp->len :
3622 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3623 silc_buffer_put(*clients, idp->data, idp->len);
3624 silc_buffer_pull(*clients, idp->len);
3626 SILC_PUT32_MSB(client->mode, mode);
3627 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3628 2, idp->data, idp->len,
3630 *umodes = silc_buffer_realloc(*umodes,
3632 (*umodes)->truelen + tmp->len :
3634 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3635 silc_buffer_put(*umodes, tmp->data, tmp->len);
3636 silc_buffer_pull(*umodes, tmp->len);
3637 silc_buffer_free(tmp);
3639 silc_buffer_free(idp);
3641 if (!silc_idcache_list_next(list, &id_cache))
3646 silc_idcache_list_free(list);
3650 /* This function is used to announce our existing clients to our router
3651 when we've connected to it. If `creation_time' is non-zero then only
3652 the clients that has been created after the `creation_time' will be
3655 void silc_server_announce_clients(SilcServer server,
3656 unsigned long creation_time,
3657 SilcSocketConnection remote)
3659 SilcBuffer clients = NULL;
3660 SilcBuffer umodes = NULL;
3662 SILC_LOG_DEBUG(("Announcing clients"));
3664 /* Get clients in local list */
3665 silc_server_announce_get_clients(server, server->local_list,
3666 &clients, &umodes, creation_time);
3668 /* As router we announce our global list as well */
3669 if (server->server_type == SILC_ROUTER)
3670 silc_server_announce_get_clients(server, server->global_list,
3671 &clients, &umodes, creation_time);
3674 silc_buffer_push(clients, clients->data - clients->head);
3675 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3677 /* Send the packet */
3678 silc_server_packet_send(server, remote,
3679 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3680 clients->data, clients->len, TRUE);
3682 silc_buffer_free(clients);
3686 silc_buffer_push(umodes, umodes->data - umodes->head);
3687 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
3689 /* Send the packet */
3690 silc_server_packet_send(server, remote,
3691 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3692 umodes->data, umodes->len, TRUE);
3694 silc_buffer_free(umodes);
3698 /* Returns channel's topic for announcing it */
3700 void silc_server_announce_get_channel_topic(SilcServer server,
3701 SilcChannelEntry channel,
3706 if (channel->topic) {
3707 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3708 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3709 chidp->data, chidp->len,
3711 strlen(channel->topic));
3712 silc_buffer_free(chidp);
3716 /* Returns assembled packets for channel users of the `channel'. */
3718 void silc_server_announce_get_channel_users(SilcServer server,
3719 SilcChannelEntry channel,
3720 SilcBuffer *channel_modes,
3721 SilcBuffer *channel_users,
3722 SilcBuffer *channel_users_modes)
3724 SilcChannelClientEntry chl;
3725 SilcHashTableList htl;
3726 SilcBuffer chidp, clidp, csidp;
3729 unsigned char mode[4], *fkey = NULL;
3730 SilcUInt32 fkey_len = 0;
3733 SILC_LOG_DEBUG(("Start"));
3735 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3736 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
3739 SILC_PUT32_MSB(channel->mode, mode);
3740 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
3741 if (channel->founder_key)
3742 fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
3744 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
3745 6, csidp->data, csidp->len,
3748 hmac, hmac ? strlen(hmac) : 0,
3749 channel->passphrase,
3750 channel->passphrase ?
3751 strlen(channel->passphrase) : 0,
3755 silc_buffer_realloc(*channel_modes,
3757 (*channel_modes)->truelen + len : len));
3758 silc_buffer_pull_tail(*channel_modes,
3759 ((*channel_modes)->end -
3760 (*channel_modes)->data));
3761 silc_buffer_put(*channel_modes, tmp->data, tmp->len);
3762 silc_buffer_pull(*channel_modes, len);
3763 silc_buffer_free(tmp);
3768 /* Now find all users on the channel */
3769 silc_hash_table_list(channel->user_list, &htl);
3770 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3771 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3774 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
3775 clidp->data, clidp->len,
3776 chidp->data, chidp->len);
3779 silc_buffer_realloc(*channel_users,
3781 (*channel_users)->truelen + len : len));
3782 silc_buffer_pull_tail(*channel_users,
3783 ((*channel_users)->end -
3784 (*channel_users)->data));
3786 silc_buffer_put(*channel_users, tmp->data, tmp->len);
3787 silc_buffer_pull(*channel_users, len);
3788 silc_buffer_free(tmp);
3790 /* CUMODE notify for mode change on the channel */
3791 SILC_PUT32_MSB(chl->mode, mode);
3792 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
3793 fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
3794 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
3795 4, csidp->data, csidp->len,
3797 clidp->data, clidp->len,
3800 *channel_users_modes =
3801 silc_buffer_realloc(*channel_users_modes,
3802 (*channel_users_modes ?
3803 (*channel_users_modes)->truelen + len : len));
3804 silc_buffer_pull_tail(*channel_users_modes,
3805 ((*channel_users_modes)->end -
3806 (*channel_users_modes)->data));
3808 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3809 silc_buffer_pull(*channel_users_modes, len);
3810 silc_buffer_free(tmp);
3814 silc_buffer_free(clidp);
3816 silc_hash_table_list_reset(&htl);
3817 silc_buffer_free(chidp);
3818 silc_buffer_free(csidp);
3821 /* Returns assembled packets for all channels and users on those channels
3822 from the given ID List. The packets are in the form dictated by the
3823 New Channel and New Channel User payloads. */
3825 void silc_server_announce_get_channels(SilcServer server,
3827 SilcBuffer *channels,
3828 SilcBuffer **channel_modes,
3829 SilcBuffer *channel_users,
3830 SilcBuffer **channel_users_modes,
3831 SilcUInt32 *channel_users_modes_c,
3832 SilcBuffer **channel_topics,
3833 SilcChannelID ***channel_ids,
3834 unsigned long creation_time)
3836 SilcIDCacheList list;
3837 SilcIDCacheEntry id_cache;
3838 SilcChannelEntry channel;
3841 SilcUInt16 name_len;
3843 int i = *channel_users_modes_c;
3846 SILC_LOG_DEBUG(("Start"));
3848 /* Go through all channels in the list */
3849 if (silc_idcache_get_all(id_list->channels, &list)) {
3850 if (silc_idcache_list_first(list, &id_cache)) {
3852 channel = (SilcChannelEntry)id_cache->context;
3854 if (creation_time && channel->created < creation_time)
3859 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3860 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3861 name_len = strlen(channel->channel_name);
3864 len = 4 + name_len + id_len + 4;
3866 silc_buffer_realloc(*channels,
3867 (*channels ? (*channels)->truelen +
3869 silc_buffer_pull_tail(*channels,
3870 ((*channels)->end - (*channels)->data));
3871 silc_buffer_format(*channels,
3872 SILC_STR_UI_SHORT(name_len),
3873 SILC_STR_UI_XNSTRING(channel->channel_name,
3875 SILC_STR_UI_SHORT(id_len),
3876 SILC_STR_UI_XNSTRING(cid, id_len),
3877 SILC_STR_UI_INT(channel->mode),
3879 silc_buffer_pull(*channels, len);
3882 /* Channel user modes */
3883 *channel_users_modes = silc_realloc(*channel_users_modes,
3884 sizeof(**channel_users_modes) *
3886 (*channel_users_modes)[i] = NULL;
3887 *channel_modes = silc_realloc(*channel_modes,
3888 sizeof(**channel_modes) * (i + 1));
3889 (*channel_modes)[i] = NULL;
3890 *channel_ids = silc_realloc(*channel_ids,
3891 sizeof(**channel_ids) * (i + 1));
3892 (*channel_ids)[i] = NULL;
3893 silc_server_announce_get_channel_users(server, channel,
3894 &(*channel_modes)[i],
3896 &(*channel_users_modes)[i]);
3897 (*channel_ids)[i] = channel->id;
3899 /* Channel's topic */
3900 *channel_topics = silc_realloc(*channel_topics,
3901 sizeof(**channel_topics) * (i + 1));
3902 (*channel_topics)[i] = NULL;
3903 silc_server_announce_get_channel_topic(server, channel,
3904 &(*channel_topics)[i]);
3907 if (!silc_idcache_list_next(list, &id_cache))
3911 *channel_users_modes_c += i;
3914 silc_idcache_list_free(list);
3918 /* This function is used to announce our existing channels to our router
3919 when we've connected to it. This also announces the users on the
3920 channels to the router. If the `creation_time' is non-zero only the
3921 channels that was created after the `creation_time' are announced.
3922 Note that the channel users are still announced even if the `creation_time'
3925 void silc_server_announce_channels(SilcServer server,
3926 unsigned long creation_time,
3927 SilcSocketConnection remote)
3929 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
3930 SilcBuffer *channel_users_modes = NULL;
3931 SilcBuffer *channel_topics = NULL;
3932 SilcUInt32 channel_users_modes_c = 0;
3933 SilcChannelID **channel_ids = NULL;
3935 SILC_LOG_DEBUG(("Announcing channels and channel users"));
3937 /* Get channels and channel users in local list */
3938 silc_server_announce_get_channels(server, server->local_list,
3939 &channels, &channel_modes,
3941 &channel_users_modes,
3942 &channel_users_modes_c,
3944 &channel_ids, creation_time);
3946 /* Get channels and channel users in global list */
3947 if (server->server_type != SILC_SERVER)
3948 silc_server_announce_get_channels(server, server->global_list,
3949 &channels, &channel_modes,
3951 &channel_users_modes,
3952 &channel_users_modes_c,
3954 &channel_ids, creation_time);
3957 silc_buffer_push(channels, channels->data - channels->head);
3958 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3960 /* Send the packet */
3961 silc_server_packet_send(server, remote,
3962 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3963 channels->data, channels->len,
3966 silc_buffer_free(channels);
3969 if (channel_modes) {
3972 for (i = 0; i < channel_users_modes_c; i++) {
3973 if (!channel_modes[i])
3975 silc_buffer_push(channel_modes[i],
3976 channel_modes[i]->data -
3977 channel_modes[i]->head);
3978 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
3979 channel_modes[i]->len);
3980 silc_server_packet_send_dest(server, remote,
3981 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3982 channel_ids[i], SILC_ID_CHANNEL,
3983 channel_modes[i]->data,
3984 channel_modes[i]->len,
3986 silc_buffer_free(channel_modes[i]);
3988 silc_free(channel_modes);
3991 if (channel_users) {
3992 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3993 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
3994 channel_users->len);
3996 /* Send the packet */
3997 silc_server_packet_send(server, remote,
3998 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3999 channel_users->data, channel_users->len,
4002 silc_buffer_free(channel_users);
4005 if (channel_users_modes) {
4008 for (i = 0; i < channel_users_modes_c; i++) {
4009 if (!channel_users_modes[i])
4011 silc_buffer_push(channel_users_modes[i],
4012 channel_users_modes[i]->data -
4013 channel_users_modes[i]->head);
4014 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4015 channel_users_modes[i]->len);
4016 silc_server_packet_send_dest(server, remote,
4017 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4018 channel_ids[i], SILC_ID_CHANNEL,
4019 channel_users_modes[i]->data,
4020 channel_users_modes[i]->len,
4022 silc_buffer_free(channel_users_modes[i]);
4024 silc_free(channel_users_modes);
4027 if (channel_topics) {
4030 for (i = 0; i < channel_users_modes_c; i++) {
4031 if (!channel_topics[i])
4034 silc_buffer_push(channel_topics[i],
4035 channel_topics[i]->data -
4036 channel_topics[i]->head);
4037 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4038 channel_topics[i]->len);
4039 silc_server_packet_send_dest(server, remote,
4040 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4041 channel_ids[i], SILC_ID_CHANNEL,
4042 channel_topics[i]->data,
4043 channel_topics[i]->len,
4045 silc_buffer_free(channel_topics[i]);
4047 silc_free(channel_topics);
4050 silc_free(channel_ids);
4053 /* Failure timeout callback. If this is called then we will immediately
4054 process the received failure. We always process the failure with timeout
4055 since we do not want to blindly trust to received failure packets.
4056 This won't be called (the timeout is cancelled) if the failure was
4057 bogus (it is bogus if remote does not close the connection after sending
4060 SILC_TASK_CALLBACK(silc_server_failure_callback)
4062 SilcServerFailureContext f = (SilcServerFailureContext)context;
4064 if (f->sock->protocol) {
4065 f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
4066 silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
4072 /* Assembles user list and users mode list from the `channel'. */
4074 bool silc_server_get_users_on_channel(SilcServer server,
4075 SilcChannelEntry channel,
4076 SilcBuffer *user_list,
4077 SilcBuffer *mode_list,
4078 SilcUInt32 *user_count)
4080 SilcChannelClientEntry chl;
4081 SilcHashTableList htl;
4082 SilcBuffer client_id_list;
4083 SilcBuffer client_mode_list;
4085 SilcUInt32 list_count = 0, len = 0;
4087 if (!silc_hash_table_count(channel->user_list))
4090 silc_hash_table_list(channel->user_list, &htl);
4091 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4092 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4093 silc_hash_table_list_reset(&htl);
4095 client_id_list = silc_buffer_alloc(len);
4097 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4098 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
4099 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
4101 silc_hash_table_list(channel->user_list, &htl);
4102 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4104 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4105 silc_buffer_put(client_id_list, idp->data, idp->len);
4106 silc_buffer_pull(client_id_list, idp->len);
4107 silc_buffer_free(idp);
4109 /* Client's mode on channel */
4110 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4111 silc_buffer_pull(client_mode_list, 4);
4115 silc_hash_table_list_reset(&htl);
4116 silc_buffer_push(client_id_list,
4117 client_id_list->data - client_id_list->head);
4118 silc_buffer_push(client_mode_list,
4119 client_mode_list->data - client_mode_list->head);
4121 *user_list = client_id_list;
4122 *mode_list = client_mode_list;
4123 *user_count = list_count;
4127 /* Saves users and their modes to the `channel'. */
4129 void silc_server_save_users_on_channel(SilcServer server,
4130 SilcSocketConnection sock,
4131 SilcChannelEntry channel,
4132 SilcClientID *noadd,
4133 SilcBuffer user_list,
4134 SilcBuffer mode_list,
4135 SilcUInt32 user_count)
4140 SilcClientID *client_id;
4141 SilcClientEntry client;
4142 SilcIDCacheEntry cache;
4143 SilcChannelClientEntry chl;
4146 SILC_LOG_DEBUG(("Start"));
4148 for (i = 0; i < user_count; i++) {
4150 SILC_GET16_MSB(idp_len, user_list->data + 2);
4152 client_id = silc_id_payload_parse_id(user_list->data, idp_len, NULL);
4153 silc_buffer_pull(user_list, idp_len);
4158 SILC_GET32_MSB(mode, mode_list->data);
4159 silc_buffer_pull(mode_list, 4);
4161 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
4162 silc_free(client_id);
4168 /* Check if we have this client cached already. */
4169 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4170 server->server_type, &cache);
4172 client = silc_idlist_find_client_by_id(server->global_list,
4173 client_id, server->server_type,
4178 /* If router did not find such Client ID in its lists then this must
4179 be bogus client or some router in the net is buggy. */
4180 if (server->server_type == SILC_ROUTER) {
4181 silc_free(client_id);
4185 /* We don't have that client anywhere, add it. The client is added
4186 to global list since server didn't have it in the lists so it must be
4188 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4189 silc_id_dup(client_id, SILC_ID_CLIENT),
4190 sock->user_data, NULL, 0);
4192 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4193 silc_free(client_id);
4197 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4199 /* Found, if it is from global list we'll assure that we won't
4200 expire it now that the entry is on channel. */
4205 silc_free(client_id);
4207 if (!silc_server_client_on_channel(client, channel, &chl)) {
4208 /* Client was not on the channel, add it. */
4209 chl = silc_calloc(1, sizeof(*chl));
4210 chl->client = client;
4212 chl->channel = channel;
4213 silc_hash_table_add(channel->user_list, chl->client, chl);
4214 silc_hash_table_add(client->channels, chl->channel, chl);
4215 channel->user_count++;
4223 /* Saves channels and channels user modes to the `client'. Removes
4224 the client from those channels that are not sent in the list but
4227 void silc_server_save_user_channels(SilcServer server,
4228 SilcSocketConnection sock,
4229 SilcClientEntry client,
4230 SilcBuffer channels,
4231 SilcBuffer channels_user_modes)
4234 SilcUInt32 *chumodes;
4235 SilcChannelPayload entry;
4236 SilcChannelEntry channel;
4237 SilcChannelID *channel_id;
4238 SilcChannelClientEntry chl;
4239 SilcHashTable ht = NULL;
4240 SilcHashTableList htl;
4244 if (!channels ||!channels_user_modes)
4247 ch = silc_channel_payload_parse_list(channels->data, channels->len);
4248 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4250 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4251 NULL, NULL, NULL, TRUE);
4252 silc_dlist_start(ch);
4253 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4254 /* Check if we have this channel, and add it if we don't have it.
4255 Also add the client on the channel unless it is there already. */
4256 channel_id = silc_channel_get_id_parse(entry);
4257 channel = silc_idlist_find_channel_by_id(server->local_list,
4260 channel = silc_idlist_find_channel_by_id(server->global_list,
4263 if (server->server_type != SILC_SERVER) {
4264 silc_free(channel_id);
4269 /* We don't have that channel anywhere, add it. */
4270 name = silc_channel_get_name(entry, NULL);
4271 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4272 channel_id, server->router,
4275 silc_free(channel_id);
4282 channel->mode = silc_channel_get_mode(entry);
4284 /* Add the client on the channel */
4285 if (!silc_server_client_on_channel(client, channel, &chl)) {
4286 chl = silc_calloc(1, sizeof(*chl));
4287 chl->client = client;
4288 chl->mode = chumodes[i++];
4289 chl->channel = channel;
4290 silc_hash_table_add(channel->user_list, chl->client, chl);
4291 silc_hash_table_add(client->channels, chl->channel, chl);
4292 channel->user_count++;
4295 chl->mode = chumodes[i++];
4298 silc_hash_table_add(ht, channel, channel);
4299 silc_free(channel_id);
4301 silc_channel_payload_list_free(ch);
4302 silc_free(chumodes);
4306 /* Go through the list again and remove client from channels that
4307 are no part of the list. */
4309 silc_hash_table_list(client->channels, &htl);
4310 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
4311 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4312 silc_hash_table_del(chl->channel->user_list, chl->client);
4313 silc_hash_table_del(chl->client->channels, chl->channel);
4317 silc_hash_table_list_reset(&htl);
4318 silc_hash_table_free(ht);
4320 silc_hash_table_list(client->channels, &htl);
4321 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
4322 silc_hash_table_del(chl->channel->user_list, chl->client);
4323 silc_hash_table_del(chl->client->channels, chl->channel);
4326 silc_hash_table_list_reset(&htl);
4330 /* Lookups route to the client indicated by the `id_data'. The connection
4331 object and internal data object is returned. Returns NULL if route
4332 could not be found to the client. If the `client_id' is specified then
4333 it is used and the `id_data' is ignored. */
4335 SilcSocketConnection
4336 silc_server_get_client_route(SilcServer server,
4337 unsigned char *id_data,
4339 SilcClientID *client_id,
4340 SilcIDListData *idata,
4341 SilcClientEntry *client_entry)
4344 SilcClientEntry client;
4346 SILC_LOG_DEBUG(("Start"));
4349 *client_entry = NULL;
4351 /* Decode destination Client ID */
4353 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
4355 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
4359 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4362 /* If the destination belongs to our server we don't have to route
4363 the packet anywhere but to send it to the local destination. */
4364 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4368 /* If we are router and the client has router then the client is in
4369 our cell but not directly connected to us. */
4370 if (server->server_type == SILC_ROUTER && client->router) {
4371 /* We are of course in this case the client's router thus the route
4372 to the client is the server who owns the client. So, we will send
4373 the packet to that server. */
4375 *idata = (SilcIDListData)client->router;
4376 return client->router->connection;
4379 /* Seems that client really is directly connected to us */
4381 *idata = (SilcIDListData)client;
4383 *client_entry = client;
4384 return client->connection;
4387 /* Destination belongs to someone not in this server. If we are normal
4388 server our action is to send the packet to our router. */
4389 if (server->server_type != SILC_ROUTER && !server->standalone) {
4392 *idata = (SilcIDListData)server->router;
4393 return server->router->connection;
4396 /* We are router and we will perform route lookup for the destination
4397 and send the packet to fastest route. */
4398 if (server->server_type == SILC_ROUTER && !server->standalone) {
4399 /* Check first that the ID is valid */
4400 client = silc_idlist_find_client_by_id(server->global_list, id,
4403 SilcSocketConnection dst_sock;
4405 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4409 *idata = (SilcIDListData)dst_sock->user_data;
4418 /* Encodes and returns channel list of channels the `client' has joined.
4419 Secret channels are not put to the list. */
4421 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4422 SilcClientEntry client,
4425 SilcBuffer *user_mode_list)
4427 SilcBuffer buffer = NULL;
4428 SilcChannelEntry channel;
4429 SilcChannelClientEntry chl;
4430 SilcHashTableList htl;
4433 SilcUInt16 name_len;
4437 *user_mode_list = NULL;
4439 silc_hash_table_list(client->channels, &htl);
4440 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4441 channel = chl->channel;
4443 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4445 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4448 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
4449 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
4450 name_len = strlen(channel->channel_name);
4452 len = 4 + name_len + id_len + 4;
4453 buffer = silc_buffer_realloc(buffer,
4454 (buffer ? buffer->truelen + len : len));
4455 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4456 silc_buffer_format(buffer,
4457 SILC_STR_UI_SHORT(name_len),
4458 SILC_STR_UI_XNSTRING(channel->channel_name,
4460 SILC_STR_UI_SHORT(id_len),
4461 SILC_STR_UI_XNSTRING(cid, id_len),
4462 SILC_STR_UI_INT(chl->channel->mode),
4464 silc_buffer_pull(buffer, len);
4467 if (user_mode_list) {
4468 *user_mode_list = silc_buffer_realloc(*user_mode_list,
4470 (*user_mode_list)->truelen + 4 :
4472 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
4473 (*user_mode_list)->data));
4474 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
4475 silc_buffer_pull(*user_mode_list, 4);
4478 silc_hash_table_list_reset(&htl);
4481 silc_buffer_push(buffer, buffer->data - buffer->head);
4482 if (user_mode_list && *user_mode_list)
4483 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
4484 (*user_mode_list)->head));
4489 /* Finds client entry by Client ID and if it is not found then resolves
4490 it using WHOIS command. */
4492 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
4493 SilcClientID *client_id,
4494 bool always_resolve,
4497 SilcClientEntry client;
4502 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4505 client = silc_idlist_find_client_by_id(server->global_list,
4506 client_id, TRUE, NULL);
4507 if (!client && server->server_type == SILC_ROUTER)
4511 if (!client && server->standalone)
4514 if (!client || !client->nickname || !client->username ||
4516 SilcBuffer buffer, idp;
4519 client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
4520 client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
4521 client->resolve_cmd_ident = ++server->cmd_ident;
4524 idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
4525 buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
4526 server->cmd_ident, 1,
4527 4, idp->data, idp->len);
4528 silc_server_packet_send(server, client ? client->router->connection :
4529 server->router->connection,
4530 SILC_PACKET_COMMAND, 0,
4531 buffer->data, buffer->len, FALSE);
4532 silc_buffer_free(idp);
4533 silc_buffer_free(buffer);
4544 /* A timeout callback for the re-key. We will be the initiator of the
4547 SILC_TASK_CALLBACK(silc_server_rekey_callback)
4549 SilcSocketConnection sock = (SilcSocketConnection)context;
4550 SilcIDListData idata = (SilcIDListData)sock->user_data;
4551 SilcServer server = (SilcServer)idata->rekey->context;
4552 SilcProtocol protocol;
4553 SilcServerRekeyInternalContext *proto_ctx;
4555 SILC_LOG_DEBUG(("Start"));
4557 /* Allocate internal protocol context. This is sent as context
4559 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
4560 proto_ctx->server = (void *)server;
4561 proto_ctx->sock = sock;
4562 proto_ctx->responder = FALSE;
4563 proto_ctx->pfs = idata->rekey->pfs;
4565 /* Perform rekey protocol. Will call the final callback after the
4566 protocol is over. */
4567 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
4568 &protocol, proto_ctx, silc_server_rekey_final);
4569 sock->protocol = protocol;
4571 /* Run the protocol */
4572 silc_protocol_execute(protocol, server->schedule, 0, 0);
4574 /* Re-register re-key timeout */
4575 silc_schedule_task_add(server->schedule, sock->sock,
4576 silc_server_rekey_callback,
4577 context, idata->rekey->timeout, 0,
4578 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
4581 /* The final callback for the REKEY protocol. This will actually take the
4582 new key material into use. */
4584 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
4586 SilcProtocol protocol = (SilcProtocol)context;
4587 SilcServerRekeyInternalContext *ctx =
4588 (SilcServerRekeyInternalContext *)protocol->context;
4589 SilcServer server = (SilcServer)ctx->server;
4590 SilcSocketConnection sock = ctx->sock;
4592 SILC_LOG_DEBUG(("Start"));
4594 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
4595 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
4596 /* Error occured during protocol */
4597 SILC_LOG_ERROR(("Error occurred during rekey protocol"));
4598 silc_protocol_cancel(protocol, server->schedule);
4599 silc_protocol_free(protocol);
4600 sock->protocol = NULL;
4602 silc_packet_context_free(ctx->packet);
4604 silc_ske_free(ctx->ske);
4609 /* Purge the outgoing data queue to assure that all rekey packets really
4610 go to the network before we quit the protocol. */
4611 silc_server_packet_queue_purge(server, sock);
4614 silc_protocol_free(protocol);
4615 sock->protocol = NULL;
4617 silc_packet_context_free(ctx->packet);
4619 silc_ske_free(ctx->ske);
4623 /* Task callback used to retrieve network statistical information from
4624 router server once in a while. */
4626 SILC_TASK_CALLBACK(silc_server_get_stats)
4628 SilcServer server = (SilcServer)context;
4629 SilcBuffer idp, packet;
4631 SILC_LOG_DEBUG(("Retrieving stats from router"));
4633 if (!server->standalone) {
4634 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
4635 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
4636 ++server->cmd_ident, 1,
4637 1, idp->data, idp->len);
4638 silc_server_packet_send(server, server->router->connection,
4639 SILC_PACKET_COMMAND, 0, packet->data,
4640 packet->len, FALSE);
4641 silc_buffer_free(packet);
4642 silc_buffer_free(idp);
4645 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
4646 server, 120, 0, SILC_TASK_TIMEOUT,