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)
89 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
90 silc_dlist_del(server->sim, sim);
93 silc_dlist_uninit(server->sim);
97 for (i = 0; i < server->config->param.connections_max; i++) {
98 if (!server->sockets[i])
100 silc_socket_free(server->sockets[i]);
102 silc_free(server->sockets);
104 silc_server_config_unref(&server->config_ref);
106 silc_rng_free(server->rng);
108 silc_pkcs_free(server->pkcs);
109 if (server->public_key)
110 silc_pkcs_public_key_free(server->public_key);
111 if (server->private_key)
112 silc_pkcs_private_key_free(server->private_key);
113 if (server->pending_commands)
114 silc_dlist_uninit(server->pending_commands);
115 if (server->id_entry)
116 silc_idlist_del_server(server->local_list, server->id_entry);
118 silc_idcache_free(server->local_list->clients);
119 silc_idcache_free(server->local_list->servers);
120 silc_idcache_free(server->local_list->channels);
121 silc_idcache_free(server->global_list->clients);
122 silc_idcache_free(server->global_list->servers);
123 silc_idcache_free(server->global_list->channels);
124 silc_hash_table_free(server->watcher_list);
126 silc_hash_free(server->md5hash);
127 silc_hash_free(server->sha1hash);
128 silc_hmac_unregister_all();
129 silc_hash_unregister_all();
130 silc_cipher_unregister_all();
131 silc_pkcs_unregister_all();
133 silc_free(server->local_list);
134 silc_free(server->global_list);
135 silc_free(server->server_name);
136 silc_free(server->id_string);
137 silc_free(server->purge_i);
138 silc_free(server->purge_g);
142 /* Creates a new server listener. */
144 static bool silc_server_listen(SilcServer server, const char *server_ip,
145 SilcUInt16 port, int *sock)
147 *sock = silc_net_create_server(port, server_ip);
149 SILC_LOG_ERROR(("Could not create server listener: %s on %hu",
156 /* Adds a secondary listener. */
158 bool silc_server_init_secondary(SilcServer server)
160 int sock = 0, sock_list[server->config->param.connections_max];
161 SilcSocketConnection newsocket = NULL;
162 SilcServerConfigServerInfoInterface *interface;
164 for (interface = server->config->server_info->secondary; interface;
165 interface = interface->next, sock++) {
167 if (!silc_server_listen(server,
168 interface->server_ip, interface->port, &sock_list[sock]))
171 /* Set socket to non-blocking mode */
172 silc_net_set_socket_nonblock(sock_list[sock]);
174 /* Add ourselves also to the socket table. The entry allocated above
175 is sent as argument for fast referencing in the future. */
176 silc_socket_alloc(sock_list[sock],
177 SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
178 server->sockets[sock_list[sock]] = newsocket;
180 /* Perform name and address lookups to resolve the listenning address
182 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
184 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
186 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
187 newsocket->hostname ? newsocket->hostname :
188 newsocket->ip ? newsocket->ip : ""));
189 server->stat.conn_failures++;
192 if (!newsocket->hostname)
193 newsocket->hostname = strdup(newsocket->ip);
195 newsocket->port = silc_net_get_local_port(sock);
197 newsocket->user_data = (void *)server->id_entry;
198 silc_schedule_task_add(server->schedule, sock_list[sock],
199 silc_server_accept_new_connection,
200 (void *)server, 0, 0,
202 SILC_TASK_PRI_NORMAL);
208 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
212 /* Initializes the entire SILC server. This is called always before running
213 the server. This is called only once at the initialization of the program.
214 This binds the server to its listenning port. After this function returns
215 one should call silc_server_run to start the server. This returns TRUE
216 when everything is ok to run the server. Configuration file must be
217 read and parsed before calling this. */
219 bool silc_server_init(SilcServer server)
223 SilcServerEntry id_entry;
224 SilcIDListPurge purge;
225 SilcSocketConnection newsocket = NULL;
227 SILC_LOG_DEBUG(("Initializing server"));
229 server->starttime = time(NULL);
231 /* Take config object for us */
232 silc_server_config_ref(&server->config_ref, server->config,
235 /* Steal public and private key from the config object */
236 server->public_key = server->config->server_info->public_key;
237 server->private_key = server->config->server_info->private_key;
238 server->config->server_info->public_key = NULL;
239 server->config->server_info->private_key = NULL;
241 /* Register all configured ciphers, PKCS and hash functions. */
242 if (!silc_server_config_register_ciphers(server))
243 silc_cipher_register_default();
244 if (!silc_server_config_register_pkcs(server))
245 silc_pkcs_register_default();
246 if (!silc_server_config_register_hashfuncs(server))
247 silc_hash_register_default();
248 if (!silc_server_config_register_hmacs(server))
249 silc_hmac_register_default();
251 /* Initialize random number generator for the server. */
252 server->rng = silc_rng_alloc();
253 silc_rng_init(server->rng);
254 silc_rng_global_init(server->rng);
256 /* Initialize hash functions for server to use */
257 silc_hash_alloc("md5", &server->md5hash);
258 silc_hash_alloc("sha1", &server->sha1hash);
260 /* Allocate PKCS context for local public and private keys */
261 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
263 silc_pkcs_public_key_set(server->pkcs, server->public_key);
264 silc_pkcs_private_key_set(server->pkcs, server->private_key);
266 /* Initialize the scheduler */
267 server->schedule = silc_schedule_init(server->config->param.connections_max);
268 if (!server->schedule)
271 /* First, register log files configuration for error output */
272 silc_server_config_setlogfiles(server);
274 /* Initialize ID caches */
275 server->local_list->clients =
276 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
277 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
278 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
280 /* These are allocated for normal server as well as these hold some
281 global information that the server has fetched from its router. For
282 router these are used as they are supposed to be used on router. */
283 server->global_list->clients =
284 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
285 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
286 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
288 /* Init watcher list */
289 server->watcher_list =
290 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
291 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
293 if (!server->watcher_list)
296 /* Create a listening server */
297 if (!silc_server_listen(server,
298 server->config->server_info->primary == NULL ? NULL :
299 server->config->server_info->primary->server_ip,
300 server->config->server_info->primary == NULL ? 0 :
301 server->config->server_info->primary->port,
305 /* Set socket to non-blocking mode */
306 silc_net_set_socket_nonblock(sock);
309 /* Allocate the entire socket list that is used in server. Eventually
310 all connections will have entry in this table (it is a table of
311 pointers to the actual object that is allocated individually
313 server->sockets = silc_calloc(server->config->param.connections_max,
314 sizeof(*server->sockets));
315 if (!server->sockets)
318 /* Add ourselves also to the socket table. The entry allocated above
319 is sent as argument for fast referencing in the future. */
320 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
321 server->sockets[sock] = newsocket;
323 /* Perform name and address lookups to resolve the listenning address
325 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
327 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
329 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
330 newsocket->hostname ? newsocket->hostname :
331 newsocket->ip ? newsocket->ip : ""));
332 server->stat.conn_failures++;
335 if (!newsocket->hostname)
336 newsocket->hostname = strdup(newsocket->ip);
338 newsocket->port = silc_net_get_local_port(sock);
340 /* Create a Server ID for the server. */
341 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
346 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
347 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
348 server->id_type = SILC_ID_SERVER;
349 server->server_name = server->config->server_info->server_name;
350 server->config->server_info->server_name = NULL;
352 /* Add ourselves to the server list. We don't have a router yet
353 beacuse we haven't established a route yet. It will be done later.
354 For now, NULL is sent as router. This allocates new entry to
357 silc_idlist_add_server(server->local_list, strdup(server->server_name),
358 server->server_type, server->id, NULL, NULL);
360 SILC_LOG_ERROR(("Could not add ourselves to cache"));
363 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
365 /* Put the allocated socket pointer also to the entry allocated above
366 for fast back-referencing to the socket list. */
367 newsocket->user_data = (void *)id_entry;
368 id_entry->connection = (void *)newsocket;
369 server->id_entry = id_entry;
371 /* Register protocols */
372 silc_server_protocols_register();
374 /* Add the first task to the scheduler. This is task that is executed by
375 timeout. It expires as soon as the caller calls silc_server_run. This
376 task performs authentication protocol and key exchange with our
378 silc_schedule_task_add(server->schedule, 0,
379 silc_server_connect_to_router,
380 (void *)server, 0, 1,
382 SILC_TASK_PRI_NORMAL);
384 /* Add listener task to the scheduler. This task receives new connections
385 to the server. This task remains on the queue until the end of the
387 silc_schedule_task_add(server->schedule, sock,
388 silc_server_accept_new_connection,
389 (void *)server, 0, 0,
391 SILC_TASK_PRI_NORMAL);
393 if (silc_server_init_secondary(server) == FALSE)
396 server->listenning = TRUE;
398 /* If server connections has been configured then we must be router as
399 normal server cannot have server connections, only router connections. */
400 if (server->config->servers) {
401 SilcServerConfigServer *ptr = server->config->servers;
403 server->server_type = SILC_ROUTER;
405 if (ptr->backup_router) {
406 server->server_type = SILC_BACKUP_ROUTER;
407 server->backup_router = TRUE;
408 server->id_entry->server_type = SILC_BACKUP_ROUTER;
415 /* Register the ID Cache purge task. This periodically purges the ID cache
416 and removes the expired cache entries. */
418 /* Clients local list */
419 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
420 purge->cache = server->local_list->clients;
421 purge->schedule = server->schedule;
422 purge->timeout = 600;
423 silc_schedule_task_add(purge->schedule, 0,
425 (void *)purge, purge->timeout, 0,
426 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
428 /* Clients global list */
429 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
430 purge->cache = server->global_list->clients;
431 purge->schedule = server->schedule;
432 purge->timeout = 300;
433 silc_schedule_task_add(purge->schedule, 0,
435 (void *)purge, purge->timeout, 0,
436 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
438 /* If we are normal server we'll retrieve network statisticial information
439 once in a while from the router. */
440 if (server->server_type == SILC_SERVER)
441 silc_schedule_task_add(purge->schedule, 0, silc_server_get_stats,
442 server, 10, 0, SILC_TASK_TIMEOUT,
445 if (server->server_type == SILC_ROUTER)
446 server->stat.routers++;
448 SILC_LOG_DEBUG(("Server initialized"));
450 /* We are done here, return succesfully */
454 silc_server_config_unref(&server->config_ref);
455 silc_net_close_server(sock);
459 /* This function basically reads the config file again and switches the config
460 object pointed by the server object. After that, we have to fix various
461 things such as the server_name and the listening ports.
462 Keep in mind that we no longer have the root privileges at this point. */
464 bool silc_server_rehash(SilcServer server)
466 SilcServerConfig newconfig;
468 SILC_LOG_INFO(("Rehashing server"));
470 /* Reset the logging system */
471 silc_log_quick = TRUE;
472 silc_log_flush_all();
474 /* Start the main rehash phase (read again the config file) */
475 newconfig = silc_server_config_alloc(server->config_file);
477 SILC_LOG_ERROR(("Rehash FAILED."));
481 /* Reinit scheduler if necessary */
482 if (newconfig->param.connections_max > server->config->param.connections_max)
483 if (!silc_schedule_reinit(server->schedule,
484 newconfig->param.connections_max))
487 /* Fix the server_name field */
488 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
489 silc_free(server->server_name);
490 server->server_name = newconfig->server_info->server_name;
491 newconfig->server_info->server_name = NULL;
493 /* Update the idcache list with a fresh pointer */
494 silc_free(server->id_entry->server_name);
495 server->id_entry->server_name = strdup(server->server_name);
496 if (!silc_idcache_del_by_context(server->local_list->servers,
499 if (!silc_idcache_add(server->local_list->servers,
500 server->id_entry->server_name,
501 server->id_entry->id, server->id_entry, 0, NULL))
506 silc_server_config_setlogfiles(server);
508 /* Change new key pair if necessary */
509 if (newconfig->server_info->public_key &&
510 !silc_pkcs_public_key_compare(server->public_key,
511 newconfig->server_info->public_key)) {
512 silc_pkcs_public_key_free(server->public_key);
513 silc_pkcs_private_key_free(server->private_key);
514 server->public_key = newconfig->server_info->public_key;
515 server->private_key = newconfig->server_info->private_key;
516 newconfig->server_info->public_key = NULL;
517 newconfig->server_info->private_key = NULL;
519 /* Allocate PKCS context for local public and private keys */
520 silc_pkcs_free(server->pkcs);
521 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
523 silc_pkcs_public_key_set(server->pkcs, server->public_key);
524 silc_pkcs_private_key_set(server->pkcs, server->private_key);
527 /* Go through all configured routers after rehash */
528 silc_schedule_task_add(server->schedule, 0,
529 silc_server_connect_to_router,
530 (void *)server, 0, 1,
532 SILC_TASK_PRI_NORMAL);
534 /* Check whether our router status has changed */
535 if (newconfig->servers) {
536 SilcServerConfigServer *ptr = newconfig->servers;
538 server->server_type = SILC_ROUTER;
540 if (ptr->backup_router) {
541 server->server_type = SILC_BACKUP_ROUTER;
542 server->backup_router = TRUE;
543 server->id_entry->server_type = SILC_BACKUP_ROUTER;
550 /* Our old config is gone now. We'll unreference our reference made in
551 silc_server_init and then destroy it since we are destroying it
552 underneath the application (layer which called silc_server_init). */
553 silc_server_config_unref(&server->config_ref);
554 silc_server_config_destroy(server->config);
556 /* Take new config context */
557 server->config = newconfig;
558 silc_server_config_ref(&server->config_ref, server->config, server->config);
560 SILC_LOG_DEBUG(("Server rehashed"));
565 /* The heart of the server. This runs the scheduler thus runs the server.
566 When this returns the server has been stopped and the program will
569 void silc_server_run(SilcServer server)
571 SILC_LOG_INFO(("SILC Server started"));
573 /* Start the scheduler, the heart of the SILC server. When this returns
574 the program will be terminated. */
575 silc_schedule(server->schedule);
578 /* Stops the SILC server. This function is used to shutdown the server.
579 This is usually called after the scheduler has returned. After stopping
580 the server one should call silc_server_free. */
582 void silc_server_stop(SilcServer server)
584 SILC_LOG_DEBUG(("Stopping server"));
586 if (server->schedule) {
587 silc_schedule_stop(server->schedule);
588 silc_schedule_uninit(server->schedule);
589 server->schedule = NULL;
592 silc_server_protocols_unregister();
594 SILC_LOG_DEBUG(("Server stopped"));
597 /* Function that is called when the network connection to a router has
598 been established. This will continue with the key exchange protocol
599 with the remote router. */
601 void silc_server_start_key_exchange(SilcServer server,
602 SilcServerConnection sconn,
605 SilcSocketConnection newsocket;
606 SilcProtocol protocol;
607 SilcServerKEInternalContext *proto_ctx;
608 SilcServerConfigRouter *conn =
609 (SilcServerConfigRouter *) sconn->conn.ref_ptr;
612 /* Cancel any possible retry timeouts */
613 silc_schedule_task_del_by_callback(server->schedule,
614 silc_server_connect_to_router_retry);
616 /* Set socket options */
617 silc_net_set_socket_nonblock(sock);
618 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
620 /* Create socket connection for the connection. Even though we
621 know that we are connecting to a router we will mark the socket
622 to be unknown connection until we have executed authentication
624 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
625 server->sockets[sock] = newsocket;
626 newsocket->hostname = strdup(sconn->remote_host);
627 newsocket->ip = strdup(sconn->remote_host);
628 newsocket->port = sconn->remote_port;
629 sconn->sock = newsocket;
631 /* Allocate internal protocol context. This is sent as context
633 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
634 proto_ctx->server = (void *)server;
635 proto_ctx->context = (void *)sconn;
636 proto_ctx->sock = newsocket;
637 proto_ctx->rng = server->rng;
638 proto_ctx->responder = FALSE;
640 /* Set Key Exchange flags from configuration, but fall back to global
642 SILC_GET_SKE_FLAGS(conn, proto_ctx);
643 if (server->config->param.key_exchange_pfs)
644 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
646 /* Perform key exchange protocol. silc_server_connect_to_router_second
647 will be called after the protocol is finished. */
648 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
649 &protocol, proto_ctx,
650 silc_server_connect_to_router_second);
651 newsocket->protocol = protocol;
653 /* Register a timeout task that will be executed if the protocol
654 is not executed within set limit. */
655 proto_ctx->timeout_task =
656 silc_schedule_task_add(server->schedule, sock,
657 silc_server_timeout_remote,
658 server, server->config->key_exchange_timeout, 0,
662 /* Register the connection for network input and output. This sets
663 that scheduler will listen for incoming packets for this connection
664 and sets that outgoing packets may be sent to this connection as
665 well. However, this doesn't set the scheduler for outgoing traffic,
666 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
667 later when outgoing data is available. */
668 context = (void *)server;
669 SILC_REGISTER_CONNECTION_FOR_IO(sock);
671 /* Run the protocol */
672 silc_protocol_execute(protocol, server->schedule, 0, 0);
675 /* Timeout callback that will be called to retry connecting to remote
676 router. This is used by both normal and router server. This will wait
677 before retrying the connecting. The timeout is generated by exponential
678 backoff algorithm. */
680 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
682 SilcServerConnection sconn = (SilcServerConnection)context;
683 SilcServer server = sconn->server;
684 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
685 SilcServerConfigConnParams *param =
686 (conn->param ? conn->param : &server->config->param);
688 SILC_LOG_INFO(("Retrying connecting to a router"));
690 /* Calculate next timeout */
691 if (sconn->retry_count >= 1) {
692 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
693 if (sconn->retry_timeout > param->reconnect_interval_max)
694 sconn->retry_timeout = param->reconnect_interval_max;
696 sconn->retry_timeout = param->reconnect_interval;
698 sconn->retry_count++;
699 sconn->retry_timeout = sconn->retry_timeout +
700 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
702 /* If we've reached max retry count, give up. */
703 if ((sconn->retry_count > param->reconnect_count) &&
704 !param->reconnect_keep_trying) {
705 SILC_LOG_ERROR(("Could not connect to router, giving up"));
706 silc_server_config_unref(&sconn->conn);
707 silc_free(sconn->remote_host);
708 silc_free(sconn->backup_replace_ip);
713 /* We will lookup a fresh pointer later */
714 silc_server_config_unref(&sconn->conn);
716 /* Wait one before retrying */
717 silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
718 context, sconn->retry_timeout, 0,
719 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
722 /* Generic routine to use connect to a router. */
724 SILC_TASK_CALLBACK(silc_server_connect_router)
726 SilcServerConnection sconn = (SilcServerConnection)context;
727 SilcServer server = sconn->server;
728 SilcServerConfigRouter *rconn;
731 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
732 (sconn->backup ? "backup router" : "router"),
733 sconn->remote_host, sconn->remote_port));
735 server->router_connect = time(NULL);
736 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
739 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
740 (sconn->backup ? "backup router" : "router"),
741 sconn->remote_host, sconn->remote_port));
742 silc_free(sconn->remote_host);
743 silc_free(sconn->backup_replace_ip);
747 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
749 /* Connect to remote host */
750 sock = silc_net_create_connection(
751 (!server->config->server_info->primary ? NULL :
752 server->config->server_info->primary->server_ip),
753 sconn->remote_port, sconn->remote_host);
755 SILC_LOG_ERROR(("Could not connect to router %s:%d",
756 sconn->remote_host, sconn->remote_port));
757 if (!sconn->no_reconnect)
758 silc_schedule_task_add(server->schedule, 0,
759 silc_server_connect_to_router_retry,
760 context, 0, 1, SILC_TASK_TIMEOUT,
761 SILC_TASK_PRI_NORMAL);
763 silc_server_config_unref(&sconn->conn);
767 /* Continue with key exchange protocol */
768 silc_server_start_key_exchange(server, sconn, sock);
771 /* This function connects to our primary router or if we are a router this
772 establishes all our primary routes. This is called at the start of the
773 server to do authentication and key exchange with our router - called
776 SILC_TASK_CALLBACK(silc_server_connect_to_router)
778 SilcServer server = (SilcServer)context;
779 SilcServerConnection sconn;
780 SilcServerConfigRouter *ptr;
782 SILC_LOG_DEBUG(("Connecting to router(s)"));
784 if (server->server_type == SILC_SERVER) {
785 SILC_LOG_DEBUG(("We are normal server"));
786 } else if (server->server_type == SILC_ROUTER) {
787 SILC_LOG_DEBUG(("We are router"));
789 SILC_LOG_DEBUG(("We are backup router/normal server"));
792 if (!server->config->routers) {
793 /* There wasn't a configured router, we will continue but we don't
794 have a connection to outside world. We will be standalone server. */
795 SILC_LOG_DEBUG(("No router(s), server will be standalone"));
796 server->standalone = TRUE;
800 /* Cancel any possible retry timeouts */
801 silc_schedule_task_del_by_callback(server->schedule,
802 silc_server_connect_router);
803 silc_schedule_task_del_by_callback(server->schedule,
804 silc_server_connect_to_router_retry);
806 /* Create the connections to all our routes */
807 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
809 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
810 ptr->backup_router ? "Backup router" : "Router",
811 ptr->initiator ? "Initiator" : "Responder",
812 ptr->host, ptr->port));
814 if (ptr->initiator) {
815 /* Check whether we are connected to this host already */
816 if (silc_server_num_sockets_by_remote(server,
817 silc_net_is_ip(ptr->host) ?
819 silc_net_is_ip(ptr->host) ?
820 NULL : ptr->host, ptr->port,
821 SILC_SOCKET_TYPE_ROUTER)) {
822 SILC_LOG_DEBUG(("We are already connected to this router"));
826 /* Allocate connection object for hold connection specific stuff. */
827 sconn = silc_calloc(1, sizeof(*sconn));
828 sconn->server = server;
829 sconn->remote_host = strdup(ptr->host);
830 sconn->remote_port = ptr->port;
831 sconn->backup = ptr->backup_router;
833 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
834 sconn->backup_replace_port = ptr->backup_replace_port;
837 if (!server->router_conn && !sconn->backup)
838 server->router_conn = sconn;
840 silc_schedule_task_add(server->schedule, 0,
841 silc_server_connect_router,
842 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
843 SILC_TASK_PRI_NORMAL);
848 /* Second part of connecting to router(s). Key exchange protocol has been
849 executed and now we will execute authentication protocol. */
851 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
853 SilcProtocol protocol = (SilcProtocol)context;
854 SilcServerKEInternalContext *ctx =
855 (SilcServerKEInternalContext *)protocol->context;
856 SilcServer server = (SilcServer)ctx->server;
857 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
858 SilcSocketConnection sock = ctx->sock;
859 SilcServerConnAuthInternalContext *proto_ctx;
860 SilcServerConfigRouter *conn = NULL;
862 SILC_LOG_DEBUG(("Start"));
864 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
865 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
866 /* Error occured during protocol */
867 silc_protocol_free(protocol);
868 sock->protocol = NULL;
869 silc_ske_free_key_material(ctx->keymat);
871 silc_packet_context_free(ctx->packet);
873 silc_ske_free(ctx->ske);
874 silc_free(ctx->dest_id);
876 silc_server_config_unref(&sconn->conn);
877 silc_free(sconn->remote_host);
878 silc_free(sconn->backup_replace_ip);
880 silc_schedule_task_del_by_callback(server->schedule,
881 silc_server_failure_callback);
882 silc_server_disconnect_remote(server, sock,
883 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
887 /* We now have the key material as the result of the key exchange
888 protocol. Take the key material into use. Free the raw key material
889 as soon as we've set them into use. */
890 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
891 ctx->sock, ctx->keymat,
892 ctx->ske->prop->cipher,
893 ctx->ske->prop->pkcs,
894 ctx->ske->prop->hash,
895 ctx->ske->prop->hmac,
896 ctx->ske->prop->group,
898 silc_protocol_free(protocol);
899 sock->protocol = NULL;
900 silc_ske_free_key_material(ctx->keymat);
902 silc_packet_context_free(ctx->packet);
904 silc_ske_free(ctx->ske);
905 silc_free(ctx->dest_id);
907 silc_server_config_unref(&sconn->conn);
908 silc_free(sconn->remote_host);
909 silc_free(sconn->backup_replace_ip);
911 silc_schedule_task_del_by_callback(server->schedule,
912 silc_server_failure_callback);
913 silc_server_disconnect_remote(server, sock,
914 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
917 silc_ske_free_key_material(ctx->keymat);
919 /* Allocate internal context for the authentication protocol. This
920 is sent as context for the protocol. */
921 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
922 proto_ctx->server = (void *)server;
923 proto_ctx->context = (void *)sconn;
924 proto_ctx->sock = sock;
925 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
926 proto_ctx->dest_id_type = ctx->dest_id_type;
927 proto_ctx->dest_id = ctx->dest_id;
929 /* Resolve the authentication method used in this connection. Check if
930 we find a match from user configured connections */
931 if (!sconn->conn.ref_ptr)
932 conn = silc_server_config_find_router_conn(server, sock->hostname,
935 conn = sconn->conn.ref_ptr;
938 /* Match found. Use the configured authentication method. Take only
939 the passphrase, since for public key auth we automatically use
940 our local key pair. */
941 if (conn->passphrase) {
942 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
943 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
945 proto_ctx->auth_data = strdup(conn->passphrase);
946 proto_ctx->auth_data_len = strlen(conn->passphrase);
947 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
949 } else if (conn->publickeys) {
950 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
952 proto_ctx->auth_meth = SILC_AUTH_NONE;
955 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
956 sock->hostname, sock->ip, sock->port));
957 silc_protocol_free(protocol);
958 sock->protocol = NULL;
960 silc_packet_context_free(ctx->packet);
962 silc_ske_free(ctx->ske);
963 silc_free(ctx->dest_id);
965 silc_server_config_unref(&sconn->conn);
966 silc_free(sconn->remote_host);
967 silc_free(sconn->backup_replace_ip);
969 silc_schedule_task_del_by_callback(server->schedule,
970 silc_server_failure_callback);
971 silc_server_disconnect_remote(server, sock,
972 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
976 /* Free old protocol as it is finished now */
977 silc_protocol_free(protocol);
979 silc_packet_context_free(ctx->packet);
981 sock->protocol = NULL;
983 /* Allocate the authentication protocol. This is allocated here
984 but we won't start it yet. We will be receiving party of this
985 protocol thus we will wait that connecting party will make
987 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
988 &sock->protocol, proto_ctx,
989 silc_server_connect_to_router_final);
991 /* Register timeout task. If the protocol is not executed inside
992 this timelimit the connection will be terminated. */
993 proto_ctx->timeout_task =
994 silc_schedule_task_add(server->schedule, sock->sock,
995 silc_server_timeout_remote,
997 server->config->conn_auth_timeout, 0,
1001 /* Run the protocol */
1002 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1005 /* Finalizes the connection to router. Registers a server task to the
1006 queue so that we can accept new connections. */
1008 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
1010 SilcProtocol protocol = (SilcProtocol)context;
1011 SilcServerConnAuthInternalContext *ctx =
1012 (SilcServerConnAuthInternalContext *)protocol->context;
1013 SilcServer server = (SilcServer)ctx->server;
1014 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1015 SilcSocketConnection sock = ctx->sock;
1016 SilcServerEntry id_entry;
1018 SilcServerHBContext hb_context;
1019 unsigned char *id_string;
1021 SilcIDListData idata;
1022 SilcServerConfigRouter *conn = NULL;
1023 SilcServerConfigConnParams *param = NULL;
1025 SILC_LOG_DEBUG(("Start"));
1027 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1028 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1029 /* Error occured during protocol */
1030 silc_free(ctx->dest_id);
1031 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1036 /* Add a task to the queue. This task receives new connections to the
1037 server. This task remains on the queue until the end of the program. */
1038 if (!server->listenning && !sconn->backup) {
1039 silc_schedule_task_add(server->schedule, server->sock,
1040 silc_server_accept_new_connection,
1041 (void *)server, 0, 0,
1043 SILC_TASK_PRI_NORMAL);
1044 server->listenning = TRUE;
1047 /* Send NEW_SERVER packet to the router. We will become registered
1048 to the SILC network after sending this packet. */
1049 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
1050 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
1051 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
1052 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1053 silc_buffer_format(packet,
1054 SILC_STR_UI_SHORT(id_len),
1055 SILC_STR_UI_XNSTRING(id_string, id_len),
1056 SILC_STR_UI_SHORT(strlen(server->server_name)),
1057 SILC_STR_UI_XNSTRING(server->server_name,
1058 strlen(server->server_name)),
1061 /* Send the packet */
1062 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
1063 packet->data, packet->len, TRUE);
1064 silc_buffer_free(packet);
1065 silc_free(id_string);
1067 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
1069 /* Check that we do not have this ID already */
1070 id_entry = silc_idlist_find_server_by_id(server->local_list,
1071 ctx->dest_id, TRUE, NULL);
1073 silc_idcache_del_by_context(server->local_list->servers, id_entry);
1075 id_entry = silc_idlist_find_server_by_id(server->global_list,
1076 ctx->dest_id, TRUE, NULL);
1078 silc_idcache_del_by_context(server->global_list->servers, id_entry);
1081 SILC_LOG_DEBUG(("New server id(%s)",
1082 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
1084 /* Add the connected router to global server list */
1085 id_entry = silc_idlist_add_server(server->global_list,
1086 strdup(sock->hostname),
1087 SILC_ROUTER, ctx->dest_id, NULL, sock);
1089 silc_free(ctx->dest_id);
1090 SILC_LOG_ERROR(("Cannot add new server entry to cache"));
1091 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1096 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1097 silc_free(sock->user_data);
1098 sock->user_data = (void *)id_entry;
1099 sock->type = SILC_SOCKET_TYPE_ROUTER;
1100 idata = (SilcIDListData)sock->user_data;
1101 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1103 conn = sconn->conn.ref_ptr;
1104 param = &server->config->param;
1105 if (conn && conn->param)
1106 param = conn->param;
1108 /* Perform keepalive. The `hb_context' will be freed automatically
1109 when finally calling the silc_socket_free function. */
1110 hb_context = silc_calloc(1, sizeof(*hb_context));
1111 hb_context->server = server;
1112 silc_socket_set_heartbeat(sock, param->keepalive_secs, hb_context,
1113 silc_server_perform_heartbeat,
1116 /* Register re-key timeout */
1117 idata->rekey->timeout = param->key_exchange_rekey;
1118 idata->rekey->context = (void *)server;
1119 silc_schedule_task_add(server->schedule, sock->sock,
1120 silc_server_rekey_callback,
1121 (void *)sock, idata->rekey->timeout, 0,
1122 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1124 if (!sconn->backup) {
1125 /* Mark this router our primary router if we're still standalone */
1126 if (server->standalone) {
1127 server->id_entry->router = id_entry;
1128 server->router = id_entry;
1129 server->standalone = FALSE;
1131 /* If we are router then announce our possible servers. */
1132 if (server->server_type == SILC_ROUTER)
1133 silc_server_announce_servers(server, FALSE, 0,
1134 server->router->connection);
1136 /* Announce our clients and channels to the router */
1137 silc_server_announce_clients(server, 0, server->router->connection);
1138 silc_server_announce_channels(server, 0, server->router->connection);
1140 #ifdef BACKUP_SINGLE_ROUTER
1141 /* If we are backup router then this primary router is whom we are
1143 if (server->server_type == SILC_BACKUP_ROUTER)
1144 silc_server_backup_add(server, server->id_entry, sock->ip, 0, TRUE);
1145 #endif /* BACKUP_SINGLE_ROUTER */
1148 /* Add this server to be our backup router */
1149 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1150 sconn->backup_replace_port, FALSE);
1153 sock->protocol = NULL;
1155 /* Call the completion callback to indicate that we've connected to
1157 if (sconn->callback)
1158 (*sconn->callback)(server, id_entry, sconn->callback_context);
1161 /* Free the temporary connection data context */
1163 silc_server_config_unref(&sconn->conn);
1164 silc_free(sconn->remote_host);
1165 silc_free(sconn->backup_replace_ip);
1168 if (sconn == server->router_conn)
1169 server->router_conn = NULL;
1171 /* Free the protocol object */
1172 if (sock->protocol == protocol)
1173 sock->protocol = NULL;
1174 silc_protocol_free(protocol);
1176 silc_packet_context_free(ctx->packet);
1178 silc_ske_free(ctx->ske);
1179 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1180 silc_free(ctx->auth_data);
1184 /* Host lookup callback that is called after the incoming connection's
1185 IP and FQDN lookup is performed. This will actually check the acceptance
1186 of the incoming connection and will register the key exchange protocol
1187 for this connection. */
1190 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1193 SilcServerKEInternalContext *proto_ctx =
1194 (SilcServerKEInternalContext *)context;
1195 SilcServer server = (SilcServer)proto_ctx->server;
1196 SilcServerConfigClient *cconfig = NULL;
1197 SilcServerConfigServer *sconfig = NULL;
1198 SilcServerConfigRouter *rconfig = NULL;
1199 SilcServerConfigDeny *deny;
1202 context = (void *)server;
1204 SILC_LOG_DEBUG(("Start"));
1206 /* Check whether we could resolve both IP and FQDN. */
1207 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1208 server->config->require_reverse_lookup)) {
1209 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1210 sock->hostname ? sock->hostname :
1211 sock->ip ? sock->ip : ""));
1212 server->stat.conn_failures++;
1213 silc_server_disconnect_remote(server, sock,
1214 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1215 "Unknown host or IP");
1216 silc_free(proto_ctx);
1220 /* Register the connection for network input and output. This sets
1221 that scheduler will listen for incoming packets for this connection
1222 and sets that outgoing packets may be sent to this connection as well.
1223 However, this doesn't set the scheduler for outgoing traffic, it
1224 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1225 later when outgoing data is available. */
1226 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1228 SILC_LOG_INFO(("Incoming connection %s (%s)", sock->hostname,
1231 /* Listenning port */
1232 port = server->sockets[(SilcUInt32)proto_ctx->context]->port;
1234 /* Check whether this connection is denied to connect to us. */
1235 deny = silc_server_config_find_denied(server, sock->ip);
1237 deny = silc_server_config_find_denied(server, sock->hostname);
1239 /* The connection is denied */
1240 SILC_LOG_INFO(("Connection %s (%s) is denied",
1241 sock->hostname, sock->ip));
1242 silc_server_disconnect_remote(server, sock,
1243 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1245 server->stat.conn_failures++;
1246 silc_free(proto_ctx);
1250 /* Check whether we have configured this sort of connection at all. We
1251 have to check all configurations since we don't know what type of
1252 connection this is. */
1253 if (!(cconfig = silc_server_config_find_client(server, sock->ip)))
1254 cconfig = silc_server_config_find_client(server, sock->hostname);
1255 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1256 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1257 if (server->server_type == SILC_ROUTER) {
1258 if (!(rconfig = silc_server_config_find_router_conn(server,
1259 sock->ip, sock->port)))
1260 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1263 if (!cconfig && !sconfig && !rconfig) {
1264 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1266 silc_server_disconnect_remote(server, sock,
1267 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
1268 server->stat.conn_failures++;
1269 silc_free(proto_ctx);
1273 /* The connection is allowed */
1275 /* Set internal context for key exchange protocol. This is
1276 sent as context for the protocol. */
1277 proto_ctx->sock = sock;
1278 proto_ctx->rng = server->rng;
1279 proto_ctx->responder = TRUE;
1280 silc_server_config_ref(&proto_ctx->cconfig, server->config, cconfig);
1281 silc_server_config_ref(&proto_ctx->sconfig, server->config, sconfig);
1282 silc_server_config_ref(&proto_ctx->rconfig, server->config, rconfig);
1284 /* Take flags for key exchange. Since we do not know what type of connection
1285 this is, we go through all found configurations and use the global ones
1286 as well. This will result always into strictest key exchange flags. */
1287 SILC_GET_SKE_FLAGS(cconfig, proto_ctx);
1288 SILC_GET_SKE_FLAGS(sconfig, proto_ctx);
1289 SILC_GET_SKE_FLAGS(rconfig, proto_ctx);
1290 if (server->config->param.key_exchange_pfs)
1291 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
1293 /* Prepare the connection for key exchange protocol. We allocate the
1294 protocol but will not start it yet. The connector will be the
1295 initiator of the protocol thus we will wait for initiation from
1296 there before we start the protocol. */
1297 server->stat.auth_attempts++;
1298 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1299 &sock->protocol, proto_ctx,
1300 silc_server_accept_new_connection_second);
1302 /* Register a timeout task that will be executed if the connector
1303 will not start the key exchange protocol within specified timeout
1304 and the connection will be closed. */
1305 proto_ctx->timeout_task =
1306 silc_schedule_task_add(server->schedule, sock->sock,
1307 silc_server_timeout_remote,
1309 server->config->key_exchange_timeout, 0,
1314 /* Accepts new connections to the server. Accepting new connections are
1315 done in three parts to make it async. */
1317 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1319 SilcServer server = (SilcServer)context;
1320 SilcSocketConnection newsocket;
1321 SilcServerKEInternalContext *proto_ctx;
1324 SILC_LOG_DEBUG(("Accepting new connection"));
1326 server->stat.conn_attempts++;
1328 sock = silc_net_accept_connection(fd);
1330 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1331 server->stat.conn_failures++;
1335 /* Check for maximum allowed connections */
1336 if (sock > server->config->param.connections_max) {
1337 SILC_LOG_ERROR(("Refusing connection, server is full"));
1338 server->stat.conn_failures++;
1339 silc_net_close_connection(sock);
1343 /* Set socket options */
1344 silc_net_set_socket_nonblock(sock);
1345 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1347 /* We don't create a ID yet, since we don't know what type of connection
1348 this is yet. But, we do add the connection to the socket table. */
1349 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1350 server->sockets[sock] = newsocket;
1352 /* Perform asynchronous host lookup. This will lookup the IP and the
1353 FQDN of the remote connection. After the lookup is done the connection
1354 is accepted further. */
1355 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1356 proto_ctx->server = server;
1357 proto_ctx->context = (void *)fd;
1358 silc_socket_host_lookup(newsocket, TRUE,
1359 silc_server_accept_new_connection_lookup,
1360 (void *)proto_ctx, server->schedule);
1363 /* Second part of accepting new connection. Key exchange protocol has been
1364 performed and now it is time to do little connection authentication
1365 protocol to figure out whether this connection is client or server
1366 and whether it has right to access this server (especially server
1367 connections needs to be authenticated). */
1369 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1371 SilcProtocol protocol = (SilcProtocol)context;
1372 SilcServerKEInternalContext *ctx =
1373 (SilcServerKEInternalContext *)protocol->context;
1374 SilcServer server = (SilcServer)ctx->server;
1375 SilcSocketConnection sock = ctx->sock;
1376 SilcServerConnAuthInternalContext *proto_ctx;
1378 SILC_LOG_DEBUG(("Start"));
1380 if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
1381 (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
1382 /* Error occured during protocol */
1383 silc_protocol_free(protocol);
1384 sock->protocol = NULL;
1385 silc_ske_free_key_material(ctx->keymat);
1387 silc_packet_context_free(ctx->packet);
1389 silc_ske_free(ctx->ske);
1390 silc_free(ctx->dest_id);
1391 silc_server_config_unref(&ctx->cconfig);
1392 silc_server_config_unref(&ctx->sconfig);
1393 silc_server_config_unref(&ctx->rconfig);
1395 silc_schedule_task_del_by_callback(server->schedule,
1396 silc_server_failure_callback);
1397 silc_server_disconnect_remote(server, sock,
1398 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
1400 server->stat.auth_failures++;
1404 /* We now have the key material as the result of the key exchange
1405 protocol. Take the key material into use. Free the raw key material
1406 as soon as we've set them into use. */
1407 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1408 ctx->sock, ctx->keymat,
1409 ctx->ske->prop->cipher,
1410 ctx->ske->prop->pkcs,
1411 ctx->ske->prop->hash,
1412 ctx->ske->prop->hmac,
1413 ctx->ske->prop->group,
1415 silc_protocol_free(protocol);
1416 sock->protocol = NULL;
1417 silc_ske_free_key_material(ctx->keymat);
1419 silc_packet_context_free(ctx->packet);
1421 silc_ske_free(ctx->ske);
1422 silc_free(ctx->dest_id);
1423 silc_server_config_unref(&ctx->cconfig);
1424 silc_server_config_unref(&ctx->sconfig);
1425 silc_server_config_unref(&ctx->rconfig);
1427 silc_schedule_task_del_by_callback(server->schedule,
1428 silc_server_failure_callback);
1429 silc_server_disconnect_remote(server, sock,
1430 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1431 server->stat.auth_failures++;
1434 silc_ske_free_key_material(ctx->keymat);
1436 /* Allocate internal context for the authentication protocol. This
1437 is sent as context for the protocol. */
1438 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1439 proto_ctx->server = (void *)server;
1440 proto_ctx->sock = sock;
1441 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1442 proto_ctx->responder = TRUE;
1443 proto_ctx->dest_id_type = ctx->dest_id_type;
1444 proto_ctx->dest_id = ctx->dest_id;
1445 proto_ctx->cconfig = ctx->cconfig;
1446 proto_ctx->sconfig = ctx->sconfig;
1447 proto_ctx->rconfig = ctx->rconfig;
1449 /* Free old protocol as it is finished now */
1450 silc_protocol_free(protocol);
1452 silc_packet_context_free(ctx->packet);
1454 sock->protocol = NULL;
1456 /* Allocate the authentication protocol. This is allocated here
1457 but we won't start it yet. We will be receiving party of this
1458 protocol thus we will wait that connecting party will make
1459 their first move. */
1460 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1461 &sock->protocol, proto_ctx,
1462 silc_server_accept_new_connection_final);
1464 /* Register timeout task. If the protocol is not executed inside
1465 this timelimit the connection will be terminated. */
1466 proto_ctx->timeout_task =
1467 silc_schedule_task_add(server->schedule, sock->sock,
1468 silc_server_timeout_remote,
1470 server->config->conn_auth_timeout, 0,
1475 /* Final part of accepting new connection. The connection has now
1476 been authenticated and keys has been exchanged. We also know whether
1477 this is client or server connection. */
1479 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1481 SilcProtocol protocol = (SilcProtocol)context;
1482 SilcServerConnAuthInternalContext *ctx =
1483 (SilcServerConnAuthInternalContext *)protocol->context;
1484 SilcServer server = (SilcServer)ctx->server;
1485 SilcSocketConnection sock = ctx->sock;
1486 SilcServerHBContext hb_context;
1487 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1489 SilcUInt32 hearbeat_timeout = server->config->param.keepalive_secs;
1491 SILC_LOG_DEBUG(("Start"));
1493 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1494 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1495 /* Error occured during protocol */
1496 silc_protocol_free(protocol);
1497 sock->protocol = NULL;
1499 silc_packet_context_free(ctx->packet);
1501 silc_ske_free(ctx->ske);
1502 silc_free(ctx->dest_id);
1503 silc_server_config_unref(&ctx->cconfig);
1504 silc_server_config_unref(&ctx->sconfig);
1505 silc_server_config_unref(&ctx->rconfig);
1507 silc_schedule_task_del_by_callback(server->schedule,
1508 silc_server_failure_callback);
1509 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1511 server->stat.auth_failures++;
1515 entry->data.last_receive = time(NULL);
1517 switch (ctx->conn_type) {
1518 case SILC_SOCKET_TYPE_CLIENT:
1520 SilcClientEntry client;
1521 SilcServerConfigClient *conn = ctx->cconfig.ref_ptr;
1523 /* Verify whether this connection is after all allowed to connect */
1524 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1525 &server->config->param,
1526 conn->param, ctx->ske)) {
1527 server->stat.auth_failures++;
1531 SILC_LOG_DEBUG(("Remote host is client"));
1532 SILC_LOG_INFO(("Connection %s (%s) is client", sock->hostname,
1535 /* Add the client to the client ID cache. The nickname and Client ID
1536 and other information is created after we have received NEW_CLIENT
1537 packet from client. */
1538 client = silc_idlist_add_client(server->local_list,
1539 NULL, NULL, NULL, NULL, NULL, sock, 0);
1541 SILC_LOG_ERROR(("Could not add new client to cache"));
1542 silc_free(sock->user_data);
1543 silc_server_disconnect_remote(server, sock,
1544 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1545 server->stat.auth_failures++;
1550 server->stat.my_clients++;
1551 server->stat.clients++;
1552 server->stat.cell_clients++;
1554 /* Get connection parameters */
1556 if (conn->param->keepalive_secs)
1557 hearbeat_timeout = conn->param->keepalive_secs;
1560 id_entry = (void *)client;
1563 case SILC_SOCKET_TYPE_SERVER:
1564 case SILC_SOCKET_TYPE_ROUTER:
1566 SilcServerEntry new_server;
1567 bool initiator = FALSE;
1568 bool backup_local = FALSE;
1569 bool backup_router = FALSE;
1570 char *backup_replace_ip = NULL;
1571 SilcUInt16 backup_replace_port = 0;
1572 SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
1573 SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
1575 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1576 /* Verify whether this connection is after all allowed to connect */
1577 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1578 &server->config->param,
1579 rconn ? rconn->param : NULL,
1581 server->stat.auth_failures++;
1587 if (rconn->param->keepalive_secs)
1588 hearbeat_timeout = rconn->param->keepalive_secs;
1591 initiator = rconn->initiator;
1592 backup_local = rconn->backup_local;
1593 backup_router = rconn->backup_router;
1594 backup_replace_ip = rconn->backup_replace_ip;
1595 backup_replace_port = rconn->backup_replace_port;
1599 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
1600 /* Verify whether this connection is after all allowed to connect */
1601 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1602 &server->config->param,
1603 sconn ? sconn->param : NULL,
1605 server->stat.auth_failures++;
1610 if (sconn->param->keepalive_secs)
1611 hearbeat_timeout = sconn->param->keepalive_secs;
1614 backup_router = sconn->backup_router;
1618 SILC_LOG_DEBUG(("Remote host is %s",
1619 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1620 "server" : (backup_router ?
1621 "backup router" : "router")));
1622 SILC_LOG_INFO(("Connection %s (%s) is %s", sock->hostname,
1623 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1624 "server" : (backup_router ?
1625 "backup router" : "router")));
1627 /* Add the server into server cache. The server name and Server ID
1628 is updated after we have received NEW_SERVER packet from the
1629 server. We mark ourselves as router for this server if we really
1632 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1633 server->local_list : (backup_router ?
1634 server->local_list :
1635 server->global_list)),
1637 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1638 SILC_SERVER : SILC_ROUTER),
1640 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1641 server->id_entry : (backup_router ?
1642 server->id_entry : NULL)),
1645 SILC_LOG_ERROR(("Could not add new server to cache"));
1646 silc_free(sock->user_data);
1647 silc_server_disconnect_remote(server, sock,
1648 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1649 server->stat.auth_failures++;
1654 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
1655 server->stat.my_servers++;
1657 server->stat.my_routers++;
1658 server->stat.routers++;
1660 server->stat.servers++;
1662 id_entry = (void *)new_server;
1664 /* If the incoming connection is router and marked as backup router
1665 then add it to be one of our backups */
1666 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
1667 silc_server_backup_add(server, new_server, backup_replace_ip,
1668 backup_replace_port, backup_local);
1670 /* Change it back to SERVER type since that's what it really is. */
1672 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1674 new_server->server_type = SILC_BACKUP_ROUTER;
1677 /* Check whether this connection is to be our primary router connection
1678 if we do not already have the primary route. */
1679 if (!backup_router &&
1680 server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1681 if (silc_server_config_is_primary_route(server) && !initiator)
1684 SILC_LOG_DEBUG(("We are not standalone server anymore"));
1685 server->standalone = FALSE;
1686 if (!server->id_entry->router) {
1687 server->id_entry->router = id_entry;
1688 server->router = id_entry;
1699 sock->type = ctx->conn_type;
1701 /* Add the common data structure to the ID entry. */
1702 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1704 /* Add to sockets internal pointer for fast referencing */
1705 silc_free(sock->user_data);
1706 sock->user_data = id_entry;
1708 /* Connection has been fully established now. Everything is ok. */
1709 SILC_LOG_DEBUG(("New connection authenticated"));
1711 /* Perform keepalive. The `hb_context' will be freed automatically
1712 when finally calling the silc_socket_free function. */
1713 hb_context = silc_calloc(1, sizeof(*hb_context));
1714 hb_context->server = server;
1715 silc_socket_set_heartbeat(sock, hearbeat_timeout, hb_context,
1716 silc_server_perform_heartbeat,
1720 silc_schedule_task_del_by_callback(server->schedule,
1721 silc_server_failure_callback);
1722 silc_protocol_free(protocol);
1724 silc_packet_context_free(ctx->packet);
1726 silc_ske_free(ctx->ske);
1727 silc_free(ctx->dest_id);
1728 silc_server_config_unref(&ctx->cconfig);
1729 silc_server_config_unref(&ctx->sconfig);
1730 silc_server_config_unref(&ctx->rconfig);
1732 sock->protocol = NULL;
1735 /* This function is used to read packets from network and send packets to
1736 network. This is usually a generic task. */
1738 SILC_TASK_CALLBACK(silc_server_packet_process)
1740 SilcServer server = (SilcServer)context;
1741 SilcSocketConnection sock = server->sockets[fd];
1742 SilcIDListData idata;
1743 SilcCipher cipher = NULL;
1744 SilcHmac hmac = NULL;
1745 SilcUInt32 sequence = 0;
1751 SILC_LOG_DEBUG(("Processing packet"));
1753 /* Packet sending */
1755 if (type == SILC_TASK_WRITE) {
1756 /* Do not send data to disconnected connection */
1757 if (SILC_IS_DISCONNECTED(sock))
1760 server->stat.packets_sent++;
1762 /* Send the packet */
1763 ret = silc_packet_send(sock, TRUE);
1765 /* If returned -2 could not write to connection now, will do
1771 SILC_LOG_ERROR(("Error sending packet to connection "
1772 "%s:%d [%s]", sock->hostname, sock->port,
1773 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1774 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1775 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1780 /* The packet has been sent and now it is time to set the connection
1781 back to only for input. When there is again some outgoing data
1782 available for this connection it will be set for output as well.
1783 This call clears the output setting and sets it only for input. */
1784 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1785 SILC_UNSET_OUTBUF_PENDING(sock);
1787 silc_buffer_clear(sock->outbuf);
1791 /* Packet receiving */
1793 /* Read some data from connection */
1794 ret = silc_packet_receive(sock);
1798 SILC_LOG_ERROR(("Error receiving packet from connection "
1799 "%s:%d [%s] %s", sock->hostname, sock->port,
1800 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1801 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1802 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1803 "Router"), strerror(errno)));
1809 SILC_LOG_DEBUG(("Read EOF"));
1811 /* If connection is disconnecting already we will finally
1812 close the connection */
1813 if (SILC_IS_DISCONNECTING(sock)) {
1814 if (sock->user_data)
1815 silc_server_free_sock_user_data(server, sock, NULL);
1816 silc_server_close_connection(server, sock);
1820 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1821 SILC_SET_DISCONNECTING(sock);
1823 if (sock->user_data) {
1825 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
1826 silc_server_free_sock_user_data(server, sock, tmp);
1828 silc_server_free_sock_user_data(server, sock, NULL);
1829 } else if (server->router_conn && server->router_conn->sock == sock &&
1830 !server->router && server->standalone)
1831 silc_schedule_task_add(server->schedule, 0,
1832 silc_server_connect_to_router,
1835 SILC_TASK_PRI_NORMAL);
1837 silc_server_close_connection(server, sock);
1841 /* If connection is disconnecting or disconnected we will ignore
1843 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1844 SILC_LOG_DEBUG(("Ignoring read data from disconnected connection"));
1848 server->stat.packets_received++;
1850 /* Get keys and stuff from ID entry */
1851 idata = (SilcIDListData)sock->user_data;
1853 cipher = idata->receive_key;
1854 hmac = idata->hmac_receive;
1855 sequence = idata->psn_receive;
1858 /* Process the packet. This will call the parser that will then
1859 decrypt and parse the packet. */
1860 ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1861 TRUE : FALSE, cipher, hmac, sequence,
1862 silc_server_packet_parse, server);
1864 /* If this socket connection is not authenticated yet and the packet
1865 processing failed we will drop the connection since it can be
1866 a malicious flooder. */
1867 if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
1868 (!sock->protocol || sock->protocol->protocol->type ==
1869 SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
1870 SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
1871 SILC_SET_DISCONNECTING(sock);
1873 if (sock->user_data)
1874 silc_server_free_sock_user_data(server, sock, NULL);
1875 silc_server_close_connection(server, sock);
1879 /* Parses whole packet, received earlier. */
1881 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1883 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1884 SilcServer server = (SilcServer)parse_ctx->context;
1885 SilcSocketConnection sock = parse_ctx->sock;
1886 SilcPacketContext *packet = parse_ctx->packet;
1887 SilcIDListData idata = (SilcIDListData)sock->user_data;
1890 SILC_LOG_DEBUG(("Start"));
1892 /* Parse the packet */
1893 if (parse_ctx->normal)
1894 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1896 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1898 /* If entry is disabled ignore what we got. */
1899 if (ret != SILC_PACKET_RESUME_ROUTER &&
1900 idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1901 SILC_LOG_DEBUG(("Connection is disabled"));
1905 if (ret == SILC_PACKET_NONE)
1908 /* Check that the the current client ID is same as in the client's packet. */
1909 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1910 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1911 if (client && client->id) {
1912 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1913 packet->src_id_type);
1914 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1922 if (server->server_type == SILC_ROUTER) {
1923 /* Route the packet if it is not destined to us. Other ID types but
1924 server are handled separately after processing them. */
1925 if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1926 packet->dst_id_type == SILC_ID_SERVER &&
1927 sock->type != SILC_SOCKET_TYPE_CLIENT &&
1928 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1930 /* Route the packet to fastest route for the destination ID */
1931 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1932 packet->dst_id_type);
1935 silc_server_packet_route(server,
1936 silc_server_route_get(server, id,
1937 packet->dst_id_type),
1944 /* Parse the incoming packet type */
1945 silc_server_packet_parse_type(server, sock, packet);
1947 if (server->server_type == SILC_ROUTER) {
1948 /* Broadcast packet if it is marked as broadcast packet and it is
1949 originated from router and we are router. */
1950 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1951 packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1952 !server->standalone) {
1953 /* Broadcast to our primary route */
1954 silc_server_packet_broadcast(server, server->router->connection, packet);
1956 /* If we have backup routers then we need to feed all broadcast
1957 data to those servers. */
1958 silc_server_backup_broadcast(server, sock, packet);
1963 silc_packet_context_free(packet);
1964 silc_free(parse_ctx);
1967 /* Parser callback called by silc_packet_receive_process. This merely
1968 registers timeout that will handle the actual parsing when appropriate. */
1970 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1973 SilcServer server = (SilcServer)context;
1974 SilcSocketConnection sock = parser_context->sock;
1975 SilcIDListData idata = (SilcIDListData)sock->user_data;
1978 idata->psn_receive = parser_context->packet->sequence + 1;
1980 /* If protocol for this connection is key exchange or rekey then we'll
1981 process all packets synchronously, since there might be packets in
1982 queue that we are not able to decrypt without first processing the
1983 packets before them. */
1984 if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1985 parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1986 (sock->protocol && sock->protocol->protocol &&
1987 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1988 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1989 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1992 /* Reprocess data since we'll return FALSE here. This is because
1993 the idata->receive_key might have become valid in the last packet
1994 and we want to call this processor with valid cipher. */
1996 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1997 TRUE : FALSE, idata->receive_key,
1998 idata->hmac_receive, idata->psn_receive,
1999 silc_server_packet_parse, server);
2001 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
2002 TRUE : FALSE, NULL, NULL, 0,
2003 silc_server_packet_parse, server);
2007 switch (sock->type) {
2008 case SILC_SOCKET_TYPE_UNKNOWN:
2009 case SILC_SOCKET_TYPE_CLIENT:
2010 /* Parse the packet with timeout */
2011 silc_schedule_task_add(server->schedule, sock->sock,
2012 silc_server_packet_parse_real,
2013 (void *)parser_context, 0, 100000,
2015 SILC_TASK_PRI_NORMAL);
2017 case SILC_SOCKET_TYPE_SERVER:
2018 case SILC_SOCKET_TYPE_ROUTER:
2019 /* Packets from servers are parsed immediately */
2020 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
2030 /* Parses the packet type and calls what ever routines the packet type
2031 requires. This is done for all incoming packets. */
2033 void silc_server_packet_parse_type(SilcServer server,
2034 SilcSocketConnection sock,
2035 SilcPacketContext *packet)
2037 SilcPacketType type = packet->type;
2038 SilcIDListData idata = (SilcIDListData)sock->user_data;
2040 SILC_LOG_DEBUG(("Parsing packet type %d", type));
2042 /* Parse the packet type */
2044 case SILC_PACKET_DISCONNECT:
2047 char *message = NULL;
2049 SILC_LOG_DEBUG(("Disconnect packet"));
2051 if (packet->flags & SILC_PACKET_FLAG_LIST)
2053 if (packet->buffer->len < 1)
2056 status = (SilcStatus)packet->buffer->data[0];
2057 if (packet->buffer->len > 1 &&
2058 silc_utf8_valid(packet->buffer->data + 1, packet->buffer->len - 1))
2059 message = silc_memdup(packet->buffer->data, packet->buffer->len);
2061 SILC_LOG_ERROR(("Disconnected by %s (%s): %s (%d) %s",
2062 sock->ip, sock->hostname,
2063 silc_get_status_message(status), status,
2064 message ? message : ""));
2069 case SILC_PACKET_SUCCESS:
2071 * Success received for something. For now we can have only
2072 * one protocol for connection executing at once hence this
2073 * success message is for whatever protocol is executing currently.
2075 SILC_LOG_DEBUG(("Success packet"));
2076 if (packet->flags & SILC_PACKET_FLAG_LIST)
2079 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2082 case SILC_PACKET_FAILURE:
2084 * Failure received for something. For now we can have only
2085 * one protocol for connection executing at once hence this
2086 * failure message is for whatever protocol is executing currently.
2088 SILC_LOG_DEBUG(("Failure packet"));
2089 if (packet->flags & SILC_PACKET_FLAG_LIST)
2091 if (sock->protocol) {
2092 SilcServerFailureContext f;
2093 f = silc_calloc(1, sizeof(*f));
2097 /* We will wait 5 seconds to process this failure packet */
2098 silc_schedule_task_add(server->schedule, sock->sock,
2099 silc_server_failure_callback, (void *)f, 5, 0,
2100 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2104 case SILC_PACKET_REJECT:
2105 SILC_LOG_DEBUG(("Reject packet"));
2106 if (packet->flags & SILC_PACKET_FLAG_LIST)
2111 case SILC_PACKET_NOTIFY:
2113 * Received notify packet. Server can receive notify packets from
2114 * router. Server then relays the notify messages to clients if needed.
2116 SILC_LOG_DEBUG(("Notify packet"));
2117 if (packet->flags & SILC_PACKET_FLAG_LIST)
2118 silc_server_notify_list(server, sock, packet);
2120 silc_server_notify(server, sock, packet);
2126 case SILC_PACKET_CHANNEL_MESSAGE:
2128 * Received channel message. Channel messages are special packets
2129 * (although probably most common ones) thus they are handled
2132 SILC_LOG_DEBUG(("Channel Message packet"));
2133 if (packet->flags & SILC_PACKET_FLAG_LIST)
2135 idata->last_receive = time(NULL);
2136 silc_server_channel_message(server, sock, packet);
2139 case SILC_PACKET_CHANNEL_KEY:
2141 * Received key for channel. As channels are created by the router
2142 * the keys are as well. We will distribute the key to all of our
2143 * locally connected clients on the particular channel. Router
2144 * never receives this channel and thus is ignored.
2146 SILC_LOG_DEBUG(("Channel Key packet"));
2147 if (packet->flags & SILC_PACKET_FLAG_LIST)
2149 silc_server_channel_key(server, sock, packet);
2155 case SILC_PACKET_COMMAND:
2157 * Recived command. Processes the command request and allocates the
2158 * command context and calls the command.
2160 SILC_LOG_DEBUG(("Command packet"));
2161 if (packet->flags & SILC_PACKET_FLAG_LIST)
2163 silc_server_command_process(server, sock, packet);
2166 case SILC_PACKET_COMMAND_REPLY:
2168 * Received command reply packet. Received command reply to command. It
2169 * may be reply to command sent by us or reply to command sent by client
2170 * that we've routed further.
2172 SILC_LOG_DEBUG(("Command Reply packet"));
2173 if (packet->flags & SILC_PACKET_FLAG_LIST)
2175 silc_server_command_reply(server, sock, packet);
2179 * Private Message packets
2181 case SILC_PACKET_PRIVATE_MESSAGE:
2183 * Received private message packet. The packet is coming from either
2186 SILC_LOG_DEBUG(("Private Message packet"));
2187 if (packet->flags & SILC_PACKET_FLAG_LIST)
2189 idata->last_receive = time(NULL);
2190 silc_server_private_message(server, sock, packet);
2193 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
2195 * Private message key packet.
2197 if (packet->flags & SILC_PACKET_FLAG_LIST)
2199 silc_server_private_message_key(server, sock, packet);
2203 * Key Exchange protocol packets
2205 case SILC_PACKET_KEY_EXCHANGE:
2206 SILC_LOG_DEBUG(("KE packet"));
2207 if (packet->flags & SILC_PACKET_FLAG_LIST)
2210 if (sock->protocol && sock->protocol->protocol &&
2211 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
2212 SilcServerKEInternalContext *proto_ctx =
2213 (SilcServerKEInternalContext *)sock->protocol->context;
2215 proto_ctx->packet = silc_packet_context_dup(packet);
2217 /* Let the protocol handle the packet */
2218 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
2220 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
2221 "protocol active, packet dropped."));
2225 case SILC_PACKET_KEY_EXCHANGE_1:
2226 SILC_LOG_DEBUG(("KE 1 packet"));
2227 if (packet->flags & SILC_PACKET_FLAG_LIST)
2230 if (sock->protocol && sock->protocol->protocol &&
2231 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2232 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2234 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2235 SilcServerRekeyInternalContext *proto_ctx =
2236 (SilcServerRekeyInternalContext *)sock->protocol->context;
2238 if (proto_ctx->packet)
2239 silc_packet_context_free(proto_ctx->packet);
2241 proto_ctx->packet = silc_packet_context_dup(packet);
2243 /* Let the protocol handle the packet */
2244 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2246 SilcServerKEInternalContext *proto_ctx =
2247 (SilcServerKEInternalContext *)sock->protocol->context;
2249 if (proto_ctx->packet)
2250 silc_packet_context_free(proto_ctx->packet);
2252 proto_ctx->packet = silc_packet_context_dup(packet);
2253 proto_ctx->dest_id_type = packet->src_id_type;
2254 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2255 packet->src_id_type);
2256 if (!proto_ctx->dest_id)
2259 /* Let the protocol handle the packet */
2260 silc_protocol_execute(sock->protocol, server->schedule,
2264 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
2265 "protocol active, packet dropped."));
2269 case SILC_PACKET_KEY_EXCHANGE_2:
2270 SILC_LOG_DEBUG(("KE 2 packet"));
2271 if (packet->flags & SILC_PACKET_FLAG_LIST)
2274 if (sock->protocol && sock->protocol->protocol &&
2275 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2276 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2278 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2279 SilcServerRekeyInternalContext *proto_ctx =
2280 (SilcServerRekeyInternalContext *)sock->protocol->context;
2282 if (proto_ctx->packet)
2283 silc_packet_context_free(proto_ctx->packet);
2285 proto_ctx->packet = silc_packet_context_dup(packet);
2287 /* Let the protocol handle the packet */
2288 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2290 SilcServerKEInternalContext *proto_ctx =
2291 (SilcServerKEInternalContext *)sock->protocol->context;
2293 if (proto_ctx->packet)
2294 silc_packet_context_free(proto_ctx->packet);
2296 proto_ctx->packet = silc_packet_context_dup(packet);
2297 proto_ctx->dest_id_type = packet->src_id_type;
2298 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2299 packet->src_id_type);
2300 if (!proto_ctx->dest_id)
2303 /* Let the protocol handle the packet */
2304 silc_protocol_execute(sock->protocol, server->schedule,
2308 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2309 "protocol active, packet dropped."));
2313 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2315 * Connection authentication request packet. When we receive this packet
2316 * we will send to the other end information about our mandatory
2317 * authentication method for the connection. This packet maybe received
2320 SILC_LOG_DEBUG(("Connection authentication request packet"));
2321 if (packet->flags & SILC_PACKET_FLAG_LIST)
2323 silc_server_connection_auth_request(server, sock, packet);
2327 * Connection Authentication protocol packets
2329 case SILC_PACKET_CONNECTION_AUTH:
2330 /* Start of the authentication protocol. We receive here the
2331 authentication data and will verify it. */
2332 SILC_LOG_DEBUG(("Connection auth packet"));
2333 if (packet->flags & SILC_PACKET_FLAG_LIST)
2336 if (sock->protocol && sock->protocol->protocol->type
2337 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2339 SilcServerConnAuthInternalContext *proto_ctx =
2340 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2342 proto_ctx->packet = silc_packet_context_dup(packet);
2344 /* Let the protocol handle the packet */
2345 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2347 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2348 "protocol active, packet dropped."));
2352 case SILC_PACKET_NEW_ID:
2354 * Received New ID packet. This includes some new ID that has been
2355 * created. It may be for client, server or channel. This is the way
2356 * to distribute information about new registered entities in the
2359 SILC_LOG_DEBUG(("New ID packet"));
2360 if (packet->flags & SILC_PACKET_FLAG_LIST)
2361 silc_server_new_id_list(server, sock, packet);
2363 silc_server_new_id(server, sock, packet);
2366 case SILC_PACKET_NEW_CLIENT:
2368 * Received new client packet. This includes client information that
2369 * we will use to create initial client ID. After creating new
2370 * ID we will send it to the client.
2372 SILC_LOG_DEBUG(("New Client packet"));
2373 if (packet->flags & SILC_PACKET_FLAG_LIST)
2375 silc_server_new_client(server, sock, packet);
2378 case SILC_PACKET_NEW_SERVER:
2380 * Received new server packet. This includes Server ID and some other
2381 * information that we may save. This is received after server has
2384 SILC_LOG_DEBUG(("New Server packet"));
2385 if (packet->flags & SILC_PACKET_FLAG_LIST)
2387 silc_server_new_server(server, sock, packet);
2390 case SILC_PACKET_NEW_CHANNEL:
2392 * Received new channel packet. Information about new channel in the
2393 * network are distributed using this packet.
2395 SILC_LOG_DEBUG(("New Channel packet"));
2396 if (packet->flags & SILC_PACKET_FLAG_LIST)
2397 silc_server_new_channel_list(server, sock, packet);
2399 silc_server_new_channel(server, sock, packet);
2402 case SILC_PACKET_HEARTBEAT:
2404 * Received heartbeat.
2406 SILC_LOG_DEBUG(("Heartbeat packet"));
2407 if (packet->flags & SILC_PACKET_FLAG_LIST)
2411 case SILC_PACKET_KEY_AGREEMENT:
2413 * Received heartbeat.
2415 SILC_LOG_DEBUG(("Key agreement packet"));
2416 if (packet->flags & SILC_PACKET_FLAG_LIST)
2418 silc_server_key_agreement(server, sock, packet);
2421 case SILC_PACKET_REKEY:
2423 * Received re-key packet. The sender wants to regenerate the session
2426 SILC_LOG_DEBUG(("Re-key packet"));
2427 if (packet->flags & SILC_PACKET_FLAG_LIST)
2429 silc_server_rekey(server, sock, packet);
2432 case SILC_PACKET_REKEY_DONE:
2434 * The re-key is done.
2436 SILC_LOG_DEBUG(("Re-key done packet"));
2437 if (packet->flags & SILC_PACKET_FLAG_LIST)
2440 if (sock->protocol && sock->protocol->protocol &&
2441 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2443 SilcServerRekeyInternalContext *proto_ctx =
2444 (SilcServerRekeyInternalContext *)sock->protocol->context;
2446 if (proto_ctx->packet)
2447 silc_packet_context_free(proto_ctx->packet);
2449 proto_ctx->packet = silc_packet_context_dup(packet);
2451 /* Let the protocol handle the packet */
2452 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2454 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2455 "protocol active, packet dropped."));
2459 case SILC_PACKET_FTP:
2461 SILC_LOG_DEBUG(("FTP packet"));
2462 if (packet->flags & SILC_PACKET_FLAG_LIST)
2464 silc_server_ftp(server, sock, packet);
2467 case SILC_PACKET_RESUME_CLIENT:
2469 SILC_LOG_DEBUG(("Resume Client packet"));
2470 if (packet->flags & SILC_PACKET_FLAG_LIST)
2472 silc_server_resume_client(server, sock, packet);
2475 case SILC_PACKET_RESUME_ROUTER:
2476 /* Resume router packet received. This packet is received for backup
2477 router resuming protocol. */
2478 SILC_LOG_DEBUG(("Resume router packet"));
2479 if (packet->flags & SILC_PACKET_FLAG_LIST)
2481 silc_server_backup_resume_router(server, sock, packet);
2485 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2491 /* Creates connection to a remote router. */
2493 void silc_server_create_connection(SilcServer server,
2494 const char *remote_host, SilcUInt32 port)
2496 SilcServerConnection sconn;
2498 /* Allocate connection object for hold connection specific stuff. */
2499 sconn = silc_calloc(1, sizeof(*sconn));
2500 sconn->server = server;
2501 sconn->remote_host = strdup(remote_host);
2502 sconn->remote_port = port;
2503 sconn->no_reconnect = TRUE;
2505 silc_schedule_task_add(server->schedule, 0,
2506 silc_server_connect_router,
2507 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
2508 SILC_TASK_PRI_NORMAL);
2511 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2513 silc_socket_free((SilcSocketConnection)context);
2516 /* Closes connection to socket connection */
2518 void silc_server_close_connection(SilcServer server,
2519 SilcSocketConnection sock)
2521 if (!server->sockets[sock->sock])
2524 SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2526 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2527 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2528 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2531 /* We won't listen for this connection anymore */
2532 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2534 /* Unregister all tasks */
2535 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2537 /* Close the actual connection */
2538 silc_net_close_connection(sock->sock);
2539 server->sockets[sock->sock] = NULL;
2541 /* If sock->user_data is NULL then we'll check for active protocols
2542 here since the silc_server_free_sock_user_data has not been called
2543 for this connection. */
2544 if (!sock->user_data) {
2545 /* If any protocol is active cancel its execution. It will call
2546 the final callback which will finalize the disconnection. */
2547 if (sock->protocol) {
2548 silc_protocol_cancel(sock->protocol, server->schedule);
2549 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2550 silc_protocol_execute_final(sock->protocol, server->schedule);
2551 sock->protocol = NULL;
2556 silc_schedule_task_add(server->schedule, 0,
2557 silc_server_close_connection_final,
2558 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
2559 SILC_TASK_PRI_NORMAL);
2562 /* Sends disconnect message to remote connection and disconnects the
2565 void silc_server_disconnect_remote(SilcServer server,
2566 SilcSocketConnection sock,
2567 SilcStatus status, ...)
2570 unsigned char buf[512];
2578 memset(buf, 0, sizeof(buf));
2579 va_start(ap, status);
2580 cp = va_arg(ap, char *);
2582 vsnprintf(buf, sizeof(buf) - 1, cp, ap);
2587 SILC_LOG_DEBUG(("Disconnecting remote host"));
2589 /* Notify remote end that the conversation is over. The notify message
2590 is tried to be sent immediately. */
2594 len += silc_utf8_encoded_len(buf, strlen(buf), SILC_STRING_ASCII);
2596 buffer = silc_buffer_alloc_size(len);
2600 buffer->data[0] = status;
2602 silc_utf8_encode(buf, strlen(buf), SILC_STRING_ASCII, buffer->data + 1,
2604 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
2605 buffer->data, buffer->len, TRUE);
2606 silc_buffer_free(buffer);
2609 silc_server_packet_queue_purge(server, sock);
2611 /* Mark the connection to be disconnected */
2612 SILC_SET_DISCONNECTED(sock);
2613 silc_server_close_connection(server, sock);
2618 SilcClientEntry client;
2619 } *FreeClientInternal;
2621 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2623 FreeClientInternal i = (FreeClientInternal)context;
2625 silc_idlist_del_data(i->client);
2626 silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2630 /* Frees client data and notifies about client's signoff. */
2632 void silc_server_free_client_data(SilcServer server,
2633 SilcSocketConnection sock,
2634 SilcClientEntry client,
2636 const char *signoff)
2638 FreeClientInternal i = silc_calloc(1, sizeof(*i));
2640 /* If there is pending outgoing data for the client then purge it
2641 to the network before removing the client entry. */
2642 silc_server_packet_queue_purge(server, sock);
2645 /* Check if anyone is watching this nickname */
2646 if (server->server_type == SILC_ROUTER)
2647 silc_server_check_watcher_list(server, client, NULL,
2648 SILC_NOTIFY_TYPE_SIGNOFF);
2650 /* Send SIGNOFF notify to routers. */
2651 if (notify && !server->standalone && server->router)
2652 silc_server_send_notify_signoff(server, server->router->connection,
2653 server->server_type == SILC_SERVER ?
2654 FALSE : TRUE, client->id, signoff);
2656 /* Remove client from all channels */
2658 silc_server_remove_from_channels(server, NULL, client,
2659 TRUE, (char *)signoff, TRUE);
2661 silc_server_remove_from_channels(server, NULL, client,
2662 FALSE, NULL, FALSE);
2664 /* Remove this client from watcher list if it is */
2665 silc_server_del_from_watcher_list(server, client);
2668 /* Update statistics */
2669 server->stat.my_clients--;
2670 server->stat.clients--;
2671 if (server->stat.cell_clients)
2672 server->stat.cell_clients--;
2673 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2674 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2675 silc_schedule_task_del_by_context(server->schedule, client);
2677 /* We will not delete the client entry right away. We will take it
2678 into history (for WHOWAS command) for 5 minutes */
2681 silc_schedule_task_add(server->schedule, 0,
2682 silc_server_free_client_data_timeout,
2684 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2685 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2687 client->router = NULL;
2688 client->connection = NULL;
2691 /* Frees user_data pointer from socket connection object. This also sends
2692 appropriate notify packets to the network to inform about leaving
2695 void silc_server_free_sock_user_data(SilcServer server,
2696 SilcSocketConnection sock,
2697 const char *signoff_message)
2699 SILC_LOG_DEBUG(("Start"));
2701 switch (sock->type) {
2702 case SILC_SOCKET_TYPE_CLIENT:
2704 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2705 silc_server_free_client_data(server, sock, user_data, TRUE,
2709 case SILC_SOCKET_TYPE_SERVER:
2710 case SILC_SOCKET_TYPE_ROUTER:
2712 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2713 SilcServerEntry backup_router = NULL;
2716 backup_router = silc_server_backup_get(server, user_data->id);
2718 /* If this was our primary router connection then we're lost to
2719 the outside world. */
2720 if (server->router == user_data) {
2721 /* Check whether we have a backup router connection */
2722 if (!backup_router || backup_router == user_data) {
2723 silc_schedule_task_add(server->schedule, 0,
2724 silc_server_connect_to_router,
2727 SILC_TASK_PRI_NORMAL);
2729 server->id_entry->router = NULL;
2730 server->router = NULL;
2731 server->standalone = TRUE;
2732 backup_router = NULL;
2734 SILC_LOG_INFO(("New primary router is backup router %s",
2735 backup_router->server_name));
2736 SILC_LOG_DEBUG(("New primary router is backup router %s",
2737 backup_router->server_name));
2738 #ifdef BACKUP_SINGLE_ROUTER
2739 if (server->id_entry != backup_router) {
2740 #endif /* BACKUP_SINGLE_ROUTER */
2741 server->id_entry->router = backup_router;
2742 server->router = backup_router;
2743 server->router_connect = time(0);
2744 server->backup_primary = TRUE;
2745 #ifdef BACKUP_SINGLE_ROUTER
2747 server->id_entry->router = NULL;
2748 server->router = NULL;
2749 server->standalone = TRUE;
2751 #endif /* BACKUP_SINGLE_ROUTER */
2753 if (server->server_type == SILC_BACKUP_ROUTER) {
2754 server->server_type = SILC_ROUTER;
2756 /* We'll need to constantly try to reconnect to the primary
2757 router so that we'll see when it comes back online. */
2758 silc_server_backup_reconnect(server, sock->ip, sock->port,
2759 silc_server_backup_connected,
2763 /* Mark this connection as replaced */
2764 silc_server_backup_replaced_add(server, user_data->id,
2767 } else if (backup_router) {
2768 SILC_LOG_INFO(("Enabling the use of backup router %s",
2769 backup_router->server_name));
2770 SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2771 backup_router->server_name));
2773 /* Mark this connection as replaced */
2774 silc_server_backup_replaced_add(server, user_data->id,
2778 if (!backup_router) {
2779 /* Free all client entries that this server owns as they will
2780 become invalid now as well. */
2782 silc_server_remove_clients_by_server(server, user_data, TRUE);
2783 if (server->server_type == SILC_SERVER)
2784 silc_server_remove_channels_by_server(server, user_data);
2786 /* Update the client entries of this server to the new backup
2787 router. This also removes the clients that *really* was owned
2788 by the primary router and went down with the router. */
2789 silc_server_update_clients_by_server(server, user_data, backup_router,
2791 silc_server_update_servers_by_server(server, user_data, backup_router);
2792 if (server->server_type == SILC_SERVER)
2793 silc_server_update_channels_by_server(server, user_data,
2797 /* Free the server entry */
2798 silc_server_backup_del(server, user_data);
2799 silc_server_backup_replaced_del(server, user_data);
2800 silc_idlist_del_data(user_data);
2801 if (!silc_idlist_del_server(server->local_list, user_data))
2802 silc_idlist_del_server(server->global_list, user_data);
2803 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2804 server->stat.my_servers--;
2806 server->stat.my_routers--;
2807 server->stat.routers--;
2809 server->stat.servers--;
2810 if (server->server_type == SILC_ROUTER)
2811 server->stat.cell_servers--;
2813 if (backup_router) {
2814 /* Announce all of our stuff that was created about 5 minutes ago.
2815 The backup router knows all the other stuff already. */
2816 if (server->server_type == SILC_ROUTER)
2817 silc_server_announce_servers(server, FALSE, time(0) - 300,
2818 backup_router->connection);
2820 /* Announce our clients and channels to the router */
2821 silc_server_announce_clients(server, time(0) - 300,
2822 backup_router->connection);
2823 silc_server_announce_channels(server, time(0) - 300,
2824 backup_router->connection);
2830 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2832 silc_idlist_del_data(user_data);
2833 silc_free(user_data);
2838 /* If any protocol is active cancel its execution */
2839 if (sock->protocol) {
2840 silc_protocol_cancel(sock->protocol, server->schedule);
2841 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2842 silc_protocol_execute_final(sock->protocol, server->schedule);
2843 sock->protocol = NULL;
2846 sock->user_data = NULL;
2849 /* Removes client from all channels it has joined. This is used when client
2850 connection is disconnected. If the client on a channel is last, the
2851 channel is removed as well. This sends the SIGNOFF notify types. */
2853 void silc_server_remove_from_channels(SilcServer server,
2854 SilcSocketConnection sock,
2855 SilcClientEntry client,
2857 const char *signoff_message,
2860 SilcChannelEntry channel;
2861 SilcChannelClientEntry chl;
2862 SilcHashTableList htl;
2865 SILC_LOG_DEBUG(("Start"));
2867 if (!client || !client->id)
2870 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2874 /* Remove the client from all channels. The client is removed from
2875 the channels' user list. */
2876 silc_hash_table_list(client->channels, &htl);
2877 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2878 channel = chl->channel;
2880 /* Remove channel if this is last client leaving the channel, unless
2881 the channel is permanent. */
2882 if (server->server_type == SILC_ROUTER &&
2883 silc_hash_table_count(channel->user_list) < 2) {
2884 silc_server_channel_delete(server, channel);
2888 silc_hash_table_del(client->channels, channel);
2889 silc_hash_table_del(channel->user_list, chl->client);
2890 channel->user_count--;
2892 /* If there is no global users on the channel anymore mark the channel
2893 as local channel. Do not check if the removed client is local client. */
2894 if (server->server_type != SILC_ROUTER && channel->global_users &&
2895 chl->client->router && !silc_server_channel_has_global(channel))
2896 channel->global_users = FALSE;
2900 /* Update statistics */
2901 if (client->connection)
2902 server->stat.my_chanclients--;
2903 if (server->server_type == SILC_ROUTER) {
2904 server->stat.cell_chanclients--;
2905 server->stat.chanclients--;
2908 /* If there is not at least one local user on the channel then we don't
2909 need the channel entry anymore, we can remove it safely, unless the
2910 channel is permanent channel */
2911 if (server->server_type != SILC_ROUTER &&
2912 !silc_server_channel_has_local(channel)) {
2913 /* Notify about leaving client if this channel has global users. */
2914 if (notify && channel->global_users)
2915 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2916 SILC_NOTIFY_TYPE_SIGNOFF,
2917 signoff_message ? 2 : 1,
2918 clidp->data, clidp->len,
2919 signoff_message, signoff_message ?
2920 strlen(signoff_message) : 0);
2922 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2923 silc_server_channel_delete(server, channel);
2927 /* Send notify to channel about client leaving SILC and channel too */
2929 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2930 SILC_NOTIFY_TYPE_SIGNOFF,
2931 signoff_message ? 2 : 1,
2932 clidp->data, clidp->len,
2933 signoff_message, signoff_message ?
2934 strlen(signoff_message) : 0);
2936 /* Re-generate channel key if needed */
2937 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2938 if (!silc_server_create_channel_key(server, channel, 0))
2941 /* Send the channel key to the channel. The key of course is not sent
2942 to the client who was removed from the channel. */
2943 silc_server_send_channel_key(server, client->connection, channel,
2944 server->server_type == SILC_ROUTER ?
2945 FALSE : !server->standalone);
2949 silc_hash_table_list_reset(&htl);
2950 silc_buffer_free(clidp);
2953 /* Removes client from one channel. This is used for example when client
2954 calls LEAVE command to remove itself from the channel. Returns TRUE
2955 if channel still exists and FALSE if the channel is removed when
2956 last client leaves the channel. If `notify' is FALSE notify messages
2959 bool silc_server_remove_from_one_channel(SilcServer server,
2960 SilcSocketConnection sock,
2961 SilcChannelEntry channel,
2962 SilcClientEntry client,
2965 SilcChannelClientEntry chl;
2968 SILC_LOG_DEBUG(("Removing %s from channel %s",
2969 silc_id_render(client->id, SILC_ID_CLIENT),
2970 channel->channel_name));
2972 /* Get the entry to the channel, if this client is not on the channel
2974 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2977 /* Remove channel if this is last client leaving the channel, unless
2978 the channel is permanent. */
2979 if (server->server_type == SILC_ROUTER &&
2980 silc_hash_table_count(channel->user_list) < 2) {
2981 silc_server_channel_delete(server, channel);
2985 silc_hash_table_del(client->channels, chl->channel);
2986 silc_hash_table_del(channel->user_list, chl->client);
2987 channel->user_count--;
2989 /* If there is no global users on the channel anymore mark the channel
2990 as local channel. Do not check if the client is local client. */
2991 if (server->server_type != SILC_ROUTER && channel->global_users &&
2992 chl->client->router && !silc_server_channel_has_global(channel))
2993 channel->global_users = FALSE;
2997 /* Update statistics */
2998 if (client->connection)
2999 server->stat.my_chanclients--;
3000 if (server->server_type == SILC_ROUTER) {
3001 server->stat.cell_chanclients--;
3002 server->stat.chanclients--;
3005 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3009 /* If there is not at least one local user on the channel then we don't
3010 need the channel entry anymore, we can remove it safely, unless the
3011 channel is permanent channel */
3012 if (server->server_type != SILC_ROUTER &&
3013 !silc_server_channel_has_local(channel)) {
3014 /* Notify about leaving client if this channel has global users. */
3015 if (notify && channel->global_users)
3016 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
3017 SILC_NOTIFY_TYPE_LEAVE, 1,
3018 clidp->data, clidp->len);
3020 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3021 silc_server_channel_delete(server, channel);
3022 silc_buffer_free(clidp);
3026 /* Send notify to channel about client leaving the channel */
3028 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
3029 SILC_NOTIFY_TYPE_LEAVE, 1,
3030 clidp->data, clidp->len);
3032 silc_buffer_free(clidp);
3036 /* Timeout callback. This is called if connection is idle or for some
3037 other reason is not responding within some period of time. This
3038 disconnects the remote end. */
3040 SILC_TASK_CALLBACK(silc_server_timeout_remote)
3042 SilcServer server = (SilcServer)context;
3043 SilcSocketConnection sock = server->sockets[fd];
3044 SilcProtocolType protocol = 0;
3046 SILC_LOG_DEBUG(("Start"));
3051 SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
3052 sock->hostname, sock->ip));
3054 /* If we have protocol active we must assure that we call the protocol's
3055 final callback so that all the memory is freed. */
3056 if (sock->protocol) {
3057 protocol = sock->protocol->protocol->type;
3058 silc_protocol_cancel(sock->protocol, server->schedule);
3059 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3060 silc_protocol_execute_final(sock->protocol, server->schedule);
3061 sock->protocol = NULL;
3065 if (sock->user_data)
3066 silc_server_free_sock_user_data(server, sock, NULL);
3068 silc_server_disconnect_remote(server, sock,
3070 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3071 SILC_STATUS_ERR_AUTH_FAILED :
3072 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3073 "Connection timeout");
3076 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3077 function may be used only by router. In real SILC network all channels
3078 are created by routers thus this function is never used by normal
3081 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3082 SilcServerID *router_id,
3088 SilcChannelID *channel_id;
3089 SilcChannelEntry entry;
3093 SILC_LOG_DEBUG(("Creating new channel"));
3096 cipher = SILC_DEFAULT_CIPHER;
3098 hmac = SILC_DEFAULT_HMAC;
3100 /* Allocate cipher */
3101 if (!silc_cipher_alloc(cipher, &key))
3105 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3106 silc_cipher_free(key);
3110 channel_name = strdup(channel_name);
3112 /* Create the channel ID */
3113 if (!silc_id_create_channel_id(server, router_id, server->rng,
3115 silc_free(channel_name);
3116 silc_cipher_free(key);
3117 silc_hmac_free(newhmac);
3121 /* Create the channel */
3122 entry = silc_idlist_add_channel(server->local_list, channel_name,
3123 SILC_CHANNEL_MODE_NONE, channel_id,
3124 NULL, key, newhmac, 0);
3126 silc_free(channel_name);
3127 silc_cipher_free(key);
3128 silc_hmac_free(newhmac);
3129 silc_free(channel_id);
3133 entry->cipher = strdup(cipher);
3134 entry->hmac_name = strdup(hmac);
3136 /* Now create the actual key material */
3137 if (!silc_server_create_channel_key(server, entry,
3138 silc_cipher_get_key_len(key) / 8)) {
3139 silc_idlist_del_channel(server->local_list, entry);
3143 /* Notify other routers about the new channel. We send the packet
3144 to our primary route. */
3145 if (broadcast && server->standalone == FALSE)
3146 silc_server_send_new_channel(server, server->router->connection, TRUE,
3147 channel_name, entry->id,
3148 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3151 /* Distribute to backup routers */
3152 if (broadcast && server->server_type == SILC_ROUTER) {
3155 SilcUInt32 name_len = strlen(channel_name);
3156 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
3157 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
3159 packet = silc_channel_payload_encode(channel_name, name_len,
3160 cid, channel_id_len, entry->mode);
3161 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3162 packet->data, packet->len, FALSE, TRUE);
3164 silc_buffer_free(packet);
3167 server->stat.my_channels++;
3168 if (server->server_type == SILC_ROUTER) {
3169 server->stat.channels++;
3170 server->stat.cell_channels++;
3171 entry->users_resolved = TRUE;
3177 /* Same as above but creates the channel with Channel ID `channel_id. */
3180 silc_server_create_new_channel_with_id(SilcServer server,
3184 SilcChannelID *channel_id,
3187 SilcChannelEntry entry;
3191 SILC_LOG_DEBUG(("Creating new channel"));
3194 cipher = SILC_DEFAULT_CIPHER;
3196 hmac = SILC_DEFAULT_HMAC;
3198 /* Allocate cipher */
3199 if (!silc_cipher_alloc(cipher, &key))
3203 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3204 silc_cipher_free(key);
3208 channel_name = strdup(channel_name);
3210 /* Create the channel */
3211 entry = silc_idlist_add_channel(server->local_list, channel_name,
3212 SILC_CHANNEL_MODE_NONE, channel_id,
3213 NULL, key, newhmac, 0);
3215 silc_cipher_free(key);
3216 silc_hmac_free(newhmac);
3217 silc_free(channel_name);
3221 /* Now create the actual key material */
3222 if (!silc_server_create_channel_key(server, entry,
3223 silc_cipher_get_key_len(key) / 8)) {
3224 silc_idlist_del_channel(server->local_list, entry);
3228 /* Notify other routers about the new channel. We send the packet
3229 to our primary route. */
3230 if (broadcast && server->standalone == FALSE)
3231 silc_server_send_new_channel(server, server->router->connection, TRUE,
3232 channel_name, entry->id,
3233 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3236 /* Distribute to backup routers */
3237 if (broadcast && server->server_type == SILC_ROUTER) {
3240 SilcUInt32 name_len = strlen(channel_name);
3241 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
3242 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
3244 packet = silc_channel_payload_encode(channel_name, name_len,
3245 cid, channel_id_len, entry->mode);
3246 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3247 packet->data, packet->len, FALSE, TRUE);
3249 silc_buffer_free(packet);
3252 server->stat.my_channels++;
3253 if (server->server_type == SILC_ROUTER) {
3254 server->stat.channels++;
3255 server->stat.cell_channels++;
3256 entry->users_resolved = TRUE;
3262 /* Channel's key re-key timeout callback. */
3264 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3266 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3267 SilcServer server = (SilcServer)rekey->context;
3271 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3274 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3277 /* Generates new channel key. This is used to create the initial channel key
3278 but also to re-generate new key for channel. If `key_len' is provided
3279 it is the bytes of the key length. */
3281 bool silc_server_create_channel_key(SilcServer server,
3282 SilcChannelEntry channel,
3286 unsigned char channel_key[32], hash[32];
3289 SILC_LOG_DEBUG(("Generating channel key"));
3291 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3292 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3296 if (!channel->channel_key)
3297 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
3298 channel->channel_key = NULL;
3304 else if (channel->key_len)
3305 len = channel->key_len / 8;
3307 len = silc_cipher_get_key_len(channel->channel_key) / 8;
3309 /* Create channel key */
3310 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3313 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
3315 /* Remove old key if exists */
3317 memset(channel->key, 0, channel->key_len / 8);
3318 silc_free(channel->key);
3322 channel->key_len = len * 8;
3323 channel->key = silc_memdup(channel_key, len);
3324 memset(channel_key, 0, sizeof(channel_key));
3326 /* Generate HMAC key from the channel key data and set it */
3328 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3329 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3330 silc_hmac_set_key(channel->hmac, hash,
3331 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3332 memset(hash, 0, sizeof(hash));
3334 if (server->server_type == SILC_ROUTER) {
3335 if (!channel->rekey)
3336 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3337 channel->rekey->context = (void *)server;
3338 channel->rekey->channel = channel;
3339 channel->rekey->key_len = key_len;
3340 if (channel->rekey->task)
3341 silc_schedule_task_del(server->schedule, channel->rekey->task);
3343 channel->rekey->task =
3344 silc_schedule_task_add(server->schedule, 0,
3345 silc_server_channel_key_rekey,
3346 (void *)channel->rekey,
3347 server->config->channel_rekey_secs, 0,
3349 SILC_TASK_PRI_NORMAL);
3355 /* Saves the channel key found in the encoded `key_payload' buffer. This
3356 function is used when we receive Channel Key Payload and also when we're
3357 processing JOIN command reply. Returns entry to the channel. */
3359 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3360 SilcBuffer key_payload,
3361 SilcChannelEntry channel)
3363 SilcChannelKeyPayload payload = NULL;
3364 SilcChannelID *id = NULL;
3365 unsigned char *tmp, hash[32];
3369 SILC_LOG_DEBUG(("Start"));
3371 /* Decode channel key payload */
3372 payload = silc_channel_key_payload_parse(key_payload->data,
3375 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3380 /* Get the channel entry */
3383 /* Get channel ID */
3384 tmp = silc_channel_key_get_id(payload, &tmp_len);
3385 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
3391 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
3393 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
3395 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3396 silc_id_render(id, SILC_ID_CHANNEL)));
3402 tmp = silc_channel_key_get_key(payload, &tmp_len);
3408 cipher = silc_channel_key_get_cipher(payload, NULL);
3414 /* Remove old key if exists */
3416 memset(channel->key, 0, channel->key_len / 8);
3417 silc_free(channel->key);
3418 silc_cipher_free(channel->channel_key);
3421 /* Create new cipher */
3422 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3423 channel->channel_key = NULL;
3428 if (channel->cipher)
3429 silc_free(channel->cipher);
3430 channel->cipher = strdup(cipher);
3433 channel->key_len = tmp_len * 8;
3434 channel->key = silc_memdup(tmp, tmp_len);
3435 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3437 /* Generate HMAC key from the channel key data and set it */
3439 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3440 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3441 silc_hmac_set_key(channel->hmac, hash,
3442 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3444 memset(hash, 0, sizeof(hash));
3445 memset(tmp, 0, tmp_len);
3447 if (server->server_type == SILC_ROUTER) {
3448 if (!channel->rekey)
3449 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3450 channel->rekey->context = (void *)server;
3451 channel->rekey->channel = channel;
3452 if (channel->rekey->task)
3453 silc_schedule_task_del(server->schedule, channel->rekey->task);
3455 channel->rekey->task =
3456 silc_schedule_task_add(server->schedule, 0,
3457 silc_server_channel_key_rekey,
3458 (void *)channel->rekey,
3459 server->config->channel_rekey_secs, 0,
3461 SILC_TASK_PRI_NORMAL);
3467 silc_channel_key_payload_free(payload);
3472 /* Heartbeat callback. This function is set as argument for the
3473 silc_socket_set_heartbeat function. The library will call this function
3474 at the set time interval. */
3476 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3479 SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3481 SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
3483 /* Send the heartbeat */
3484 silc_server_send_heartbeat(hb->server, sock);
3487 /* Returns assembled of all servers in the given ID list. The packet's
3488 form is dictated by the New ID payload. */
3490 static void silc_server_announce_get_servers(SilcServer server,
3491 SilcServerEntry remote,
3493 SilcBuffer *servers,
3494 unsigned long creation_time)
3496 SilcIDCacheList list;
3497 SilcIDCacheEntry id_cache;
3498 SilcServerEntry entry;
3501 /* Go through all clients in the list */
3502 if (silc_idcache_get_all(id_list->servers, &list)) {
3503 if (silc_idcache_list_first(list, &id_cache)) {
3505 entry = (SilcServerEntry)id_cache->context;
3507 /* Do not announce the one we've sending our announcements and
3508 do not announce ourself. Also check the creation time if it's
3510 if ((entry == remote) || (entry == server->id_entry) ||
3511 (creation_time && entry->data.created < creation_time)) {
3512 if (!silc_idcache_list_next(list, &id_cache))
3517 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3519 *servers = silc_buffer_realloc(*servers,
3521 (*servers)->truelen + idp->len :
3523 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3524 silc_buffer_put(*servers, idp->data, idp->len);
3525 silc_buffer_pull(*servers, idp->len);
3526 silc_buffer_free(idp);
3528 if (!silc_idcache_list_next(list, &id_cache))
3533 silc_idcache_list_free(list);
3538 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3544 p = silc_notify_payload_encode(notify, argc, ap);
3550 /* This function is used by router to announce existing servers to our
3551 primary router when we've connected to it. If `creation_time' is non-zero
3552 then only the servers that has been created after the `creation_time'
3553 will be announced. */
3555 void silc_server_announce_servers(SilcServer server, bool global,
3556 unsigned long creation_time,
3557 SilcSocketConnection remote)
3559 SilcBuffer servers = NULL;
3561 SILC_LOG_DEBUG(("Announcing servers"));
3563 /* Get servers in local list */
3564 silc_server_announce_get_servers(server, remote->user_data,
3565 server->local_list, &servers,
3569 /* Get servers in global list */
3570 silc_server_announce_get_servers(server, remote->user_data,
3571 server->global_list, &servers,
3575 silc_buffer_push(servers, servers->data - servers->head);
3576 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3578 /* Send the packet */
3579 silc_server_packet_send(server, remote,
3580 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3581 servers->data, servers->len, TRUE);
3583 silc_buffer_free(servers);
3587 /* Returns assembled packet of all clients in the given ID list. The
3588 packet's form is dictated by the New ID Payload. */
3590 static void silc_server_announce_get_clients(SilcServer server,
3592 SilcBuffer *clients,
3594 unsigned long creation_time)
3596 SilcIDCacheList list;
3597 SilcIDCacheEntry id_cache;
3598 SilcClientEntry client;
3601 unsigned char mode[4];
3603 /* Go through all clients in the list */
3604 if (silc_idcache_get_all(id_list->clients, &list)) {
3605 if (silc_idcache_list_first(list, &id_cache)) {
3607 client = (SilcClientEntry)id_cache->context;
3609 if (creation_time && client->data.created < creation_time) {
3610 if (!silc_idcache_list_next(list, &id_cache))
3615 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3617 *clients = silc_buffer_realloc(*clients,
3619 (*clients)->truelen + idp->len :
3621 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3622 silc_buffer_put(*clients, idp->data, idp->len);
3623 silc_buffer_pull(*clients, idp->len);
3625 SILC_PUT32_MSB(client->mode, mode);
3626 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3627 2, idp->data, idp->len,
3629 *umodes = silc_buffer_realloc(*umodes,
3631 (*umodes)->truelen + tmp->len :
3633 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3634 silc_buffer_put(*umodes, tmp->data, tmp->len);
3635 silc_buffer_pull(*umodes, tmp->len);
3636 silc_buffer_free(tmp);
3638 silc_buffer_free(idp);
3640 if (!silc_idcache_list_next(list, &id_cache))
3645 silc_idcache_list_free(list);
3649 /* This function is used to announce our existing clients to our router
3650 when we've connected to it. If `creation_time' is non-zero then only
3651 the clients that has been created after the `creation_time' will be
3654 void silc_server_announce_clients(SilcServer server,
3655 unsigned long creation_time,
3656 SilcSocketConnection remote)
3658 SilcBuffer clients = NULL;
3659 SilcBuffer umodes = NULL;
3661 SILC_LOG_DEBUG(("Announcing clients"));
3663 /* Get clients in local list */
3664 silc_server_announce_get_clients(server, server->local_list,
3665 &clients, &umodes, creation_time);
3667 /* As router we announce our global list as well */
3668 if (server->server_type == SILC_ROUTER)
3669 silc_server_announce_get_clients(server, server->global_list,
3670 &clients, &umodes, creation_time);
3673 silc_buffer_push(clients, clients->data - clients->head);
3674 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3676 /* Send the packet */
3677 silc_server_packet_send(server, remote,
3678 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3679 clients->data, clients->len, TRUE);
3681 silc_buffer_free(clients);
3685 silc_buffer_push(umodes, umodes->data - umodes->head);
3686 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
3688 /* Send the packet */
3689 silc_server_packet_send(server, remote,
3690 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3691 umodes->data, umodes->len, TRUE);
3693 silc_buffer_free(umodes);
3697 /* Returns channel's topic for announcing it */
3699 void silc_server_announce_get_channel_topic(SilcServer server,
3700 SilcChannelEntry channel,
3705 if (channel->topic) {
3706 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3707 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3708 chidp->data, chidp->len,
3710 strlen(channel->topic));
3711 silc_buffer_free(chidp);
3715 /* Returns assembled packets for channel users of the `channel'. */
3717 void silc_server_announce_get_channel_users(SilcServer server,
3718 SilcChannelEntry channel,
3719 SilcBuffer *channel_modes,
3720 SilcBuffer *channel_users,
3721 SilcBuffer *channel_users_modes)
3723 SilcChannelClientEntry chl;
3724 SilcHashTableList htl;
3725 SilcBuffer chidp, clidp, csidp;
3728 unsigned char mode[4], *fkey = NULL;
3729 SilcUInt32 fkey_len = 0;
3732 SILC_LOG_DEBUG(("Start"));
3734 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3735 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
3738 SILC_PUT32_MSB(channel->mode, mode);
3739 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
3740 if (channel->founder_key)
3741 fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
3743 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
3744 6, csidp->data, csidp->len,
3747 hmac, hmac ? strlen(hmac) : 0,
3748 channel->passphrase,
3749 channel->passphrase ?
3750 strlen(channel->passphrase) : 0,
3754 silc_buffer_realloc(*channel_modes,
3756 (*channel_modes)->truelen + len : len));
3757 silc_buffer_pull_tail(*channel_modes,
3758 ((*channel_modes)->end -
3759 (*channel_modes)->data));
3760 silc_buffer_put(*channel_modes, tmp->data, tmp->len);
3761 silc_buffer_pull(*channel_modes, len);
3762 silc_buffer_free(tmp);
3767 /* Now find all users on the channel */
3768 silc_hash_table_list(channel->user_list, &htl);
3769 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3770 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3773 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
3774 clidp->data, clidp->len,
3775 chidp->data, chidp->len);
3778 silc_buffer_realloc(*channel_users,
3780 (*channel_users)->truelen + len : len));
3781 silc_buffer_pull_tail(*channel_users,
3782 ((*channel_users)->end -
3783 (*channel_users)->data));
3785 silc_buffer_put(*channel_users, tmp->data, tmp->len);
3786 silc_buffer_pull(*channel_users, len);
3787 silc_buffer_free(tmp);
3789 /* CUMODE notify for mode change on the channel */
3790 SILC_PUT32_MSB(chl->mode, mode);
3791 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
3792 fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
3793 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
3794 4, csidp->data, csidp->len,
3796 clidp->data, clidp->len,
3799 *channel_users_modes =
3800 silc_buffer_realloc(*channel_users_modes,
3801 (*channel_users_modes ?
3802 (*channel_users_modes)->truelen + len : len));
3803 silc_buffer_pull_tail(*channel_users_modes,
3804 ((*channel_users_modes)->end -
3805 (*channel_users_modes)->data));
3807 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3808 silc_buffer_pull(*channel_users_modes, len);
3809 silc_buffer_free(tmp);
3813 silc_buffer_free(clidp);
3815 silc_hash_table_list_reset(&htl);
3816 silc_buffer_free(chidp);
3817 silc_buffer_free(csidp);
3820 /* Returns assembled packets for all channels and users on those channels
3821 from the given ID List. The packets are in the form dictated by the
3822 New Channel and New Channel User payloads. */
3824 void silc_server_announce_get_channels(SilcServer server,
3826 SilcBuffer *channels,
3827 SilcBuffer **channel_modes,
3828 SilcBuffer *channel_users,
3829 SilcBuffer **channel_users_modes,
3830 SilcUInt32 *channel_users_modes_c,
3831 SilcBuffer **channel_topics,
3832 SilcChannelID ***channel_ids,
3833 unsigned long creation_time)
3835 SilcIDCacheList list;
3836 SilcIDCacheEntry id_cache;
3837 SilcChannelEntry channel;
3840 SilcUInt16 name_len;
3842 int i = *channel_users_modes_c;
3845 SILC_LOG_DEBUG(("Start"));
3847 /* Go through all channels in the list */
3848 if (silc_idcache_get_all(id_list->channels, &list)) {
3849 if (silc_idcache_list_first(list, &id_cache)) {
3851 channel = (SilcChannelEntry)id_cache->context;
3853 if (creation_time && channel->created < creation_time)
3858 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3859 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3860 name_len = strlen(channel->channel_name);
3863 len = 4 + name_len + id_len + 4;
3865 silc_buffer_realloc(*channels,
3866 (*channels ? (*channels)->truelen +
3868 silc_buffer_pull_tail(*channels,
3869 ((*channels)->end - (*channels)->data));
3870 silc_buffer_format(*channels,
3871 SILC_STR_UI_SHORT(name_len),
3872 SILC_STR_UI_XNSTRING(channel->channel_name,
3874 SILC_STR_UI_SHORT(id_len),
3875 SILC_STR_UI_XNSTRING(cid, id_len),
3876 SILC_STR_UI_INT(channel->mode),
3878 silc_buffer_pull(*channels, len);
3881 /* Channel user modes */
3882 *channel_users_modes = silc_realloc(*channel_users_modes,
3883 sizeof(**channel_users_modes) *
3885 (*channel_users_modes)[i] = NULL;
3886 *channel_modes = silc_realloc(*channel_modes,
3887 sizeof(**channel_modes) * (i + 1));
3888 (*channel_modes)[i] = NULL;
3889 *channel_ids = silc_realloc(*channel_ids,
3890 sizeof(**channel_ids) * (i + 1));
3891 (*channel_ids)[i] = NULL;
3892 silc_server_announce_get_channel_users(server, channel,
3893 &(*channel_modes)[i],
3895 &(*channel_users_modes)[i]);
3896 (*channel_ids)[i] = channel->id;
3898 /* Channel's topic */
3899 *channel_topics = silc_realloc(*channel_topics,
3900 sizeof(**channel_topics) * (i + 1));
3901 (*channel_topics)[i] = NULL;
3902 silc_server_announce_get_channel_topic(server, channel,
3903 &(*channel_topics)[i]);
3906 if (!silc_idcache_list_next(list, &id_cache))
3910 *channel_users_modes_c += i;
3913 silc_idcache_list_free(list);
3917 /* This function is used to announce our existing channels to our router
3918 when we've connected to it. This also announces the users on the
3919 channels to the router. If the `creation_time' is non-zero only the
3920 channels that was created after the `creation_time' are announced.
3921 Note that the channel users are still announced even if the `creation_time'
3924 void silc_server_announce_channels(SilcServer server,
3925 unsigned long creation_time,
3926 SilcSocketConnection remote)
3928 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
3929 SilcBuffer *channel_users_modes = NULL;
3930 SilcBuffer *channel_topics = NULL;
3931 SilcUInt32 channel_users_modes_c = 0;
3932 SilcChannelID **channel_ids = NULL;
3934 SILC_LOG_DEBUG(("Announcing channels and channel users"));
3936 /* Get channels and channel users in local list */
3937 silc_server_announce_get_channels(server, server->local_list,
3938 &channels, &channel_modes,
3940 &channel_users_modes,
3941 &channel_users_modes_c,
3943 &channel_ids, creation_time);
3945 /* Get channels and channel users in global list */
3946 if (server->server_type != SILC_SERVER)
3947 silc_server_announce_get_channels(server, server->global_list,
3948 &channels, &channel_modes,
3950 &channel_users_modes,
3951 &channel_users_modes_c,
3953 &channel_ids, creation_time);
3956 silc_buffer_push(channels, channels->data - channels->head);
3957 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3959 /* Send the packet */
3960 silc_server_packet_send(server, remote,
3961 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3962 channels->data, channels->len,
3965 silc_buffer_free(channels);
3968 if (channel_modes) {
3971 for (i = 0; i < channel_users_modes_c; i++) {
3972 if (!channel_modes[i])
3974 silc_buffer_push(channel_modes[i],
3975 channel_modes[i]->data -
3976 channel_modes[i]->head);
3977 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
3978 channel_modes[i]->len);
3979 silc_server_packet_send_dest(server, remote,
3980 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3981 channel_ids[i], SILC_ID_CHANNEL,
3982 channel_modes[i]->data,
3983 channel_modes[i]->len,
3985 silc_buffer_free(channel_modes[i]);
3987 silc_free(channel_modes);
3990 if (channel_users) {
3991 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3992 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
3993 channel_users->len);
3995 /* Send the packet */
3996 silc_server_packet_send(server, remote,
3997 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3998 channel_users->data, channel_users->len,
4001 silc_buffer_free(channel_users);
4004 if (channel_users_modes) {
4007 for (i = 0; i < channel_users_modes_c; i++) {
4008 if (!channel_users_modes[i])
4010 silc_buffer_push(channel_users_modes[i],
4011 channel_users_modes[i]->data -
4012 channel_users_modes[i]->head);
4013 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4014 channel_users_modes[i]->len);
4015 silc_server_packet_send_dest(server, remote,
4016 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4017 channel_ids[i], SILC_ID_CHANNEL,
4018 channel_users_modes[i]->data,
4019 channel_users_modes[i]->len,
4021 silc_buffer_free(channel_users_modes[i]);
4023 silc_free(channel_users_modes);
4026 if (channel_topics) {
4029 for (i = 0; i < channel_users_modes_c; i++) {
4030 if (!channel_topics[i])
4033 silc_buffer_push(channel_topics[i],
4034 channel_topics[i]->data -
4035 channel_topics[i]->head);
4036 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4037 channel_topics[i]->len);
4038 silc_server_packet_send_dest(server, remote,
4039 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4040 channel_ids[i], SILC_ID_CHANNEL,
4041 channel_topics[i]->data,
4042 channel_topics[i]->len,
4044 silc_buffer_free(channel_topics[i]);
4046 silc_free(channel_topics);
4049 silc_free(channel_ids);
4052 /* Failure timeout callback. If this is called then we will immediately
4053 process the received failure. We always process the failure with timeout
4054 since we do not want to blindly trust to received failure packets.
4055 This won't be called (the timeout is cancelled) if the failure was
4056 bogus (it is bogus if remote does not close the connection after sending
4059 SILC_TASK_CALLBACK(silc_server_failure_callback)
4061 SilcServerFailureContext f = (SilcServerFailureContext)context;
4063 if (f->sock->protocol) {
4064 f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
4065 silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
4071 /* Assembles user list and users mode list from the `channel'. */
4073 bool silc_server_get_users_on_channel(SilcServer server,
4074 SilcChannelEntry channel,
4075 SilcBuffer *user_list,
4076 SilcBuffer *mode_list,
4077 SilcUInt32 *user_count)
4079 SilcChannelClientEntry chl;
4080 SilcHashTableList htl;
4081 SilcBuffer client_id_list;
4082 SilcBuffer client_mode_list;
4084 SilcUInt32 list_count = 0, len = 0;
4086 if (!silc_hash_table_count(channel->user_list))
4089 silc_hash_table_list(channel->user_list, &htl);
4090 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4091 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4092 silc_hash_table_list_reset(&htl);
4094 client_id_list = silc_buffer_alloc(len);
4096 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4097 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
4098 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
4100 silc_hash_table_list(channel->user_list, &htl);
4101 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4103 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4104 silc_buffer_put(client_id_list, idp->data, idp->len);
4105 silc_buffer_pull(client_id_list, idp->len);
4106 silc_buffer_free(idp);
4108 /* Client's mode on channel */
4109 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4110 silc_buffer_pull(client_mode_list, 4);
4114 silc_hash_table_list_reset(&htl);
4115 silc_buffer_push(client_id_list,
4116 client_id_list->data - client_id_list->head);
4117 silc_buffer_push(client_mode_list,
4118 client_mode_list->data - client_mode_list->head);
4120 *user_list = client_id_list;
4121 *mode_list = client_mode_list;
4122 *user_count = list_count;
4126 /* Saves users and their modes to the `channel'. */
4128 void silc_server_save_users_on_channel(SilcServer server,
4129 SilcSocketConnection sock,
4130 SilcChannelEntry channel,
4131 SilcClientID *noadd,
4132 SilcBuffer user_list,
4133 SilcBuffer mode_list,
4134 SilcUInt32 user_count)
4139 SilcClientID *client_id;
4140 SilcClientEntry client;
4141 SilcIDCacheEntry cache;
4142 SilcChannelClientEntry chl;
4145 SILC_LOG_DEBUG(("Start"));
4147 for (i = 0; i < user_count; i++) {
4149 SILC_GET16_MSB(idp_len, user_list->data + 2);
4151 client_id = silc_id_payload_parse_id(user_list->data, idp_len, NULL);
4152 silc_buffer_pull(user_list, idp_len);
4157 SILC_GET32_MSB(mode, mode_list->data);
4158 silc_buffer_pull(mode_list, 4);
4160 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
4161 silc_free(client_id);
4167 /* Check if we have this client cached already. */
4168 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4169 server->server_type, &cache);
4171 client = silc_idlist_find_client_by_id(server->global_list,
4172 client_id, server->server_type,
4177 /* If router did not find such Client ID in its lists then this must
4178 be bogus client or some router in the net is buggy. */
4179 if (server->server_type == SILC_ROUTER) {
4180 silc_free(client_id);
4184 /* We don't have that client anywhere, add it. The client is added
4185 to global list since server didn't have it in the lists so it must be
4187 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4188 silc_id_dup(client_id, SILC_ID_CLIENT),
4189 sock->user_data, NULL, 0);
4191 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4192 silc_free(client_id);
4196 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4198 /* Found, if it is from global list we'll assure that we won't
4199 expire it now that the entry is on channel. */
4204 silc_free(client_id);
4206 if (!silc_server_client_on_channel(client, channel, &chl)) {
4207 /* Client was not on the channel, add it. */
4208 chl = silc_calloc(1, sizeof(*chl));
4209 chl->client = client;
4211 chl->channel = channel;
4212 silc_hash_table_add(channel->user_list, chl->client, chl);
4213 silc_hash_table_add(client->channels, chl->channel, chl);
4214 channel->user_count++;
4222 /* Saves channels and channels user modes to the `client'. Removes
4223 the client from those channels that are not sent in the list but
4226 void silc_server_save_user_channels(SilcServer server,
4227 SilcSocketConnection sock,
4228 SilcClientEntry client,
4229 SilcBuffer channels,
4230 SilcBuffer channels_user_modes)
4233 SilcUInt32 *chumodes;
4234 SilcChannelPayload entry;
4235 SilcChannelEntry channel;
4236 SilcChannelID *channel_id;
4237 SilcChannelClientEntry chl;
4238 SilcHashTable ht = NULL;
4239 SilcHashTableList htl;
4243 if (!channels ||!channels_user_modes)
4246 ch = silc_channel_payload_parse_list(channels->data, channels->len);
4247 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4249 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4250 NULL, NULL, NULL, TRUE);
4251 silc_dlist_start(ch);
4252 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4253 /* Check if we have this channel, and add it if we don't have it.
4254 Also add the client on the channel unless it is there already. */
4255 channel_id = silc_channel_get_id_parse(entry);
4256 channel = silc_idlist_find_channel_by_id(server->local_list,
4259 channel = silc_idlist_find_channel_by_id(server->global_list,
4262 if (server->server_type != SILC_SERVER) {
4263 silc_free(channel_id);
4268 /* We don't have that channel anywhere, add it. */
4269 name = silc_channel_get_name(entry, NULL);
4270 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4271 channel_id, server->router,
4274 silc_free(channel_id);
4281 channel->mode = silc_channel_get_mode(entry);
4283 /* Add the client on the channel */
4284 if (!silc_server_client_on_channel(client, channel, &chl)) {
4285 chl = silc_calloc(1, sizeof(*chl));
4286 chl->client = client;
4287 chl->mode = chumodes[i++];
4288 chl->channel = channel;
4289 silc_hash_table_add(channel->user_list, chl->client, chl);
4290 silc_hash_table_add(client->channels, chl->channel, chl);
4291 channel->user_count++;
4294 chl->mode = chumodes[i++];
4297 silc_hash_table_add(ht, channel, channel);
4298 silc_free(channel_id);
4300 silc_channel_payload_list_free(ch);
4301 silc_free(chumodes);
4305 /* Go through the list again and remove client from channels that
4306 are no part of the list. */
4308 silc_hash_table_list(client->channels, &htl);
4309 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
4310 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4311 silc_hash_table_del(chl->channel->user_list, chl->client);
4312 silc_hash_table_del(chl->client->channels, chl->channel);
4316 silc_hash_table_list_reset(&htl);
4317 silc_hash_table_free(ht);
4319 silc_hash_table_list(client->channels, &htl);
4320 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
4321 silc_hash_table_del(chl->channel->user_list, chl->client);
4322 silc_hash_table_del(chl->client->channels, chl->channel);
4325 silc_hash_table_list_reset(&htl);
4329 /* Lookups route to the client indicated by the `id_data'. The connection
4330 object and internal data object is returned. Returns NULL if route
4331 could not be found to the client. If the `client_id' is specified then
4332 it is used and the `id_data' is ignored. */
4334 SilcSocketConnection
4335 silc_server_get_client_route(SilcServer server,
4336 unsigned char *id_data,
4338 SilcClientID *client_id,
4339 SilcIDListData *idata,
4340 SilcClientEntry *client_entry)
4343 SilcClientEntry client;
4345 SILC_LOG_DEBUG(("Start"));
4348 *client_entry = NULL;
4350 /* Decode destination Client ID */
4352 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
4354 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
4358 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4361 /* If the destination belongs to our server we don't have to route
4362 the packet anywhere but to send it to the local destination. */
4363 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4367 /* If we are router and the client has router then the client is in
4368 our cell but not directly connected to us. */
4369 if (server->server_type == SILC_ROUTER && client->router) {
4370 /* We are of course in this case the client's router thus the route
4371 to the client is the server who owns the client. So, we will send
4372 the packet to that server. */
4374 *idata = (SilcIDListData)client->router;
4375 return client->router->connection;
4378 /* Seems that client really is directly connected to us */
4380 *idata = (SilcIDListData)client;
4382 *client_entry = client;
4383 return client->connection;
4386 /* Destination belongs to someone not in this server. If we are normal
4387 server our action is to send the packet to our router. */
4388 if (server->server_type != SILC_ROUTER && !server->standalone) {
4391 *idata = (SilcIDListData)server->router;
4392 return server->router->connection;
4395 /* We are router and we will perform route lookup for the destination
4396 and send the packet to fastest route. */
4397 if (server->server_type == SILC_ROUTER && !server->standalone) {
4398 /* Check first that the ID is valid */
4399 client = silc_idlist_find_client_by_id(server->global_list, id,
4402 SilcSocketConnection dst_sock;
4404 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4408 *idata = (SilcIDListData)dst_sock->user_data;
4417 /* Encodes and returns channel list of channels the `client' has joined.
4418 Secret channels are not put to the list. */
4420 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4421 SilcClientEntry client,
4424 SilcBuffer *user_mode_list)
4426 SilcBuffer buffer = NULL;
4427 SilcChannelEntry channel;
4428 SilcChannelClientEntry chl;
4429 SilcHashTableList htl;
4432 SilcUInt16 name_len;
4436 *user_mode_list = NULL;
4438 silc_hash_table_list(client->channels, &htl);
4439 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4440 channel = chl->channel;
4442 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4444 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4447 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
4448 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
4449 name_len = strlen(channel->channel_name);
4451 len = 4 + name_len + id_len + 4;
4452 buffer = silc_buffer_realloc(buffer,
4453 (buffer ? buffer->truelen + len : len));
4454 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4455 silc_buffer_format(buffer,
4456 SILC_STR_UI_SHORT(name_len),
4457 SILC_STR_UI_XNSTRING(channel->channel_name,
4459 SILC_STR_UI_SHORT(id_len),
4460 SILC_STR_UI_XNSTRING(cid, id_len),
4461 SILC_STR_UI_INT(chl->channel->mode),
4463 silc_buffer_pull(buffer, len);
4466 if (user_mode_list) {
4467 *user_mode_list = silc_buffer_realloc(*user_mode_list,
4469 (*user_mode_list)->truelen + 4 :
4471 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
4472 (*user_mode_list)->data));
4473 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
4474 silc_buffer_pull(*user_mode_list, 4);
4477 silc_hash_table_list_reset(&htl);
4480 silc_buffer_push(buffer, buffer->data - buffer->head);
4481 if (user_mode_list && *user_mode_list)
4482 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
4483 (*user_mode_list)->head));
4488 /* Finds client entry by Client ID and if it is not found then resolves
4489 it using WHOIS command. */
4491 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
4492 SilcClientID *client_id,
4493 bool always_resolve,
4496 SilcClientEntry client;
4501 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4504 client = silc_idlist_find_client_by_id(server->global_list,
4505 client_id, TRUE, NULL);
4506 if (!client && server->server_type == SILC_ROUTER)
4510 if (!client && server->standalone)
4513 if (!client || !client->nickname || !client->username ||
4515 SilcBuffer buffer, idp;
4518 client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
4519 client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
4520 client->resolve_cmd_ident = ++server->cmd_ident;
4523 idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
4524 buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
4525 server->cmd_ident, 1,
4526 4, idp->data, idp->len);
4527 silc_server_packet_send(server, client ? client->router->connection :
4528 server->router->connection,
4529 SILC_PACKET_COMMAND, 0,
4530 buffer->data, buffer->len, FALSE);
4531 silc_buffer_free(idp);
4532 silc_buffer_free(buffer);
4543 /* A timeout callback for the re-key. We will be the initiator of the
4546 SILC_TASK_CALLBACK(silc_server_rekey_callback)
4548 SilcSocketConnection sock = (SilcSocketConnection)context;
4549 SilcIDListData idata = (SilcIDListData)sock->user_data;
4550 SilcServer server = (SilcServer)idata->rekey->context;
4551 SilcProtocol protocol;
4552 SilcServerRekeyInternalContext *proto_ctx;
4554 SILC_LOG_DEBUG(("Start"));
4556 /* Allocate internal protocol context. This is sent as context
4558 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
4559 proto_ctx->server = (void *)server;
4560 proto_ctx->sock = sock;
4561 proto_ctx->responder = FALSE;
4562 proto_ctx->pfs = idata->rekey->pfs;
4564 /* Perform rekey protocol. Will call the final callback after the
4565 protocol is over. */
4566 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
4567 &protocol, proto_ctx, silc_server_rekey_final);
4568 sock->protocol = protocol;
4570 /* Run the protocol */
4571 silc_protocol_execute(protocol, server->schedule, 0, 0);
4573 /* Re-register re-key timeout */
4574 silc_schedule_task_add(server->schedule, sock->sock,
4575 silc_server_rekey_callback,
4576 context, idata->rekey->timeout, 0,
4577 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
4580 /* The final callback for the REKEY protocol. This will actually take the
4581 new key material into use. */
4583 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
4585 SilcProtocol protocol = (SilcProtocol)context;
4586 SilcServerRekeyInternalContext *ctx =
4587 (SilcServerRekeyInternalContext *)protocol->context;
4588 SilcServer server = (SilcServer)ctx->server;
4589 SilcSocketConnection sock = ctx->sock;
4591 SILC_LOG_DEBUG(("Start"));
4593 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
4594 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
4595 /* Error occured during protocol */
4596 SILC_LOG_ERROR(("Error occurred during rekey protocol"));
4597 silc_protocol_cancel(protocol, server->schedule);
4598 silc_protocol_free(protocol);
4599 sock->protocol = NULL;
4601 silc_packet_context_free(ctx->packet);
4603 silc_ske_free(ctx->ske);
4608 /* Purge the outgoing data queue to assure that all rekey packets really
4609 go to the network before we quit the protocol. */
4610 silc_server_packet_queue_purge(server, sock);
4613 silc_protocol_free(protocol);
4614 sock->protocol = NULL;
4616 silc_packet_context_free(ctx->packet);
4618 silc_ske_free(ctx->ske);
4622 /* Task callback used to retrieve network statistical information from
4623 router server once in a while. */
4625 SILC_TASK_CALLBACK(silc_server_get_stats)
4627 SilcServer server = (SilcServer)context;
4628 SilcBuffer idp, packet;
4630 SILC_LOG_DEBUG(("Retrieving stats from router"));
4632 if (!server->standalone) {
4633 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
4634 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
4635 ++server->cmd_ident, 1,
4636 1, idp->data, idp->len);
4637 silc_server_packet_send(server, server->router->connection,
4638 SILC_PACKET_COMMAND, 0, packet->data,
4639 packet->len, FALSE);
4640 silc_buffer_free(packet);
4641 silc_buffer_free(idp);
4644 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
4645 server, 120, 0, SILC_TASK_TIMEOUT,