5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2004 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 * This is the actual SILC server than handles everything relating to
21 * servicing the SILC connections. This is also a SILC router as a router
22 * is also normal server.
26 #include "serverincludes.h"
27 #include "server_internal.h"
29 /* Static prototypes */
30 SILC_TASK_CALLBACK(silc_server_rehash_close_connection);
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_second);
34 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
35 SILC_TASK_CALLBACK(silc_server_accept_new_connection);
36 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second);
37 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final);
38 SILC_TASK_CALLBACK(silc_server_packet_process);
39 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
40 SILC_TASK_CALLBACK(silc_server_close_connection_final);
41 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout);
42 SILC_TASK_CALLBACK(silc_server_timeout_remote);
43 SILC_TASK_CALLBACK(silc_server_channel_key_rekey);
44 SILC_TASK_CALLBACK(silc_server_get_stats);
45 SILC_TASK_CALLBACK(silc_server_connect_router);
47 /* Allocates a new SILC server object. This has to be done before the server
48 can be used. After allocation one must call silc_server_init to initialize
49 the server. The new allocated server object is returned to the new_server
52 int silc_server_alloc(SilcServer *new_server)
56 SILC_LOG_DEBUG(("Allocating new server object"));
58 server = silc_calloc(1, sizeof(*server));
59 server->server_type = SILC_SERVER;
60 server->standalone = TRUE;
61 server->local_list = silc_calloc(1, sizeof(*server->local_list));
62 server->global_list = silc_calloc(1, sizeof(*server->global_list));
63 server->pending_commands = silc_dlist_init();
65 server->sim = silc_dlist_init();
73 /* Free's the SILC server object. This is called at the very end before
76 void silc_server_free(SilcServer server)
79 SilcIDCacheEntry cache;
87 silc_dlist_start(server->sim);
88 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
89 silc_dlist_del(server->sim, sim);
93 silc_dlist_uninit(server->sim);
97 silc_server_backup_free(server);
98 silc_server_config_unref(&server->config_ref);
100 silc_rng_free(server->rng);
102 silc_pkcs_free(server->pkcs);
103 if (server->public_key)
104 silc_pkcs_public_key_free(server->public_key);
105 if (server->private_key)
106 silc_pkcs_private_key_free(server->private_key);
107 if (server->pending_commands)
108 silc_dlist_uninit(server->pending_commands);
109 if (server->id_entry)
110 silc_idlist_del_server(server->local_list, server->id_entry);
112 /* Delete all channels */
114 if (silc_idcache_get_all(server->local_list->channels, &list) &&
115 silc_idcache_list_first(list, &cache)) {
116 silc_idlist_del_channel(server->local_list, cache->context);
117 while (silc_idcache_list_next(list, &cache))
118 silc_idlist_del_channel(server->local_list, cache->context);
121 silc_idcache_list_free(list);
123 if (silc_idcache_get_all(server->global_list->channels, &list) &&
124 silc_idcache_list_first(list, &cache)) {
125 silc_idlist_del_channel(server->global_list, cache->context);
126 while (silc_idcache_list_next(list, &cache))
127 silc_idlist_del_channel(server->global_list, cache->context);
130 silc_idcache_list_free(list);
133 silc_hash_table_free(server->pk_hash);
135 /* Delete all clients */
137 if (silc_idcache_get_all(server->local_list->clients, &list) &&
138 silc_idcache_list_first(list, &cache)) {
139 silc_idlist_del_client(server->local_list, cache->context);
140 while (silc_idcache_list_next(list, &cache))
141 silc_idlist_del_client(server->local_list, cache->context);
144 silc_idcache_list_free(list);
146 if (silc_idcache_get_all(server->global_list->clients, &list) &&
147 silc_idcache_list_first(list, &cache)) {
148 silc_idlist_del_client(server->global_list, cache->context);
149 while (silc_idcache_list_next(list, &cache))
150 silc_idlist_del_client(server->global_list, cache->context);
153 silc_idcache_list_free(list);
156 /* Delete all servers */
158 if (silc_idcache_get_all(server->local_list->servers, &list) &&
159 silc_idcache_list_first(list, &cache)) {
160 silc_idlist_del_server(server->local_list, cache->context);
161 while (silc_idcache_list_next(list, &cache))
162 silc_idlist_del_server(server->local_list, cache->context);
165 silc_idcache_list_free(list);
167 if (silc_idcache_get_all(server->global_list->servers, &list) &&
168 silc_idcache_list_first(list, &cache)) {
169 silc_idlist_del_server(server->global_list, cache->context);
170 while (silc_idcache_list_next(list, &cache))
171 silc_idlist_del_server(server->global_list, cache->context);
174 silc_idcache_list_free(list);
176 silc_idcache_free(server->local_list->clients);
177 silc_idcache_free(server->local_list->servers);
178 silc_idcache_free(server->local_list->channels);
179 silc_idcache_free(server->global_list->clients);
180 silc_idcache_free(server->global_list->servers);
181 silc_idcache_free(server->global_list->channels);
182 silc_hash_table_free(server->watcher_list);
183 silc_hash_table_free(server->watcher_list_pk);
185 silc_hash_free(server->md5hash);
186 silc_hash_free(server->sha1hash);
187 silc_hmac_unregister_all();
188 silc_hash_unregister_all();
189 silc_cipher_unregister_all();
190 silc_pkcs_unregister_all();
192 silc_free(server->local_list);
193 silc_free(server->global_list);
194 silc_free(server->server_name);
195 silc_free(server->id_string);
196 silc_free(server->purge_i);
197 silc_free(server->purge_g);
201 /* Creates a new server listener. */
203 static bool silc_server_listen(SilcServer server, const char *server_ip,
204 SilcUInt16 port, int *sock)
206 *sock = silc_net_create_server(port, server_ip);
208 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
215 /* Adds a secondary listener. */
217 bool silc_server_init_secondary(SilcServer server)
219 int sock = 0, sock_list[server->config->param.connections_max];
220 SilcSocketConnection newsocket = NULL;
221 SilcServerConfigServerInfoInterface *interface;
223 for (interface = server->config->server_info->secondary; interface;
224 interface = interface->next, sock++) {
226 if (!silc_server_listen(server,
227 interface->server_ip, interface->port, &sock_list[sock]))
230 /* Set socket to non-blocking mode */
231 silc_net_set_socket_nonblock(sock_list[sock]);
233 /* Add ourselves also to the socket table. The entry allocated above
234 is sent as argument for fast referencing in the future. */
235 silc_socket_alloc(sock_list[sock],
236 SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
237 server->sockets[sock_list[sock]] = newsocket;
238 SILC_SET_LISTENER(newsocket);
240 /* Perform name and address lookups to resolve the listenning address
242 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
244 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
246 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
247 newsocket->hostname ? newsocket->hostname :
248 newsocket->ip ? newsocket->ip : ""));
249 server->stat.conn_failures++;
252 if (!newsocket->hostname)
253 newsocket->hostname = strdup(newsocket->ip);
255 newsocket->port = silc_net_get_local_port(sock);
257 newsocket->user_data = (void *)server->id_entry;
258 silc_schedule_task_add(server->schedule, sock_list[sock],
259 silc_server_accept_new_connection,
260 (void *)server, 0, 0,
262 SILC_TASK_PRI_NORMAL);
268 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
272 /* Initializes the entire SILC server. This is called always before running
273 the server. This is called only once at the initialization of the program.
274 This binds the server to its listenning port. After this function returns
275 one should call silc_server_run to start the server. This returns TRUE
276 when everything is ok to run the server. Configuration file must be
277 read and parsed before calling this. */
279 bool silc_server_init(SilcServer server)
283 SilcServerEntry id_entry;
284 SilcIDListPurge purge;
285 SilcSocketConnection newsocket = NULL;
287 SILC_LOG_DEBUG(("Initializing server"));
289 server->starttime = time(NULL);
291 /* Take config object for us */
292 silc_server_config_ref(&server->config_ref, server->config,
296 /* Set debugging on if configured */
297 if (server->config->debug_string) {
299 silc_log_set_debug_string(server->config->debug_string);
301 #endif /* SILC_DEBUG */
303 /* Steal public and private key from the config object */
304 server->public_key = server->config->server_info->public_key;
305 server->private_key = server->config->server_info->private_key;
306 server->config->server_info->public_key = NULL;
307 server->config->server_info->private_key = NULL;
309 /* Register all configured ciphers, PKCS and hash functions. */
310 if (!silc_server_config_register_ciphers(server))
311 silc_cipher_register_default();
312 if (!silc_server_config_register_pkcs(server))
313 silc_pkcs_register_default();
314 if (!silc_server_config_register_hashfuncs(server))
315 silc_hash_register_default();
316 if (!silc_server_config_register_hmacs(server))
317 silc_hmac_register_default();
319 /* Initialize random number generator for the server. */
320 server->rng = silc_rng_alloc();
321 silc_rng_init(server->rng);
322 silc_rng_global_init(server->rng);
324 /* Initialize hash functions for server to use */
325 silc_hash_alloc("md5", &server->md5hash);
326 silc_hash_alloc("sha1", &server->sha1hash);
328 /* Allocate PKCS context for local public and private keys */
329 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
331 silc_pkcs_public_key_set(server->pkcs, server->public_key);
332 silc_pkcs_private_key_set(server->pkcs, server->private_key);
334 /* Initialize the scheduler */
335 server->schedule = silc_schedule_init(server->config->param.connections_max,
337 if (!server->schedule)
340 /* First, register log files configuration for error output */
341 silc_server_config_setlogfiles(server);
343 /* Initialize ID caches */
344 server->local_list->clients =
345 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
346 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
347 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
349 /* These are allocated for normal server as well as these hold some
350 global information that the server has fetched from its router. For
351 router these are used as they are supposed to be used on router. */
352 server->global_list->clients =
353 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
354 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
355 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
357 /* Init watcher lists */
358 server->watcher_list =
359 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
360 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
362 if (!server->watcher_list)
364 server->watcher_list_pk =
365 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
366 silc_hash_public_key_compare, NULL,
368 if (!server->watcher_list_pk)
371 /* Init public key list */
373 silc_hash_table_alloc(0, silc_hash_public_key, NULL,
374 silc_hash_public_key_compare, NULL,
377 if (!server->pk_hash)
380 /* Create a listening server */
381 if (!silc_server_listen(server,
382 server->config->server_info->primary == NULL ? NULL :
383 server->config->server_info->primary->server_ip,
384 server->config->server_info->primary == NULL ? 0 :
385 server->config->server_info->primary->port,
389 /* Set socket to non-blocking mode */
390 silc_net_set_socket_nonblock(sock);
393 /* Allocate the entire socket list that is used in server. Eventually
394 all connections will have entry in this table (it is a table of
395 pointers to the actual object that is allocated individually
397 server->sockets = silc_calloc(server->config->param.connections_max,
398 sizeof(*server->sockets));
399 if (!server->sockets)
402 /* Add ourselves also to the socket table. The entry allocated above
403 is sent as argument for fast referencing in the future. */
404 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
405 server->sockets[sock] = newsocket;
406 SILC_SET_LISTENER(newsocket);
408 /* Perform name and address lookups to resolve the listenning address
410 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
412 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
414 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
415 newsocket->hostname ? newsocket->hostname :
416 newsocket->ip ? newsocket->ip : ""));
417 server->stat.conn_failures++;
420 if (!newsocket->hostname)
421 newsocket->hostname = strdup(newsocket->ip);
423 newsocket->port = silc_net_get_local_port(sock);
425 /* Create a Server ID for the server. */
426 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
431 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
432 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
433 server->server_name = server->config->server_info->server_name;
434 server->config->server_info->server_name = NULL;
436 /* Add ourselves to the server list. We don't have a router yet
437 beacuse we haven't established a route yet. It will be done later.
438 For now, NULL is sent as router. This allocates new entry to
441 silc_idlist_add_server(server->local_list, strdup(server->server_name),
442 server->server_type, server->id, NULL, NULL);
444 SILC_LOG_ERROR(("Could not add ourselves to cache"));
447 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
449 /* Put the allocated socket pointer also to the entry allocated above
450 for fast back-referencing to the socket list. */
451 newsocket->user_data = (void *)id_entry;
452 id_entry->connection = (void *)newsocket;
453 server->id_entry = id_entry;
455 /* Register protocols */
456 silc_server_protocols_register();
458 /* Create connections to configured routers. */
459 silc_server_create_connections(server);
461 /* Add listener task to the scheduler. This task receives new connections
462 to the server. This task remains on the queue until the end of the
464 silc_schedule_task_add(server->schedule, sock,
465 silc_server_accept_new_connection,
466 (void *)server, 0, 0,
468 SILC_TASK_PRI_NORMAL);
470 if (silc_server_init_secondary(server) == FALSE)
473 server->listenning = TRUE;
475 /* If server connections has been configured then we must be router as
476 normal server cannot have server connections, only router connections. */
477 if (server->config->servers) {
478 SilcServerConfigServer *ptr = server->config->servers;
480 server->server_type = SILC_ROUTER;
482 if (ptr->backup_router) {
483 server->server_type = SILC_BACKUP_ROUTER;
484 server->backup_router = TRUE;
485 server->id_entry->server_type = SILC_BACKUP_ROUTER;
492 /* Register the ID Cache purge task. This periodically purges the ID cache
493 and removes the expired cache entries. */
495 /* Clients local list */
496 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
497 purge->cache = server->local_list->clients;
498 purge->timeout = 600;
499 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
500 (void *)purge, purge->timeout, 0,
501 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
503 /* Clients global list */
504 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
505 purge->cache = server->global_list->clients;
506 purge->timeout = 300;
507 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
508 (void *)purge, purge->timeout, 0,
509 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
511 /* If we are normal server we'll retrieve network statisticial information
512 once in a while from the router. */
513 if (server->server_type != SILC_ROUTER)
514 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
515 server, 10, 0, SILC_TASK_TIMEOUT,
518 if (server->server_type == SILC_ROUTER)
519 server->stat.routers++;
521 SILC_LOG_DEBUG(("Server initialized"));
523 /* We are done here, return succesfully */
527 silc_server_config_unref(&server->config_ref);
528 silc_net_close_server(sock);
532 /* Task callback to close a socket connection after rehash */
534 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
536 SilcServer server = context;
537 SilcSocketConnection sock = server->sockets[fd];
542 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
543 sock->hostname, sock->port,
544 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
545 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
546 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
548 silc_schedule_task_del_by_context(server->schedule, sock);
549 silc_server_disconnect_remote(server, sock,
550 SILC_STATUS_ERR_BANNED_FROM_SERVER,
551 "This connection is removed from "
554 silc_server_free_sock_user_data(server, sock, NULL);
557 /* This function basically reads the config file again and switches the config
558 object pointed by the server object. After that, we have to fix various
559 things such as the server_name and the listening ports.
560 Keep in mind that we no longer have the root privileges at this point. */
562 bool silc_server_rehash(SilcServer server)
564 SilcServerConfig newconfig;
566 SILC_LOG_INFO(("Rehashing server"));
568 /* Reset the logging system */
569 silc_log_quick = TRUE;
570 silc_log_flush_all();
572 /* Start the main rehash phase (read again the config file) */
573 newconfig = silc_server_config_alloc(server->config_file);
575 SILC_LOG_ERROR(("Rehash FAILED."));
579 /* Reinit scheduler if necessary */
580 if (newconfig->param.connections_max > server->config->param.connections_max)
581 if (!silc_schedule_reinit(server->schedule,
582 newconfig->param.connections_max))
585 /* Fix the server_name field */
586 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
587 silc_free(server->server_name);
588 server->server_name = newconfig->server_info->server_name;
589 newconfig->server_info->server_name = NULL;
591 /* Update the idcache list with a fresh pointer */
592 silc_free(server->id_entry->server_name);
593 server->id_entry->server_name = strdup(server->server_name);
594 if (!silc_idcache_del_by_context(server->local_list->servers,
597 if (!silc_idcache_add(server->local_list->servers,
598 server->id_entry->server_name,
599 server->id_entry->id, server->id_entry, 0, NULL))
604 silc_server_config_setlogfiles(server);
606 /* Change new key pair if necessary */
607 if (newconfig->server_info->public_key &&
608 !silc_pkcs_public_key_compare(server->public_key,
609 newconfig->server_info->public_key)) {
610 silc_pkcs_public_key_free(server->public_key);
611 silc_pkcs_private_key_free(server->private_key);
612 server->public_key = newconfig->server_info->public_key;
613 server->private_key = newconfig->server_info->private_key;
614 newconfig->server_info->public_key = NULL;
615 newconfig->server_info->private_key = NULL;
617 /* Allocate PKCS context for local public and private keys */
618 silc_pkcs_free(server->pkcs);
619 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
621 silc_pkcs_public_key_set(server->pkcs, server->public_key);
622 silc_pkcs_private_key_set(server->pkcs, server->private_key);
625 /* Check for unconfigured server and router connections and close
626 connections that were unconfigured. */
628 if (server->config->routers) {
629 SilcServerConfigRouter *ptr;
630 SilcServerConfigRouter *newptr;
633 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
636 /* Check whether new config has this one too */
637 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
638 if (silc_string_compare(newptr->host, ptr->host) &&
639 newptr->port == ptr->port &&
640 newptr->initiator == ptr->initiator) {
646 if (!found && ptr->host) {
647 /* Remove this connection */
648 SilcSocketConnection sock;
649 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_ROUTER,
650 ptr->host, ptr->port);
651 if (sock && !SILC_IS_LISTENER(sock))
652 silc_schedule_task_add(server->schedule, sock->sock,
653 silc_server_rehash_close_connection,
654 server, 0, 1, SILC_TASK_TIMEOUT,
655 SILC_TASK_PRI_NORMAL);
660 if (server->config->servers) {
661 SilcServerConfigServer *ptr;
662 SilcServerConfigServer *newptr;
665 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
668 /* Check whether new config has this one too */
669 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
670 if (silc_string_compare(newptr->host, ptr->host)) {
676 if (!found && ptr->host) {
677 /* Remove this connection */
678 SilcSocketConnection sock;
679 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_SERVER,
681 if (sock && !SILC_IS_LISTENER(sock))
682 silc_schedule_task_add(server->schedule, sock->sock,
683 silc_server_rehash_close_connection,
684 server, 0, 1, SILC_TASK_TIMEOUT,
685 SILC_TASK_PRI_NORMAL);
690 if (server->config->clients) {
691 SilcServerConfigClient *ptr;
692 SilcServerConfigClient *newptr;
695 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
698 /* Check whether new config has this one too */
699 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
700 if (silc_string_compare(newptr->host, ptr->host)) {
706 if (!found && ptr->host) {
707 /* Remove this connection */
708 SilcSocketConnection sock;
709 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_CLIENT,
712 silc_schedule_task_add(server->schedule, sock->sock,
713 silc_server_rehash_close_connection,
714 server, 0, 1, SILC_TASK_TIMEOUT,
715 SILC_TASK_PRI_NORMAL);
720 /* Create connections after rehash */
721 silc_server_create_connections(server);
723 /* Check whether our router status has changed */
724 if (newconfig->servers) {
725 SilcServerConfigServer *ptr = newconfig->servers;
727 server->server_type = SILC_ROUTER;
729 if (ptr->backup_router) {
730 server->server_type = SILC_BACKUP_ROUTER;
731 server->backup_router = TRUE;
732 server->id_entry->server_type = SILC_BACKUP_ROUTER;
739 /* Our old config is gone now. We'll unreference our reference made in
740 silc_server_init and then destroy it since we are destroying it
741 underneath the application (layer which called silc_server_init). */
742 silc_server_config_unref(&server->config_ref);
743 silc_server_config_destroy(server->config);
745 /* Take new config context */
746 server->config = newconfig;
747 silc_server_config_ref(&server->config_ref, server->config, server->config);
750 /* Set debugging on if configured */
751 if (server->config->debug_string) {
753 silc_log_set_debug_string(server->config->debug_string);
757 #endif /* SILC_DEBUG */
759 SILC_LOG_DEBUG(("Server rehashed"));
764 /* The heart of the server. This runs the scheduler thus runs the server.
765 When this returns the server has been stopped and the program will
768 void silc_server_run(SilcServer server)
770 SILC_LOG_INFO(("SILC Server started"));
772 /* Start the scheduler, the heart of the SILC server. When this returns
773 the program will be terminated. */
774 silc_schedule(server->schedule);
777 /* Stops the SILC server. This function is used to shutdown the server.
778 This is usually called after the scheduler has returned. After stopping
779 the server one should call silc_server_free. */
781 void silc_server_stop(SilcServer server)
783 SILC_LOG_INFO(("SILC Server shutting down"));
785 if (server->schedule) {
788 server->server_shutdown = TRUE;
790 /* Close all connections */
791 for (i = 0; i < server->config->param.connections_max; i++) {
792 if (!server->sockets[i])
794 if (!SILC_IS_LISTENER(server->sockets[i])) {
795 SilcSocketConnection sock = server->sockets[i];
796 SilcIDListData idata = sock->user_data;
799 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
801 silc_schedule_task_del_by_context(server->schedule,
803 silc_schedule_task_del_by_fd(server->schedule,
804 server->sockets[i]->sock);
805 silc_server_disconnect_remote(server, server->sockets[i],
807 "Server is shutting down");
808 if (server->sockets[i]) {
810 silc_server_free_sock_user_data(server, sock,
811 "Server is shutting down");
812 silc_socket_free(sock);
815 silc_socket_free(server->sockets[i]);
816 server->sockets[i] = NULL;
820 /* We are not connected to network anymore */
821 server->standalone = TRUE;
823 silc_schedule_stop(server->schedule);
824 silc_schedule_uninit(server->schedule);
825 server->schedule = NULL;
827 silc_free(server->sockets);
828 server->sockets = NULL;
831 silc_server_protocols_unregister();
833 SILC_LOG_DEBUG(("Server stopped"));
836 /* Function that is called when the network connection to a router has
837 been established. This will continue with the key exchange protocol
838 with the remote router. */
840 void silc_server_start_key_exchange(SilcServer server,
841 SilcServerConnection sconn,
844 SilcSocketConnection newsocket;
845 SilcProtocol protocol;
846 SilcServerKEInternalContext *proto_ctx;
847 SilcServerConfigRouter *conn =
848 (SilcServerConfigRouter *) sconn->conn.ref_ptr;
851 /* Cancel any possible retry timeouts */
852 silc_schedule_task_del_by_callback(server->schedule,
853 silc_server_connect_to_router_retry);
855 /* Set socket options */
856 silc_net_set_socket_nonblock(sock);
857 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
859 /* Create socket connection for the connection. Even though we
860 know that we are connecting to a router we will mark the socket
861 to be unknown connection until we have executed authentication
863 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
864 server->sockets[sock] = newsocket;
865 newsocket->hostname = strdup(sconn->remote_host);
866 newsocket->ip = strdup(sconn->remote_host);
867 newsocket->port = sconn->remote_port;
868 sconn->sock = newsocket;
870 /* Allocate internal protocol context. This is sent as context
872 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
873 proto_ctx->server = (void *)server;
874 proto_ctx->context = (void *)sconn;
875 proto_ctx->sock = newsocket;
876 proto_ctx->rng = server->rng;
877 proto_ctx->responder = FALSE;
879 /* Set Key Exchange flags from configuration, but fall back to global
881 SILC_GET_SKE_FLAGS(conn, proto_ctx);
882 if (server->config->param.key_exchange_pfs)
883 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
885 /* Perform key exchange protocol. silc_server_connect_to_router_second
886 will be called after the protocol is finished. */
887 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
888 &protocol, proto_ctx,
889 silc_server_connect_to_router_second);
890 newsocket->protocol = protocol;
892 /* Register a timeout task that will be executed if the protocol
893 is not executed within set limit. */
894 proto_ctx->timeout_task =
895 silc_schedule_task_add(server->schedule, sock,
896 silc_server_timeout_remote,
897 server, server->config->key_exchange_timeout, 0,
901 /* Register the connection for network input and output. This sets
902 that scheduler will listen for incoming packets for this connection
903 and sets that outgoing packets may be sent to this connection as
904 well. However, this doesn't set the scheduler for outgoing traffic,
905 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
906 later when outgoing data is available. */
907 context = (void *)server;
908 SILC_REGISTER_CONNECTION_FOR_IO(sock);
910 /* Run the protocol */
911 silc_protocol_execute(protocol, server->schedule, 0, 0);
914 /* Timeout callback that will be called to retry connecting to remote
915 router. This is used by both normal and router server. This will wait
916 before retrying the connecting. The timeout is generated by exponential
917 backoff algorithm. */
919 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
921 SilcServer server = app_context;
922 SilcServerConnection sconn = (SilcServerConnection)context;
923 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
924 SilcServerConfigConnParams *param =
925 (conn->param ? conn->param : &server->config->param);
927 /* Don't retry if we are shutting down. */
928 if (server->server_shutdown) {
929 silc_server_config_unref(&sconn->conn);
930 silc_free(sconn->remote_host);
931 silc_free(sconn->backup_replace_ip);
936 SILC_LOG_INFO(("Retrying connecting to a router"));
938 /* Calculate next timeout */
939 if (sconn->retry_count >= 1) {
940 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
941 if (sconn->retry_timeout > param->reconnect_interval_max)
942 sconn->retry_timeout = param->reconnect_interval_max;
944 sconn->retry_timeout = param->reconnect_interval;
946 sconn->retry_count++;
947 sconn->retry_timeout = sconn->retry_timeout +
948 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
950 /* If we've reached max retry count, give up. */
951 if ((sconn->retry_count > param->reconnect_count) &&
952 !param->reconnect_keep_trying) {
953 SILC_LOG_ERROR(("Could not connect to router, giving up"));
954 silc_server_config_unref(&sconn->conn);
955 silc_free(sconn->remote_host);
956 silc_free(sconn->backup_replace_ip);
961 SILC_LOG_DEBUG(("Retrying connecting to a router in %d seconds",
962 sconn->retry_timeout));
964 /* We will lookup a fresh pointer later */
965 silc_server_config_unref(&sconn->conn);
967 /* Wait one before retrying */
968 silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
969 context, sconn->retry_timeout, 0,
970 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
973 /* callback for async connection to remote router */
975 SILC_TASK_CALLBACK(silc_server_connection_established)
977 SilcServer server = app_context;
978 SilcServerConnection sconn = (SilcServerConnection)context;
980 int opt = EINVAL, optlen = sizeof(opt);
982 silc_schedule_task_del_by_fd(server->schedule, sock);
983 silc_schedule_unset_listen_fd(server->schedule, sock);
985 if (silc_net_get_socket_opt(sock, SOL_SOCKET, SO_ERROR, &opt, &optlen) ||
987 SILC_LOG_ERROR(("Could not connect to router %s:%d: %s",
988 sconn->remote_host, sconn->remote_port,
990 if (!sconn->no_reconnect)
991 silc_schedule_task_add(server->schedule, 0,
992 silc_server_connect_to_router_retry,
993 context, 0, 1, SILC_TASK_TIMEOUT,
994 SILC_TASK_PRI_NORMAL);
996 silc_server_config_unref(&sconn->conn);
997 silc_free(sconn->remote_host);
998 silc_free(sconn->backup_replace_ip);
1004 SILC_LOG_DEBUG(("Connection to router %s:%d established", sconn->remote_host,
1005 sconn->remote_port));
1007 /* Continue with key exchange protocol */
1008 silc_server_start_key_exchange(server, sconn, sock);
1010 /* Generic routine to use connect to a router. */
1012 SILC_TASK_CALLBACK(silc_server_connect_router)
1014 SilcServer server = app_context;
1015 SilcServerConnection sconn = (SilcServerConnection)context;
1016 SilcServerConfigRouter *rconn;
1019 /* Don't connect if we are shutting down. */
1020 if (server->server_shutdown) {
1021 silc_free(sconn->remote_host);
1022 silc_free(sconn->backup_replace_ip);
1027 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1028 (sconn->backup ? "backup router" : "router"),
1029 sconn->remote_host, sconn->remote_port));
1031 server->router_connect = time(NULL);
1032 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1033 sconn->remote_port);
1035 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1036 (sconn->backup ? "backup router" : "router"),
1037 sconn->remote_host, sconn->remote_port));
1038 silc_free(sconn->remote_host);
1039 silc_free(sconn->backup_replace_ip);
1043 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1045 /* Connect to remote host */
1046 sock = silc_net_create_connection_async(
1047 (!server->config->server_info->primary ? NULL :
1048 server->config->server_info->primary->server_ip),
1049 sconn->remote_port, sconn->remote_host);
1051 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1052 sconn->remote_host, sconn->remote_port));
1053 if (!sconn->no_reconnect)
1054 silc_schedule_task_add(server->schedule, 0,
1055 silc_server_connect_to_router_retry,
1056 context, 0, 1, SILC_TASK_TIMEOUT,
1057 SILC_TASK_PRI_NORMAL);
1059 silc_server_config_unref(&sconn->conn);
1060 silc_free(sconn->remote_host);
1061 silc_free(sconn->backup_replace_ip);
1067 /* wait for the connection to be established */
1068 silc_schedule_task_add(server->schedule, sock,
1069 silc_server_connection_established,
1070 context, 0, 0, SILC_TASK_FD,
1071 SILC_TASK_PRI_NORMAL);
1072 silc_schedule_set_listen_fd(server->schedule, sock,
1073 SILC_TASK_WRITE, FALSE);
1076 /* This function connects to our primary router or if we are a router this
1077 establishes all our primary routes. This is called at the start of the
1078 server to do authentication and key exchange with our router - called
1081 SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router)
1083 SilcServer server = (SilcServer)context;
1084 SilcServerConnection sconn;
1085 SilcServerConfigRouter *ptr;
1087 /* Don't connect if we are shutting down. */
1088 if (server->server_shutdown)
1091 SILC_LOG_DEBUG(("We are %s",
1092 (server->server_type == SILC_SERVER ?
1093 "normal server" : server->server_type == SILC_ROUTER ?
1094 "router" : "backup router/normal server")));
1096 if (!server->config->routers) {
1097 /* There wasn't a configured router, we will continue but we don't
1098 have a connection to outside world. We will be standalone server. */
1099 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1100 server->standalone = TRUE;
1104 /* Cancel any possible retry timeouts */
1105 silc_schedule_task_del_by_callback(server->schedule,
1106 silc_server_connect_router);
1107 silc_schedule_task_del_by_callback(server->schedule,
1108 silc_server_connect_to_router_retry);
1110 /* Create the connections to all our routes */
1111 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1113 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1114 ptr->backup_router ? "Backup router" : "Router",
1115 ptr->initiator ? "Initiator" : "Responder",
1116 ptr->host, ptr->port));
1118 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1119 ptr->initiator == FALSE && !server->backup_router &&
1120 !silc_server_config_get_backup_router(server))
1121 server->wait_backup = TRUE;
1123 if (ptr->initiator) {
1124 /* Check whether we are connecting or connected to this host already */
1125 if (silc_server_num_sockets_by_remote(server,
1126 silc_net_is_ip(ptr->host) ?
1128 silc_net_is_ip(ptr->host) ?
1129 NULL : ptr->host, ptr->port,
1130 SILC_SOCKET_TYPE_ROUTER)) {
1131 SILC_LOG_DEBUG(("We are already connected to this router"));
1133 /* If we don't have primary router and this connection is our
1134 primary router we are in desync. Reconnect to the primary. */
1135 if (server->standalone && !server->router) {
1136 SilcServerConfigRouter *primary =
1137 silc_server_config_get_primary_router(server);
1138 if (primary == ptr) {
1139 SilcSocketConnection sock =
1140 silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_ROUTER,
1141 ptr->host, ptr->port);
1143 server->backup_noswitch = TRUE;
1144 if (sock->user_data)
1145 silc_server_free_sock_user_data(server, sock, NULL);
1146 silc_server_disconnect_remote(server, sock, 0, NULL);
1147 server->backup_noswitch = FALSE;
1148 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1159 if (silc_server_num_sockets_by_remote(server,
1160 silc_net_is_ip(ptr->host) ?
1162 silc_net_is_ip(ptr->host) ?
1163 NULL : ptr->host, ptr->port,
1164 SILC_SOCKET_TYPE_UNKNOWN)) {
1165 SILC_LOG_DEBUG(("We are already connecting to this router"));
1169 /* Allocate connection object for hold connection specific stuff. */
1170 sconn = silc_calloc(1, sizeof(*sconn));
1171 sconn->remote_host = strdup(ptr->host);
1172 sconn->remote_port = ptr->port;
1173 sconn->backup = ptr->backup_router;
1174 if (sconn->backup) {
1175 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1176 sconn->backup_replace_port = ptr->backup_replace_port;
1179 if (!server->router_conn && !sconn->backup)
1180 server->router_conn = sconn;
1182 silc_schedule_task_add(server->schedule, 0,
1183 silc_server_connect_router,
1184 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
1185 SILC_TASK_PRI_NORMAL);
1190 /* Second part of connecting to router(s). Key exchange protocol has been
1191 executed and now we will execute authentication protocol. */
1193 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
1195 SilcProtocol protocol = (SilcProtocol)context;
1196 SilcServerKEInternalContext *ctx =
1197 (SilcServerKEInternalContext *)protocol->context;
1198 SilcServer server = (SilcServer)ctx->server;
1199 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1200 SilcSocketConnection sock = ctx->sock;
1201 SilcServerConnAuthInternalContext *proto_ctx;
1202 SilcServerConfigRouter *conn = NULL;
1204 SILC_LOG_DEBUG(("Start"));
1206 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1207 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1208 /* Error occured during protocol */
1209 silc_protocol_free(protocol);
1210 sock->protocol = NULL;
1211 silc_ske_free_key_material(ctx->keymat);
1213 silc_packet_context_free(ctx->packet);
1215 silc_ske_free(ctx->ske);
1216 silc_free(ctx->dest_id);
1218 silc_server_disconnect_remote(server, sock,
1219 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1221 /* Try reconnecting if configuration wants it */
1222 if (!sconn->no_reconnect) {
1223 silc_schedule_task_add(server->schedule, 0,
1224 silc_server_connect_to_router_retry,
1225 sconn, 0, 1, SILC_TASK_TIMEOUT,
1226 SILC_TASK_PRI_NORMAL);
1230 /* Call completion to indicate error */
1231 if (sconn->callback)
1232 (*sconn->callback)(server, NULL, sconn->callback_context);
1234 silc_server_config_unref(&sconn->conn);
1235 silc_free(sconn->remote_host);
1236 silc_free(sconn->backup_replace_ip);
1241 /* We now have the key material as the result of the key exchange
1242 protocol. Take the key material into use. Free the raw key material
1243 as soon as we've set them into use. */
1244 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1245 ctx->sock, ctx->keymat,
1246 ctx->ske->prop->cipher,
1247 ctx->ske->prop->pkcs,
1248 ctx->ske->prop->hash,
1249 ctx->ske->prop->hmac,
1250 ctx->ske->prop->group,
1252 silc_protocol_free(protocol);
1253 sock->protocol = NULL;
1254 silc_ske_free_key_material(ctx->keymat);
1256 silc_packet_context_free(ctx->packet);
1258 silc_ske_free(ctx->ske);
1259 silc_free(ctx->dest_id);
1261 silc_server_disconnect_remote(server, sock,
1262 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1264 /* Try reconnecting if configuration wants it */
1265 if (!sconn->no_reconnect) {
1266 silc_schedule_task_add(server->schedule, 0,
1267 silc_server_connect_to_router_retry,
1268 sconn, 0, 1, SILC_TASK_TIMEOUT,
1269 SILC_TASK_PRI_NORMAL);
1273 /* Call completion to indicate error */
1274 if (sconn->callback)
1275 (*sconn->callback)(server, NULL, sconn->callback_context);
1277 silc_server_config_unref(&sconn->conn);
1278 silc_free(sconn->remote_host);
1279 silc_free(sconn->backup_replace_ip);
1283 silc_ske_free_key_material(ctx->keymat);
1285 /* Allocate internal context for the authentication protocol. This
1286 is sent as context for the protocol. */
1287 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1288 proto_ctx->server = (void *)server;
1289 proto_ctx->context = (void *)sconn;
1290 proto_ctx->sock = sock;
1291 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1292 proto_ctx->dest_id_type = ctx->dest_id_type;
1293 proto_ctx->dest_id = ctx->dest_id;
1295 /* Resolve the authentication method used in this connection. Check if
1296 we find a match from user configured connections */
1297 if (!sconn->conn.ref_ptr)
1298 conn = silc_server_config_find_router_conn(server, sock->hostname,
1301 conn = sconn->conn.ref_ptr;
1304 /* Match found. Use the configured authentication method. Take only
1305 the passphrase, since for public key auth we automatically use
1306 our local key pair. */
1307 if (conn->passphrase) {
1308 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1309 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
1311 proto_ctx->auth_data = strdup(conn->passphrase);
1312 proto_ctx->auth_data_len = strlen(conn->passphrase);
1313 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
1315 } else if (conn->publickeys) {
1316 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
1318 proto_ctx->auth_meth = SILC_AUTH_NONE;
1321 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
1322 sock->hostname, sock->ip, sock->port));
1323 silc_protocol_free(protocol);
1324 sock->protocol = NULL;
1326 silc_packet_context_free(ctx->packet);
1328 silc_ske_free(ctx->ske);
1329 silc_free(ctx->dest_id);
1331 silc_server_config_unref(&sconn->conn);
1332 silc_free(sconn->remote_host);
1333 silc_free(sconn->backup_replace_ip);
1335 silc_server_disconnect_remote(server, sock,
1336 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1340 /* Free old protocol as it is finished now */
1341 silc_protocol_free(protocol);
1343 silc_packet_context_free(ctx->packet);
1345 sock->protocol = NULL;
1347 /* Allocate the authentication protocol. This is allocated here
1348 but we won't start it yet. We will be receiving party of this
1349 protocol thus we will wait that connecting party will make
1350 their first move. */
1351 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1352 &sock->protocol, proto_ctx,
1353 silc_server_connect_to_router_final);
1355 /* Register timeout task. If the protocol is not executed inside
1356 this timelimit the connection will be terminated. */
1357 proto_ctx->timeout_task =
1358 silc_schedule_task_add(server->schedule, sock->sock,
1359 silc_server_timeout_remote,
1361 server->config->conn_auth_timeout, 0,
1365 /* Run the protocol */
1366 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1369 /* Finalizes the connection to router. Registers a server task to the
1370 queue so that we can accept new connections. */
1372 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
1374 SilcProtocol protocol = (SilcProtocol)context;
1375 SilcServerConnAuthInternalContext *ctx =
1376 (SilcServerConnAuthInternalContext *)protocol->context;
1377 SilcServer server = (SilcServer)ctx->server;
1378 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1379 SilcSocketConnection sock = ctx->sock;
1380 SilcServerEntry id_entry = NULL;
1382 unsigned char *id_string;
1384 SilcIDListData idata;
1385 SilcServerConfigRouter *conn = NULL;
1386 SilcServerConfigConnParams *param = NULL;
1388 SILC_LOG_DEBUG(("Start"));
1390 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1391 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1392 /* Error occured during protocol */
1393 silc_free(ctx->dest_id);
1394 sock->protocol = NULL;
1395 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1397 sock->protocol = protocol;
1399 /* Try reconnecting if configuration wants it */
1400 if (!sconn->no_reconnect) {
1401 silc_schedule_task_add(server->schedule, 0,
1402 silc_server_connect_to_router_retry,
1403 sconn, 0, 1, SILC_TASK_TIMEOUT,
1404 SILC_TASK_PRI_NORMAL);
1411 /* Add a task to the queue. This task receives new connections to the
1412 server. This task remains on the queue until the end of the program. */
1413 if (!server->listenning && !sconn->backup) {
1414 silc_schedule_task_add(server->schedule, server->sock,
1415 silc_server_accept_new_connection,
1416 (void *)server, 0, 0,
1418 SILC_TASK_PRI_NORMAL);
1419 server->listenning = TRUE;
1422 /* Send NEW_SERVER packet to the router. We will become registered
1423 to the SILC network after sending this packet. */
1424 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
1425 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
1426 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
1427 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1428 silc_buffer_format(packet,
1429 SILC_STR_UI_SHORT(id_len),
1430 SILC_STR_UI_XNSTRING(id_string, id_len),
1431 SILC_STR_UI_SHORT(strlen(server->server_name)),
1432 SILC_STR_UI_XNSTRING(server->server_name,
1433 strlen(server->server_name)),
1436 /* Send the packet */
1437 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
1438 packet->data, packet->len, TRUE);
1439 silc_buffer_free(packet);
1440 silc_free(id_string);
1442 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
1444 /* Check that we do not have this ID already */
1445 id_entry = silc_idlist_find_server_by_id(server->local_list,
1446 ctx->dest_id, TRUE, NULL);
1448 silc_idcache_del_by_context(server->local_list->servers, id_entry);
1450 id_entry = silc_idlist_find_server_by_id(server->global_list,
1451 ctx->dest_id, TRUE, NULL);
1453 silc_idcache_del_by_context(server->global_list->servers, id_entry);
1456 SILC_LOG_DEBUG(("New server id(%s)",
1457 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
1459 /* Add the connected router to global server list. Router is sent
1460 as NULL since it's local to us. */
1461 id_entry = silc_idlist_add_server(server->global_list,
1462 strdup(sock->hostname),
1463 SILC_ROUTER, ctx->dest_id, NULL, sock);
1465 silc_free(ctx->dest_id);
1466 SILC_LOG_ERROR(("Cannot add new server entry to cache"));
1467 sock->protocol = NULL;
1468 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1470 sock->protocol = protocol;
1474 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1475 silc_free(sock->user_data);
1476 sock->user_data = (void *)id_entry;
1477 sock->type = SILC_SOCKET_TYPE_ROUTER;
1478 idata = (SilcIDListData)sock->user_data;
1479 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1480 SILC_IDLIST_STATUS_LOCAL);
1482 conn = sconn->conn.ref_ptr;
1483 param = &server->config->param;
1484 if (conn && conn->param)
1485 param = conn->param;
1487 /* Perform keepalive. */
1488 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
1489 silc_server_perform_heartbeat,
1492 /* Register re-key timeout */
1493 idata->rekey->timeout = param->key_exchange_rekey;
1494 silc_schedule_task_add(server->schedule, sock->sock,
1495 silc_server_rekey_callback,
1496 (void *)sock, idata->rekey->timeout, 0,
1497 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1499 if (!sconn->backup) {
1500 /* Mark this router our primary router if we're still standalone */
1501 if (server->standalone) {
1502 SILC_LOG_DEBUG(("This connection is our primary router"));
1503 server->id_entry->router = id_entry;
1504 server->router = id_entry;
1505 server->router->server_type = SILC_ROUTER;
1506 server->standalone = FALSE;
1507 server->backup_primary = FALSE;
1509 /* Announce data if we are not backup router (unless not as primary
1510 currently). Backup router announces later at the end of
1511 resuming protocol. */
1512 if (server->backup_router && server->server_type == SILC_ROUTER) {
1513 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1515 /* If we are router then announce our possible servers. Backup
1516 router announces also global servers. */
1517 if (server->server_type == SILC_ROUTER)
1518 silc_server_announce_servers(server,
1519 server->backup_router ? TRUE : FALSE,
1520 0, SILC_PRIMARY_ROUTE(server));
1522 /* Announce our clients and channels to the router */
1523 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1524 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1527 /* If we are backup router then this primary router is whom we are
1529 if (server->server_type == SILC_BACKUP_ROUTER)
1530 silc_server_backup_add(server, server->id_entry, sock->ip,
1531 sconn->remote_port, TRUE);
1534 /* Add this server to be our backup router */
1535 id_entry->server_type = SILC_BACKUP_ROUTER;
1536 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1537 sconn->backup_replace_port, FALSE);
1540 sock->protocol = NULL;
1543 /* Call the completion callback to indicate that we've connected to
1545 if (sconn && sconn->callback)
1546 (*sconn->callback)(server, id_entry, sconn->callback_context);
1548 /* Free the temporary connection data context */
1550 silc_server_config_unref(&sconn->conn);
1551 silc_free(sconn->remote_host);
1552 silc_free(sconn->backup_replace_ip);
1555 if (sconn == server->router_conn)
1556 server->router_conn = NULL;
1559 /* Free the protocol object */
1560 if (sock->protocol == protocol)
1561 sock->protocol = NULL;
1562 silc_protocol_free(protocol);
1564 silc_packet_context_free(ctx->packet);
1566 silc_ske_free(ctx->ske);
1567 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1568 silc_free(ctx->auth_data);
1572 /* Host lookup callback that is called after the incoming connection's
1573 IP and FQDN lookup is performed. This will actually check the acceptance
1574 of the incoming connection and will register the key exchange protocol
1575 for this connection. */
1578 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1581 SilcServerKEInternalContext *proto_ctx =
1582 (SilcServerKEInternalContext *)context;
1583 SilcServer server = (SilcServer)proto_ctx->server;
1584 SilcServerConfigClient *cconfig = NULL;
1585 SilcServerConfigServer *sconfig = NULL;
1586 SilcServerConfigRouter *rconfig = NULL;
1587 SilcServerConfigDeny *deny;
1590 /* Check whether we could resolve both IP and FQDN. */
1591 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1592 server->config->require_reverse_lookup)) {
1593 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1594 sock->hostname ? sock->hostname :
1595 sock->ip ? sock->ip : ""));
1596 server->stat.conn_failures++;
1597 silc_server_disconnect_remote(server, sock,
1598 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1599 "Unknown host or IP");
1600 silc_free(proto_ctx);
1604 /* Register the connection for network input and output. This sets
1605 that scheduler will listen for incoming packets for this connection
1606 and sets that outgoing packets may be sent to this connection as well.
1607 However, this doesn't set the scheduler for outgoing traffic, it
1608 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1609 later when outgoing data is available. */
1610 context = (void *)server;
1611 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1613 SILC_LOG_INFO(("Incoming connection %s (%s)", sock->hostname,
1616 /* Listenning port */
1617 if (!server->sockets[SILC_PTR_TO_32(proto_ctx->context)]) {
1618 silc_server_disconnect_remote(server, sock,
1619 SILC_STATUS_ERR_RESOURCE_LIMIT,
1620 "Connection refused");
1621 server->stat.conn_failures++;
1622 silc_free(proto_ctx);
1625 port = server->sockets[SILC_PTR_TO_32(proto_ctx->context)]->port;
1627 /* Check whether this connection is denied to connect to us. */
1628 deny = silc_server_config_find_denied(server, sock->ip);
1630 deny = silc_server_config_find_denied(server, sock->hostname);
1632 /* The connection is denied */
1633 SILC_LOG_INFO(("Connection %s (%s) is denied",
1634 sock->hostname, sock->ip));
1635 silc_server_disconnect_remote(server, sock,
1636 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1638 server->stat.conn_failures++;
1639 silc_free(proto_ctx);
1643 /* Check whether we have configured this sort of connection at all. We
1644 have to check all configurations since we don't know what type of
1645 connection this is. */
1646 if (!(cconfig = silc_server_config_find_client(server, sock->ip)))
1647 cconfig = silc_server_config_find_client(server, sock->hostname);
1648 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1649 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1650 if (server->server_type == SILC_ROUTER) {
1651 if (!(rconfig = silc_server_config_find_router_conn(server,
1652 sock->ip, sock->port)))
1653 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1656 if (!cconfig && !sconfig && !rconfig) {
1657 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1659 silc_server_disconnect_remote(server, sock,
1660 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
1661 server->stat.conn_failures++;
1662 silc_free(proto_ctx);
1666 /* The connection is allowed */
1668 /* Set internal context for key exchange protocol. This is
1669 sent as context for the protocol. */
1670 proto_ctx->sock = sock;
1671 proto_ctx->rng = server->rng;
1672 proto_ctx->responder = TRUE;
1673 silc_server_config_ref(&proto_ctx->cconfig, server->config, cconfig);
1674 silc_server_config_ref(&proto_ctx->sconfig, server->config, sconfig);
1675 silc_server_config_ref(&proto_ctx->rconfig, server->config, rconfig);
1677 /* Take flags for key exchange. Since we do not know what type of connection
1678 this is, we go through all found configurations and use the global ones
1679 as well. This will result always into strictest key exchange flags. */
1680 SILC_GET_SKE_FLAGS(cconfig, proto_ctx);
1681 SILC_GET_SKE_FLAGS(sconfig, proto_ctx);
1682 SILC_GET_SKE_FLAGS(rconfig, proto_ctx);
1683 if (server->config->param.key_exchange_pfs)
1684 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
1686 /* Prepare the connection for key exchange protocol. We allocate the
1687 protocol but will not start it yet. The connector will be the
1688 initiator of the protocol thus we will wait for initiation from
1689 there before we start the protocol. */
1690 server->stat.auth_attempts++;
1691 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1692 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1693 &sock->protocol, proto_ctx,
1694 silc_server_accept_new_connection_second);
1696 /* Register a timeout task that will be executed if the connector
1697 will not start the key exchange protocol within specified timeout
1698 and the connection will be closed. */
1699 proto_ctx->timeout_task =
1700 silc_schedule_task_add(server->schedule, sock->sock,
1701 silc_server_timeout_remote,
1703 server->config->key_exchange_timeout, 0,
1708 /* Accepts new connections to the server. Accepting new connections are
1709 done in three parts to make it async. */
1711 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1713 SilcServer server = (SilcServer)context;
1714 SilcSocketConnection newsocket;
1715 SilcServerKEInternalContext *proto_ctx;
1718 SILC_LOG_DEBUG(("Accepting new connection"));
1720 server->stat.conn_attempts++;
1722 sock = silc_net_accept_connection(fd);
1724 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1725 server->stat.conn_failures++;
1729 /* Check for maximum allowed connections */
1730 if (sock > server->config->param.connections_max) {
1731 SILC_LOG_ERROR(("Refusing connection, server is full"));
1732 server->stat.conn_failures++;
1733 silc_net_close_connection(sock);
1737 /* Set socket options */
1738 silc_net_set_socket_nonblock(sock);
1739 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1741 /* We don't create a ID yet, since we don't know what type of connection
1742 this is yet. But, we do add the connection to the socket table. */
1743 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1744 server->sockets[sock] = newsocket;
1746 /* Perform asynchronous host lookup. This will lookup the IP and the
1747 FQDN of the remote connection. After the lookup is done the connection
1748 is accepted further. */
1749 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1750 proto_ctx->server = server;
1751 proto_ctx->context = SILC_32_TO_PTR(fd);
1752 silc_socket_host_lookup(newsocket, TRUE,
1753 silc_server_accept_new_connection_lookup,
1754 (void *)proto_ctx, server->schedule);
1757 /* Second part of accepting new connection. Key exchange protocol has been
1758 performed and now it is time to do little connection authentication
1759 protocol to figure out whether this connection is client or server
1760 and whether it has right to access this server (especially server
1761 connections needs to be authenticated). */
1763 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1765 SilcProtocol protocol = (SilcProtocol)context;
1766 SilcServerKEInternalContext *ctx =
1767 (SilcServerKEInternalContext *)protocol->context;
1768 SilcServer server = (SilcServer)ctx->server;
1769 SilcSocketConnection sock = ctx->sock;
1770 SilcServerConnAuthInternalContext *proto_ctx;
1772 SILC_LOG_DEBUG(("Start"));
1774 if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
1775 (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
1776 /* Error occured during protocol */
1777 SILC_LOG_DEBUG(("Error in key exchange protocol"));
1778 silc_protocol_free(protocol);
1779 sock->protocol = NULL;
1780 silc_ske_free_key_material(ctx->keymat);
1782 silc_packet_context_free(ctx->packet);
1784 silc_ske_free(ctx->ske);
1785 silc_free(ctx->dest_id);
1786 silc_server_config_unref(&ctx->cconfig);
1787 silc_server_config_unref(&ctx->sconfig);
1788 silc_server_config_unref(&ctx->rconfig);
1791 if (!SILC_IS_DISCONNECTING(sock)) {
1792 SILC_LOG_INFO(("Key exchange failed for %s:%d [%s]", sock->hostname,
1794 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1795 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1796 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1798 silc_server_disconnect_remote(server, sock,
1799 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
1803 server->stat.auth_failures++;
1807 /* We now have the key material as the result of the key exchange
1808 protocol. Take the key material into use. Free the raw key material
1809 as soon as we've set them into use. */
1810 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1811 ctx->sock, ctx->keymat,
1812 ctx->ske->prop->cipher,
1813 ctx->ske->prop->pkcs,
1814 ctx->ske->prop->hash,
1815 ctx->ske->prop->hmac,
1816 ctx->ske->prop->group,
1818 SILC_LOG_ERROR(("Error setting key material in use"));
1819 silc_protocol_free(protocol);
1820 sock->protocol = NULL;
1821 silc_ske_free_key_material(ctx->keymat);
1823 silc_packet_context_free(ctx->packet);
1825 silc_ske_free(ctx->ske);
1826 silc_free(ctx->dest_id);
1827 silc_server_config_unref(&ctx->cconfig);
1828 silc_server_config_unref(&ctx->sconfig);
1829 silc_server_config_unref(&ctx->rconfig);
1831 silc_server_disconnect_remote(server, sock,
1832 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1833 server->stat.auth_failures++;
1836 silc_ske_free_key_material(ctx->keymat);
1838 /* Allocate internal context for the authentication protocol. This
1839 is sent as context for the protocol. */
1840 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1841 proto_ctx->server = (void *)server;
1842 proto_ctx->sock = sock;
1843 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1844 proto_ctx->responder = TRUE;
1845 proto_ctx->dest_id_type = ctx->dest_id_type;
1846 proto_ctx->dest_id = ctx->dest_id;
1847 proto_ctx->cconfig = ctx->cconfig;
1848 proto_ctx->sconfig = ctx->sconfig;
1849 proto_ctx->rconfig = ctx->rconfig;
1851 /* Free old protocol as it is finished now */
1852 silc_protocol_free(protocol);
1854 silc_packet_context_free(ctx->packet);
1856 sock->protocol = NULL;
1858 /* Allocate the authentication protocol. This is allocated here
1859 but we won't start it yet. We will be receiving party of this
1860 protocol thus we will wait that connecting party will make
1861 their first move. */
1862 SILC_LOG_DEBUG(("Starting connection authentication protocol"));
1863 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1864 &sock->protocol, proto_ctx,
1865 silc_server_accept_new_connection_final);
1867 /* Register timeout task. If the protocol is not executed inside
1868 this timelimit the connection will be terminated. */
1869 proto_ctx->timeout_task =
1870 silc_schedule_task_add(server->schedule, sock->sock,
1871 silc_server_timeout_remote,
1873 server->config->conn_auth_timeout, 0,
1878 /* After this is called, server don't wait for backup router anymore.
1879 This gets called automatically even after we have backup router
1880 connection established. */
1882 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
1884 SilcServer server = context;
1885 server->wait_backup = FALSE;
1888 /* Final part of accepting new connection. The connection has now
1889 been authenticated and keys has been exchanged. We also know whether
1890 this is client or server connection. */
1892 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1894 SilcProtocol protocol = (SilcProtocol)context;
1895 SilcServerConnAuthInternalContext *ctx =
1896 (SilcServerConnAuthInternalContext *)protocol->context;
1897 SilcServer server = (SilcServer)ctx->server;
1898 SilcSocketConnection sock = ctx->sock;
1899 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1901 SilcServerConfigConnParams *param = &server->config->param;
1903 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1904 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1905 /* Error occured during protocol */
1906 SILC_LOG_DEBUG(("Error during authentication protocol"));
1907 silc_protocol_free(protocol);
1908 sock->protocol = NULL;
1910 silc_packet_context_free(ctx->packet);
1912 silc_ske_free(ctx->ske);
1913 silc_free(ctx->dest_id);
1914 silc_server_config_unref(&ctx->cconfig);
1915 silc_server_config_unref(&ctx->sconfig);
1916 silc_server_config_unref(&ctx->rconfig);
1919 if (!SILC_IS_DISCONNECTING(sock)) {
1920 SILC_LOG_INFO(("Authentication failed for %s:%d [%s]", sock->hostname,
1922 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1923 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1924 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1926 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1929 server->stat.auth_failures++;
1933 entry->data.last_receive = time(NULL);
1935 switch (ctx->conn_type) {
1936 case SILC_SOCKET_TYPE_CLIENT:
1938 SilcClientEntry client;
1939 SilcServerConfigClient *conn = ctx->cconfig.ref_ptr;
1941 /* Verify whether this connection is after all allowed to connect */
1942 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1943 &server->config->param,
1944 conn->param, ctx->ske)) {
1945 server->stat.auth_failures++;
1949 /* If we are primary router and we have backup router configured
1950 but it has not connected to use yet, do not accept any other
1952 if (server->wait_backup && server->server_type == SILC_ROUTER &&
1953 !server->backup_router) {
1954 SilcServerConfigRouter *router;
1955 router = silc_server_config_get_backup_router(server);
1956 if (router && strcmp(server->config->server_info->primary->server_ip,
1958 silc_server_find_socket_by_host(server,
1959 SILC_SOCKET_TYPE_SERVER,
1960 router->backup_replace_ip, 0)) {
1961 SILC_LOG_INFO(("Will not accept connections because we do "
1962 "not have backup router connection established"));
1963 sock->protocol = NULL;
1964 silc_server_disconnect_remote(server, sock,
1965 SILC_STATUS_ERR_PERM_DENIED,
1966 "We do not have connection to backup "
1967 "router established, try later");
1968 silc_free(sock->user_data);
1969 server->stat.auth_failures++;
1971 /* From here on, wait 20 seconds for the backup router to appear. */
1972 silc_schedule_task_add(server->schedule, 0,
1973 silc_server_backup_router_wait,
1974 (void *)server, 20, 0,
1975 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1980 SILC_LOG_DEBUG(("Remote host is client"));
1981 SILC_LOG_INFO(("Connection %s (%s) is client", sock->hostname,
1984 /* Add the client to the client ID cache. The nickname and Client ID
1985 and other information is created after we have received NEW_CLIENT
1986 packet from client. */
1987 client = silc_idlist_add_client(server->local_list,
1988 NULL, NULL, NULL, NULL, NULL, sock, 0);
1990 SILC_LOG_ERROR(("Could not add new client to cache"));
1991 silc_free(sock->user_data);
1992 sock->protocol = NULL;
1993 silc_server_disconnect_remote(server, sock,
1994 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1995 server->stat.auth_failures++;
1998 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2001 server->stat.my_clients++;
2002 server->stat.clients++;
2003 server->stat.cell_clients++;
2005 /* Get connection parameters */
2007 param = conn->param;
2009 if (!param->keepalive_secs)
2010 param->keepalive_secs = server->config->param.keepalive_secs;
2012 if (!param->qos && server->config->param.qos) {
2013 param->qos = server->config->param.qos;
2014 param->qos_rate_limit = server->config->param.qos_rate_limit;
2015 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2016 param->qos_limit_sec = server->config->param.qos_limit_sec;
2017 param->qos_limit_usec = server->config->param.qos_limit_usec;
2020 /* Check if to be anonymous connection */
2021 if (param->anonymous)
2022 client->mode |= SILC_UMODE_ANONYMOUS;
2025 /* Add public key to hash list (for whois using attributes) */
2026 silc_hash_table_add(server->pk_hash,
2027 entry->data.public_key, client);
2029 id_entry = (void *)client;
2032 case SILC_SOCKET_TYPE_SERVER:
2033 case SILC_SOCKET_TYPE_ROUTER:
2035 SilcServerEntry new_server;
2036 bool initiator = FALSE;
2037 bool backup_local = FALSE;
2038 bool backup_router = FALSE;
2039 char *backup_replace_ip = NULL;
2040 SilcUInt16 backup_replace_port = 0;
2041 SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
2042 SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
2044 /* If we are backup router and this is incoming server connection
2045 and we do not have connection to primary router, do not allow
2047 if (server->server_type == SILC_BACKUP_ROUTER &&
2048 ctx->conn_type == SILC_SOCKET_TYPE_SERVER &&
2049 !SILC_PRIMARY_ROUTE(server)) {
2050 SILC_LOG_INFO(("Will not accept server connection because we do "
2051 "not have primary router connection established"));
2052 sock->protocol = NULL;
2053 silc_server_disconnect_remote(server, sock,
2054 SILC_STATUS_ERR_PERM_DENIED,
2055 "We do not have connection to primary "
2056 "router established, try later");
2057 silc_free(sock->user_data);
2058 server->stat.auth_failures++;
2062 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
2063 /* Verify whether this connection is after all allowed to connect */
2064 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
2065 &server->config->param,
2066 rconn ? rconn->param : NULL,
2068 silc_free(sock->user_data);
2069 server->stat.auth_failures++;
2075 param = rconn->param;
2077 if (!param->keepalive_secs)
2078 param->keepalive_secs = server->config->param.keepalive_secs;
2080 if (!param->qos && server->config->param.qos) {
2081 param->qos = server->config->param.qos;
2082 param->qos_rate_limit = server->config->param.qos_rate_limit;
2083 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2084 param->qos_limit_sec = server->config->param.qos_limit_sec;
2085 param->qos_limit_usec = server->config->param.qos_limit_usec;
2089 initiator = rconn->initiator;
2090 backup_local = rconn->backup_local;
2091 backup_router = rconn->backup_router;
2092 backup_replace_ip = rconn->backup_replace_ip;
2093 backup_replace_port = rconn->backup_replace_port;
2097 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
2098 /* Verify whether this connection is after all allowed to connect */
2099 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
2100 &server->config->param,
2101 sconn ? sconn->param : NULL,
2103 silc_free(sock->user_data);
2104 server->stat.auth_failures++;
2109 param = sconn->param;
2111 if (!param->keepalive_secs)
2112 param->keepalive_secs = server->config->param.keepalive_secs;
2114 if (!param->qos && server->config->param.qos) {
2115 param->qos = server->config->param.qos;
2116 param->qos_rate_limit = server->config->param.qos_rate_limit;
2117 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2118 param->qos_limit_sec = server->config->param.qos_limit_sec;
2119 param->qos_limit_usec = server->config->param.qos_limit_usec;
2123 backup_router = sconn->backup_router;
2127 /* If we are primary router and we have backup router configured
2128 but it has not connected to use yet, do not accept any other
2130 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2131 !server->backup_router && !backup_router) {
2132 SilcServerConfigRouter *router;
2133 router = silc_server_config_get_backup_router(server);
2134 if (router && strcmp(server->config->server_info->primary->server_ip,
2136 silc_server_find_socket_by_host(server,
2137 SILC_SOCKET_TYPE_SERVER,
2138 router->backup_replace_ip, 0)) {
2139 SILC_LOG_INFO(("Will not accept connections because we do "
2140 "not have backup router connection established"));
2141 sock->protocol = NULL;
2142 silc_server_disconnect_remote(server, sock,
2143 SILC_STATUS_ERR_PERM_DENIED,
2144 "We do not have connection to backup "
2145 "router established, try later");
2146 silc_free(sock->user_data);
2147 server->stat.auth_failures++;
2149 /* From here on, wait 20 seconds for the backup router to appear. */
2150 silc_schedule_task_add(server->schedule, 0,
2151 silc_server_backup_router_wait,
2152 (void *)server, 20, 0,
2153 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2158 SILC_LOG_DEBUG(("Remote host is %s",
2159 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2160 "server" : (backup_router ?
2161 "backup router" : "router")));
2162 SILC_LOG_INFO(("Connection %s (%s) is %s", sock->hostname,
2163 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2164 "server" : (backup_router ?
2165 "backup router" : "router")));
2167 /* Add the server into server cache. The server name and Server ID
2168 is updated after we have received NEW_SERVER packet from the
2169 server. We mark ourselves as router for this server if we really
2172 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2173 server->local_list : (backup_router ?
2174 server->local_list :
2175 server->global_list)),
2177 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2178 SILC_SERVER : SILC_ROUTER),
2180 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2181 server->id_entry : (backup_router ?
2182 server->id_entry : NULL)),
2185 SILC_LOG_ERROR(("Could not add new server to cache"));
2186 silc_free(sock->user_data);
2187 sock->protocol = NULL;
2188 silc_server_disconnect_remote(server, sock,
2189 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2190 server->stat.auth_failures++;
2193 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2195 id_entry = (void *)new_server;
2197 /* If the incoming connection is router and marked as backup router
2198 then add it to be one of our backups */
2199 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
2200 /* Change it back to SERVER type since that's what it really is. */
2202 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
2203 new_server->server_type = SILC_BACKUP_ROUTER;
2205 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2206 ("Backup router %s is now online",
2209 /* Remove the backup waiting with timeout */
2210 silc_schedule_task_add(server->schedule, 0,
2211 silc_server_backup_router_wait,
2212 (void *)server, 10, 0,
2213 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2217 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
2218 server->stat.my_servers++;
2220 server->stat.my_routers++;
2221 server->stat.routers++;
2223 server->stat.servers++;
2225 /* Check whether this connection is to be our primary router connection
2226 if we do not already have the primary route. */
2227 if (!backup_router &&
2228 server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
2229 if (silc_server_config_is_primary_route(server) && !initiator)
2232 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2233 server->standalone = FALSE;
2234 if (!server->id_entry->router) {
2235 server->id_entry->router = id_entry;
2236 server->router = id_entry;
2247 sock->type = ctx->conn_type;
2249 /* Add the common data structure to the ID entry. */
2250 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
2252 /* Add to sockets internal pointer for fast referencing */
2253 silc_free(sock->user_data);
2254 sock->user_data = id_entry;
2256 /* Connection has been fully established now. Everything is ok. */
2257 SILC_LOG_DEBUG(("New connection authenticated"));
2259 /* Perform keepalive. */
2260 if (param->keepalive_secs)
2261 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
2262 silc_server_perform_heartbeat,
2265 /* Perform Quality of Service */
2267 silc_socket_set_qos(sock, param->qos_rate_limit, param->qos_bytes_limit,
2268 param->qos_limit_sec, param->qos_limit_usec,
2272 if (sock->protocol == protocol)
2273 silc_protocol_free(protocol);
2275 silc_packet_context_free(ctx->packet);
2277 silc_ske_free(ctx->ske);
2278 silc_free(ctx->dest_id);
2279 silc_server_config_unref(&ctx->cconfig);
2280 silc_server_config_unref(&ctx->sconfig);
2281 silc_server_config_unref(&ctx->rconfig);
2283 sock->protocol = NULL;
2286 /* This function is used to read packets from network and send packets to
2287 network. This is usually a generic task. */
2289 SILC_TASK_CALLBACK(silc_server_packet_process)
2291 SilcServer server = (SilcServer)context;
2292 SilcSocketConnection sock = server->sockets[fd];
2293 SilcIDListData idata;
2294 SilcCipher cipher = NULL;
2295 SilcHmac hmac = NULL;
2296 SilcUInt32 sequence = 0;
2297 bool local_is_router;
2301 SILC_LOG_DEBUG(("Unknown socket connection"));
2305 /* Packet sending */
2307 if (type == SILC_TASK_WRITE) {
2308 /* Do not send data to disconnected connection */
2309 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2310 SILC_LOG_DEBUG(("Disconnected socket connection, cannot send"));
2311 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
2312 SILC_UNSET_OUTBUF_PENDING(sock);
2313 silc_buffer_clear(sock->outbuf);
2317 server->stat.packets_sent++;
2319 /* Send the packet */
2320 ret = silc_packet_send(sock, TRUE);
2322 /* If returned -2 could not write to connection now, will do
2327 /* The packet has been sent and now it is time to set the connection
2328 back to only for input. When there is again some outgoing data
2329 available for this connection it will be set for output as well.
2330 This call clears the output setting and sets it only for input. */
2331 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
2332 SILC_UNSET_OUTBUF_PENDING(sock);
2333 silc_buffer_clear(sock->outbuf);
2336 SILC_LOG_ERROR(("Error sending packet to connection "
2337 "%s:%d [%s]", sock->hostname, sock->port,
2338 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2339 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2340 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2343 if (sock->user_data) {
2344 /* If backup then mark that resuming will not be allowed */
2345 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2346 sock->type == SILC_SOCKET_TYPE_SERVER) {
2347 SilcServerEntry server_entry = sock->user_data;
2348 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2349 server->backup_closed = TRUE;
2352 silc_server_free_sock_user_data(server, sock, NULL);
2354 SILC_SET_DISCONNECTING(sock);
2355 silc_server_close_connection(server, sock);
2360 /* Packet receiving */
2362 /* Read some data from connection */
2363 ret = silc_packet_receive(sock);
2367 SILC_LOG_ERROR(("Error receiving packet from connection "
2368 "%s:%d [%s] %s", sock->hostname, sock->port,
2369 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2370 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2371 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2372 "Router"), strerror(errno)));
2374 if (sock->user_data) {
2375 /* If backup then mark that resuming will not be allowed */
2376 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2377 sock->type == SILC_SOCKET_TYPE_SERVER) {
2378 SilcServerEntry server_entry = sock->user_data;
2379 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2380 server->backup_closed = TRUE;
2383 silc_server_free_sock_user_data(server, sock, NULL);
2385 SILC_SET_DISCONNECTING(sock);
2386 silc_server_close_connection(server, sock);
2393 SILC_LOG_DEBUG(("Read EOF"));
2395 /* If connection is disconnecting already we will finally
2396 close the connection */
2397 if (SILC_IS_DISCONNECTING(sock)) {
2398 if (sock->user_data)
2399 silc_server_free_sock_user_data(server, sock, NULL);
2400 silc_server_close_connection(server, sock);
2404 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
2406 if (sock->user_data) {
2409 /* If backup disconnected then mark that resuming will not be allowed */
2410 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2411 sock->type == SILC_SOCKET_TYPE_SERVER && sock->user_data) {
2412 SilcServerEntry server_entry = sock->user_data;
2413 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2414 server->backup_closed = TRUE;
2417 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
2418 silc_server_free_sock_user_data(server, sock, tmp);
2420 silc_server_free_sock_user_data(server, sock, NULL);
2421 } else if (server->router_conn && server->router_conn->sock == sock &&
2422 !server->router && server->standalone) {
2423 silc_server_create_connections(server);
2426 SILC_SET_DISCONNECTING(sock);
2427 silc_server_close_connection(server, sock);
2431 /* If connection is disconnecting or disconnected we will ignore
2433 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2434 SILC_LOG_DEBUG(("Ignoring read data from disconnected connection"));
2438 /* Get keys and stuff from ID entry */
2439 idata = (SilcIDListData)sock->user_data;
2441 cipher = idata->receive_key;
2442 hmac = idata->hmac_receive;
2443 sequence = idata->psn_receive;
2446 /* Then, process the packet. This will call the parser that will then
2447 decrypt and parse the packet. */
2449 local_is_router = (server->server_type == SILC_ROUTER);
2451 /* If socket connection is our primary, we are backup and we are doing
2452 backup resuming, we won't process the packet as being a router
2453 (affects channel message decryption). */
2454 if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
2455 SILC_PRIMARY_ROUTE(server) == sock)
2456 local_is_router = FALSE;
2458 ret = silc_packet_receive_process(sock, local_is_router,
2459 cipher, hmac, sequence,
2460 silc_server_packet_parse, server);
2462 /* If processing failed the connection is closed. */
2464 /* On packet processing errors we may close our primary router
2465 connection but won't become primary router if we are the backup
2466 since this is local error condition. */
2467 if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
2468 server->backup_noswitch = TRUE;
2470 if (sock->user_data) {
2471 /* If we are router and backup errorred then mark that resuming
2472 will not be allowed */
2473 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2474 sock->type == SILC_SOCKET_TYPE_SERVER) {
2475 SilcServerEntry server_entry = sock->user_data;
2476 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2477 server->backup_closed = TRUE;
2480 silc_server_free_sock_user_data(server, sock, NULL);
2482 SILC_SET_DISCONNECTING(sock);
2483 silc_server_close_connection(server, sock);
2487 /* Parses whole packet, received earlier. */
2489 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
2491 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
2492 SilcServer server = (SilcServer)parse_ctx->context;
2493 SilcSocketConnection sock = parse_ctx->sock;
2494 SilcPacketContext *packet = parse_ctx->packet;
2495 SilcIDListData idata = (SilcIDListData)sock->user_data;
2498 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2499 SILC_LOG_DEBUG(("Connection is disconnected"));
2503 server->stat.packets_received++;
2505 /* Parse the packet */
2506 if (parse_ctx->normal)
2507 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
2509 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
2511 /* If entry is disabled ignore what we got. */
2512 if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
2513 ret != SILC_PACKET_HEARTBEAT && ret != SILC_PACKET_RESUME_ROUTER &&
2514 ret != SILC_PACKET_REKEY && ret != SILC_PACKET_REKEY_DONE) {
2515 SILC_LOG_DEBUG(("Connection is disabled"));
2519 if (ret == SILC_PACKET_NONE) {
2520 SILC_LOG_DEBUG(("Error parsing packet"));
2524 /* Check that the the current client ID is same as in the client's packet. */
2525 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2526 SilcClientEntry client = (SilcClientEntry)sock->user_data;
2527 if (client && client->id && packet->src_id) {
2528 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
2529 packet->src_id_type);
2530 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
2532 SILC_LOG_DEBUG(("Packet source is not same as sender"));
2539 if (server->server_type == SILC_ROUTER) {
2540 /* Route the packet if it is not destined to us. Other ID types but
2541 server are handled separately after processing them. */
2542 if (packet->dst_id && !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
2543 packet->dst_id_type == SILC_ID_SERVER &&
2544 sock->type != SILC_SOCKET_TYPE_CLIENT &&
2545 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
2547 /* Route the packet to fastest route for the destination ID */
2548 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
2549 packet->dst_id_type);
2552 silc_server_packet_route(server,
2553 silc_server_route_get(server, id,
2554 packet->dst_id_type),
2561 /* Parse the incoming packet type */
2562 silc_server_packet_parse_type(server, sock, packet);
2564 /* Broadcast packet if it is marked as broadcast packet and it is
2565 originated from router and we are router. */
2566 if (server->server_type == SILC_ROUTER &&
2567 sock->type == SILC_SOCKET_TYPE_ROUTER &&
2568 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
2569 /* Broadcast to our primary route */
2570 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
2572 /* If we have backup routers then we need to feed all broadcast
2573 data to those servers. */
2574 silc_server_backup_broadcast(server, sock, packet);
2578 silc_packet_context_free(packet);
2579 silc_free(parse_ctx);
2582 /* Parser callback called by silc_packet_receive_process. This merely
2583 registers timeout that will handle the actual parsing when appropriate. */
2585 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
2588 SilcServer server = (SilcServer)context;
2589 SilcSocketConnection sock = parser_context->sock;
2590 SilcIDListData idata = (SilcIDListData)sock->user_data;
2594 idata->psn_receive = parser_context->packet->sequence + 1;
2596 /* If protocol for this connection is key exchange or rekey then we'll
2597 process all packets synchronously, since there might be packets in
2598 queue that we are not able to decrypt without first processing the
2599 packets before them. */
2600 if (sock->protocol && sock->protocol->protocol &&
2601 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2602 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2603 silc_server_packet_parse_real(server->schedule, server, 0, sock->sock,
2606 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2607 SILC_LOG_DEBUG(("Connection is disconnected"));
2611 /* Reprocess data since we'll return FALSE here. This is because
2612 the idata->receive_key might have become valid in the last packet
2613 and we want to call this processor with valid cipher. */
2615 ret = silc_packet_receive_process(
2616 sock, server->server_type == SILC_ROUTER,
2618 idata->hmac_receive, idata->psn_receive,
2619 silc_server_packet_parse, server);
2621 ret = silc_packet_receive_process(
2622 sock, server->server_type == SILC_ROUTER,
2624 silc_server_packet_parse, server);
2627 /* On packet processing errors we may close our primary router
2628 connection but won't become primary router if we are the backup
2629 since this is local error condition. */
2630 if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
2631 server->backup_noswitch = TRUE;
2633 if (sock->user_data)
2634 silc_server_free_sock_user_data(server, sock, NULL);
2635 SILC_SET_DISCONNECTING(sock);
2636 silc_server_close_connection(server, sock);
2642 switch (sock->type) {
2643 case SILC_SOCKET_TYPE_UNKNOWN:
2644 case SILC_SOCKET_TYPE_CLIENT:
2645 /* Parse the packet with timeout */
2646 silc_schedule_task_add(server->schedule, sock->sock,
2647 silc_server_packet_parse_real,
2648 (void *)parser_context, 0, 100000,
2650 SILC_TASK_PRI_NORMAL);
2652 case SILC_SOCKET_TYPE_SERVER:
2653 case SILC_SOCKET_TYPE_ROUTER:
2654 /* Packets from servers are parsed immediately */
2655 silc_server_packet_parse_real(server->schedule, server, 0, sock->sock,
2663 /* Parses the packet type and calls what ever routines the packet type
2664 requires. This is done for all incoming packets. */
2666 void silc_server_packet_parse_type(SilcServer server,
2667 SilcSocketConnection sock,
2668 SilcPacketContext *packet)
2670 SilcPacketType type = packet->type;
2671 SilcIDListData idata = (SilcIDListData)sock->user_data;
2673 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
2674 silc_get_packet_name(type), packet->flags));
2676 /* Parse the packet type */
2678 case SILC_PACKET_DISCONNECT:
2681 char *message = NULL;
2683 if (packet->flags & SILC_PACKET_FLAG_LIST)
2685 if (packet->buffer->len < 1)
2688 status = (SilcStatus)packet->buffer->data[0];
2689 if (packet->buffer->len > 1 &&
2690 silc_utf8_valid(packet->buffer->data + 1, packet->buffer->len - 1))
2691 message = silc_memdup(packet->buffer->data + 1,
2692 packet->buffer->len - 1);
2694 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s",
2695 sock->ip, sock->hostname,
2696 silc_get_status_message(status), status,
2697 message ? message : ""));
2700 /* Do not switch to backup in case of error */
2701 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
2703 /* If backup disconnected then mark that resuming will not be allowed */
2704 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2705 sock->type == SILC_SOCKET_TYPE_SERVER && sock->user_data) {
2706 SilcServerEntry server_entry = sock->user_data;
2707 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2708 server->backup_closed = TRUE;
2711 /* Handle the disconnection from our end too */
2712 if (sock->user_data && SILC_IS_LOCAL(sock->user_data))
2713 silc_server_free_sock_user_data(server, sock, NULL);
2714 SILC_SET_DISCONNECTING(sock);
2715 silc_server_close_connection(server, sock);
2716 server->backup_noswitch = FALSE;
2720 case SILC_PACKET_SUCCESS:
2722 * Success received for something. For now we can have only
2723 * one protocol for connection executing at once hence this
2724 * success message is for whatever protocol is executing currently.
2726 if (packet->flags & SILC_PACKET_FLAG_LIST)
2729 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2732 case SILC_PACKET_FAILURE:
2734 * Failure received for something. For now we can have only
2735 * one protocol for connection executing at once hence this
2736 * failure message is for whatever protocol is executing currently.
2738 if (packet->flags & SILC_PACKET_FLAG_LIST)
2741 /* Check for failure START_USE from backup router */
2742 if (server->server_type == SILC_SERVER &&
2743 server->backup_primary && packet->buffer->len == 4) {
2745 SILC_GET32_MSB(type, packet->buffer->data);
2746 if (type == SILC_SERVER_BACKUP_START_USE) {
2747 /* Attempt to reconnect to primary */
2748 SILC_LOG_DEBUG(("Received failed START_USE from backup %s", sock->ip));
2750 /* Default action is to disconnect from backup and reconnect to
2751 primary. Since this failure can happen during switching to
2752 backup (backup might have not noticed the primary going down yet),
2753 we will wait a while and keep sending START_USE to backup.
2754 Only after that we'll give up. */
2755 if (server->router == sock->user_data &&
2756 (time(0) - server->router_connect) < 30) {
2757 SILC_LOG_DEBUG(("Resending START_USE to backup router"));
2758 silc_server_backup_send_start_use(server, sock, FALSE);
2762 /* If backup is our primary, disconnect now. */
2763 if (server->router == sock->user_data) {
2764 if (sock->user_data)
2765 silc_server_free_sock_user_data(server, sock, NULL);
2766 SILC_SET_DISCONNECTING(sock);
2767 silc_server_close_connection(server, sock);
2771 silc_server_create_connections(server);
2775 /* Execute protocol */
2776 if (sock->protocol) {
2777 sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
2778 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2783 case SILC_PACKET_REJECT:
2784 if (packet->flags & SILC_PACKET_FLAG_LIST)
2789 case SILC_PACKET_NOTIFY:
2791 * Received notify packet. Server can receive notify packets from
2792 * router. Server then relays the notify messages to clients if needed.
2794 if (packet->flags & SILC_PACKET_FLAG_LIST)
2795 silc_server_notify_list(server, sock, packet);
2797 silc_server_notify(server, sock, packet);
2803 case SILC_PACKET_CHANNEL_MESSAGE:
2805 * Received channel message. Channel messages are special packets
2806 * (although probably most common ones) thus they are handled
2809 if (packet->flags & SILC_PACKET_FLAG_LIST)
2811 idata->last_receive = time(NULL);
2812 silc_server_channel_message(server, sock, packet);
2815 case SILC_PACKET_CHANNEL_KEY:
2817 * Received key for channel. As channels are created by the router
2818 * the keys are as well. We will distribute the key to all of our
2819 * locally connected clients on the particular channel. Router
2820 * never receives this channel and thus is ignored.
2822 if (packet->flags & SILC_PACKET_FLAG_LIST)
2824 silc_server_channel_key(server, sock, packet);
2830 case SILC_PACKET_COMMAND:
2832 * Recived command. Processes the command request and allocates the
2833 * command context and calls the command.
2835 if (packet->flags & SILC_PACKET_FLAG_LIST)
2837 silc_server_command_process(server, sock, packet);
2840 case SILC_PACKET_COMMAND_REPLY:
2842 * Received command reply packet. Received command reply to command. It
2843 * may be reply to command sent by us or reply to command sent by client
2844 * that we've routed further.
2846 if (packet->flags & SILC_PACKET_FLAG_LIST)
2848 silc_server_command_reply(server, sock, packet);
2852 * Private Message packets
2854 case SILC_PACKET_PRIVATE_MESSAGE:
2856 * Received private message packet. The packet is coming from either
2859 if (packet->flags & SILC_PACKET_FLAG_LIST)
2861 idata->last_receive = time(NULL);
2862 silc_server_private_message(server, sock, packet);
2865 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
2867 * Private message key packet.
2869 if (packet->flags & SILC_PACKET_FLAG_LIST)
2871 silc_server_private_message_key(server, sock, packet);
2875 * Key Exchange protocol packets
2877 case SILC_PACKET_KEY_EXCHANGE:
2878 if (packet->flags & SILC_PACKET_FLAG_LIST)
2881 if (sock->protocol && sock->protocol->protocol &&
2882 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
2883 SilcServerKEInternalContext *proto_ctx =
2884 (SilcServerKEInternalContext *)sock->protocol->context;
2886 proto_ctx->packet = silc_packet_context_dup(packet);
2888 /* Let the protocol handle the packet */
2889 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
2891 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
2892 "protocol active (%s:%d [%s]).", sock->hostname,
2894 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2895 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2896 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2901 case SILC_PACKET_KEY_EXCHANGE_1:
2902 if (packet->flags & SILC_PACKET_FLAG_LIST)
2905 if (sock->protocol && sock->protocol->protocol &&
2906 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2907 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2909 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2910 SilcServerRekeyInternalContext *proto_ctx =
2911 (SilcServerRekeyInternalContext *)sock->protocol->context;
2913 if (proto_ctx->packet)
2914 silc_packet_context_free(proto_ctx->packet);
2916 proto_ctx->packet = silc_packet_context_dup(packet);
2918 /* Let the protocol handle the packet */
2919 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2921 SilcServerKEInternalContext *proto_ctx =
2922 (SilcServerKEInternalContext *)sock->protocol->context;
2924 if (proto_ctx->packet)
2925 silc_packet_context_free(proto_ctx->packet);
2927 proto_ctx->packet = silc_packet_context_dup(packet);
2928 proto_ctx->dest_id_type = packet->src_id_type;
2929 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2930 packet->src_id_type);
2931 if (!proto_ctx->dest_id)
2934 /* Let the protocol handle the packet */
2935 silc_protocol_execute(sock->protocol, server->schedule,
2939 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
2940 "protocol active (%s:%d [%s]).", sock->hostname,
2942 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2943 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2944 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2949 case SILC_PACKET_KEY_EXCHANGE_2:
2950 if (packet->flags & SILC_PACKET_FLAG_LIST)
2953 if (sock->protocol && sock->protocol->protocol &&
2954 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2955 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2957 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2958 SilcServerRekeyInternalContext *proto_ctx =
2959 (SilcServerRekeyInternalContext *)sock->protocol->context;
2961 if (proto_ctx->packet)
2962 silc_packet_context_free(proto_ctx->packet);
2964 proto_ctx->packet = silc_packet_context_dup(packet);
2966 /* Let the protocol handle the packet */
2967 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2969 SilcServerKEInternalContext *proto_ctx =
2970 (SilcServerKEInternalContext *)sock->protocol->context;
2972 if (proto_ctx->packet)
2973 silc_packet_context_free(proto_ctx->packet);
2975 proto_ctx->packet = silc_packet_context_dup(packet);
2976 proto_ctx->dest_id_type = packet->src_id_type;
2977 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2978 packet->src_id_type);
2979 if (!proto_ctx->dest_id)
2982 /* Let the protocol handle the packet */
2983 silc_protocol_execute(sock->protocol, server->schedule,
2987 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2988 "protocol active (%s:%d [%s]).", sock->hostname,
2990 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2991 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2992 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2997 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2999 * Connection authentication request packet. When we receive this packet
3000 * we will send to the other end information about our mandatory
3001 * authentication method for the connection. This packet maybe received
3004 if (packet->flags & SILC_PACKET_FLAG_LIST)
3006 silc_server_connection_auth_request(server, sock, packet);
3010 * Connection Authentication protocol packets
3012 case SILC_PACKET_CONNECTION_AUTH:
3013 /* Start of the authentication protocol. We receive here the
3014 authentication data and will verify it. */
3015 if (packet->flags & SILC_PACKET_FLAG_LIST)
3018 if (sock->protocol && sock->protocol->protocol->type
3019 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
3021 SilcServerConnAuthInternalContext *proto_ctx =
3022 (SilcServerConnAuthInternalContext *)sock->protocol->context;
3024 proto_ctx->packet = silc_packet_context_dup(packet);
3026 /* Let the protocol handle the packet */
3027 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
3029 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
3030 "protocol active (%s:%d [%s]).", sock->hostname,
3032 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3033 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3034 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3039 case SILC_PACKET_NEW_ID:
3041 * Received New ID packet. This includes some new ID that has been
3042 * created. It may be for client, server or channel. This is the way
3043 * to distribute information about new registered entities in the
3046 if (packet->flags & SILC_PACKET_FLAG_LIST)
3047 silc_server_new_id_list(server, sock, packet);
3049 silc_server_new_id(server, sock, packet);
3052 case SILC_PACKET_NEW_CLIENT:
3054 * Received new client packet. This includes client information that
3055 * we will use to create initial client ID. After creating new
3056 * ID we will send it to the client.
3058 if (packet->flags & SILC_PACKET_FLAG_LIST)
3060 silc_server_new_client(server, sock, packet);
3063 case SILC_PACKET_NEW_SERVER:
3065 * Received new server packet. This includes Server ID and some other
3066 * information that we may save. This is received after server has
3069 if (packet->flags & SILC_PACKET_FLAG_LIST)
3071 silc_server_new_server(server, sock, packet);
3074 case SILC_PACKET_NEW_CHANNEL:
3076 * Received new channel packet. Information about new channel in the
3077 * network are distributed using this packet.
3079 if (packet->flags & SILC_PACKET_FLAG_LIST)
3080 silc_server_new_channel_list(server, sock, packet);
3082 silc_server_new_channel(server, sock, packet);
3085 case SILC_PACKET_HEARTBEAT:
3087 * Received heartbeat.
3089 if (packet->flags & SILC_PACKET_FLAG_LIST)
3093 case SILC_PACKET_KEY_AGREEMENT:
3095 * Received heartbeat.
3097 if (packet->flags & SILC_PACKET_FLAG_LIST)
3099 silc_server_key_agreement(server, sock, packet);
3102 case SILC_PACKET_REKEY:
3104 * Received re-key packet. The sender wants to regenerate the session
3107 if (packet->flags & SILC_PACKET_FLAG_LIST)
3109 silc_server_rekey(server, sock, packet);
3112 case SILC_PACKET_REKEY_DONE:
3114 * The re-key is done.
3116 if (packet->flags & SILC_PACKET_FLAG_LIST)
3119 if (sock->protocol && sock->protocol->protocol &&
3120 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
3122 SilcServerRekeyInternalContext *proto_ctx =
3123 (SilcServerRekeyInternalContext *)sock->protocol->context;
3125 if (proto_ctx->packet)
3126 silc_packet_context_free(proto_ctx->packet);
3128 proto_ctx->packet = silc_packet_context_dup(packet);
3130 /* Let the protocol handle the packet */
3131 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
3133 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
3134 "protocol active (%s:%d [%s]).", sock->hostname,
3136 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3137 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3138 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3143 case SILC_PACKET_FTP:
3145 if (packet->flags & SILC_PACKET_FLAG_LIST)
3147 silc_server_ftp(server, sock, packet);
3150 case SILC_PACKET_RESUME_CLIENT:
3152 if (packet->flags & SILC_PACKET_FLAG_LIST)
3154 silc_server_resume_client(server, sock, packet);
3157 case SILC_PACKET_RESUME_ROUTER:
3158 /* Resume router packet received. This packet is received for backup
3159 router resuming protocol. */
3160 if (packet->flags & SILC_PACKET_FLAG_LIST)
3162 silc_server_backup_resume_router(server, sock, packet);
3166 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
3171 /* Creates connection to a remote router. */
3173 void silc_server_create_connection(SilcServer server,
3174 const char *remote_host, SilcUInt32 port)
3176 SilcServerConnection sconn;
3178 /* Allocate connection object for hold connection specific stuff. */
3179 sconn = silc_calloc(1, sizeof(*sconn));
3180 sconn->remote_host = strdup(remote_host);
3181 sconn->remote_port = port;
3182 sconn->no_reconnect = TRUE;
3184 silc_schedule_task_add(server->schedule, 0,
3185 silc_server_connect_router,
3186 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
3187 SILC_TASK_PRI_NORMAL);
3190 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3192 SilcServer server = app_context;
3193 SilcSocketConnection sock = context;
3195 SILC_LOG_DEBUG(("Deleting socket %p", sock));
3197 /* Close the actual connection */
3198 silc_net_close_connection(sock->sock);
3199 server->sockets[sock->sock] = NULL;
3201 /* We won't listen for this connection anymore */
3202 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
3203 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
3205 silc_socket_free(sock);
3208 /* Closes connection to socket connection */
3210 void silc_server_close_connection(SilcServer server,
3211 SilcSocketConnection sock)
3215 if (SILC_IS_DISCONNECTED(sock)) {
3216 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
3217 silc_schedule_task_add(server->schedule, sock->sock,
3218 silc_server_close_connection_final,
3219 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
3220 SILC_TASK_PRI_NORMAL);
3221 server->sockets[sock->sock] = NULL;
3225 /* If any protocol is active cancel its execution. It will call
3226 the final callback which will finalize the disconnection. */
3227 if (sock->protocol && sock->protocol->protocol &&
3228 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3229 SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
3230 silc_protocol_cancel(sock->protocol, server->schedule);
3231 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3232 silc_protocol_execute_final(sock->protocol, server->schedule);
3233 sock->protocol = NULL;
3237 memset(tmp, 0, sizeof(tmp));
3238 silc_socket_get_error(sock, tmp, sizeof(tmp));
3239 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", sock->hostname,
3241 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3242 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3243 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3244 "Router"), tmp[0] ? tmp : ""));
3246 SILC_SET_DISCONNECTED(sock);
3247 silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3248 silc_schedule_task_add(server->schedule, sock->sock,
3249 silc_server_close_connection_final,
3250 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
3251 SILC_TASK_PRI_NORMAL);
3252 server->sockets[sock->sock] = NULL;
3255 /* Sends disconnect message to remote connection and disconnects the
3256 connection. NOTE: If this is called from protocol callback
3257 then sock->protocol must be set NULL before calling this, since
3258 this routine dispatches protocol callbacks too. */
3260 void silc_server_disconnect_remote(SilcServer server,
3261 SilcSocketConnection sock,
3262 SilcStatus status, ...)
3265 unsigned char buf[512];
3273 if (SILC_IS_DISCONNECTING(sock)) {
3274 SILC_SET_DISCONNECTED(sock);
3275 silc_server_close_connection(server, sock);
3279 memset(buf, 0, sizeof(buf));
3280 va_start(ap, status);
3281 cp = va_arg(ap, char *);
3283 vsnprintf(buf, sizeof(buf) - 1, cp, ap);
3288 SILC_LOG_DEBUG(("Disconnecting remote host"));
3290 /* Notify remote end that the conversation is over. The notify message
3291 is tried to be sent immediately. */
3295 len += silc_utf8_encoded_len(buf, strlen(buf), SILC_STRING_ASCII);
3297 buffer = silc_buffer_alloc_size(len);
3301 buffer->data[0] = status;
3303 silc_utf8_encode(buf, strlen(buf), SILC_STRING_ASCII, buffer->data + 1,
3305 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
3306 buffer->data, buffer->len, TRUE);
3307 silc_buffer_free(buffer);
3310 silc_server_packet_queue_purge(server, sock);
3312 /* Mark the connection to be disconnected */
3313 SILC_SET_DISCONNECTING(sock);
3314 silc_server_close_connection(server, sock);
3317 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
3319 SilcServer server = app_context;
3320 SilcClientEntry client = context;
3322 assert(!silc_hash_table_count(client->channels));
3324 silc_idlist_del_data(client);
3325 silc_idcache_purge_by_context(server->local_list->clients, client);
3328 /* Frees client data and notifies about client's signoff. */
3330 void silc_server_free_client_data(SilcServer server,
3331 SilcSocketConnection sock,
3332 SilcClientEntry client,
3334 const char *signoff)
3336 SILC_LOG_DEBUG(("Freeing client data"));
3338 /* If there is pending outgoing data for the client then purge it
3339 to the network before removing the client entry. */
3340 silc_server_packet_queue_purge(server, sock);
3343 /* Check if anyone is watching this nickname */
3344 if (server->server_type == SILC_ROUTER)
3345 silc_server_check_watcher_list(server, client, NULL,
3346 SILC_NOTIFY_TYPE_SIGNOFF);
3348 /* Send SIGNOFF notify to routers. */
3350 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3351 SILC_BROADCAST(server), client->id,
3355 /* Remove client from all channels */
3357 silc_server_remove_from_channels(server, NULL, client,
3358 TRUE, (char *)signoff, TRUE, FALSE);
3360 silc_server_remove_from_channels(server, NULL, client,
3361 FALSE, NULL, FALSE, FALSE);
3363 /* Remove this client from watcher list if it is */
3364 silc_server_del_from_watcher_list(server, client);
3366 /* Remove this client from the public key hash list */
3367 if (client->data.public_key)
3368 silc_hash_table_del_by_context(server->pk_hash,
3369 client->data.public_key, client);
3371 /* Update statistics */
3372 server->stat.my_clients--;
3373 server->stat.clients--;
3374 if (server->stat.cell_clients)
3375 server->stat.cell_clients--;
3376 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3377 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3378 silc_schedule_task_del_by_context(server->schedule, client);
3380 /* We will not delete the client entry right away. We will take it
3381 into history (for WHOWAS command) for 5 minutes, unless we're
3382 shutting down server. */
3383 if (!server->server_shutdown) {
3384 silc_schedule_task_add(server->schedule, 0,
3385 silc_server_free_client_data_timeout,
3387 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
3388 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3389 client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3391 client->router = NULL;
3392 client->connection = NULL;
3394 /* Delete directly since we're shutting down server */
3395 silc_idlist_del_data(client);
3396 silc_idlist_del_client(server->local_list, client);
3400 /* Frees user_data pointer from socket connection object. This also sends
3401 appropriate notify packets to the network to inform about leaving
3404 void silc_server_free_sock_user_data(SilcServer server,
3405 SilcSocketConnection sock,
3406 const char *signoff_message)
3409 /* If any protocol is active cancel its execution */
3410 if (sock->protocol && sock->protocol->protocol &&
3411 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3412 SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
3413 silc_protocol_cancel(sock->protocol, server->schedule);
3414 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3415 silc_protocol_execute_final(sock->protocol, server->schedule);
3416 sock->protocol = NULL;
3419 switch (sock->type) {
3420 case SILC_SOCKET_TYPE_CLIENT:
3422 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
3423 silc_server_free_client_data(server, sock, user_data, TRUE,
3427 case SILC_SOCKET_TYPE_SERVER:
3428 case SILC_SOCKET_TYPE_ROUTER:
3430 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
3431 SilcServerEntry backup_router = NULL;
3433 SILC_LOG_DEBUG(("Freeing server data"));
3436 backup_router = silc_server_backup_get(server, user_data->id);
3438 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3439 backup_router == server->id_entry &&
3440 sock->type != SILC_SOCKET_TYPE_ROUTER)
3441 backup_router = NULL;
3443 if (server->server_shutdown || server->backup_noswitch)
3444 backup_router = NULL;
3446 /* If this was our primary router connection then we're lost to
3447 the outside world. */
3448 if (server->router == user_data) {
3449 /* Check whether we have a backup router connection */
3450 if (!backup_router || backup_router == user_data) {
3451 if (!server->no_reconnect)
3452 silc_server_create_connections(server);
3453 server->id_entry->router = NULL;
3454 server->router = NULL;
3455 server->standalone = TRUE;
3456 server->backup_primary = FALSE;
3457 backup_router = NULL;
3459 if (server->id_entry != backup_router) {
3460 SILC_LOG_INFO(("New primary router is backup router %s",
3461 backup_router->server_name));
3462 server->id_entry->router = backup_router;
3463 server->router = backup_router;
3464 server->router_connect = time(0);
3465 server->backup_primary = TRUE;
3466 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3468 /* Send START_USE to backup router to indicate we have switched */
3469 silc_server_backup_send_start_use(server,
3470 backup_router->connection,
3473 SILC_LOG_INFO(("We are now new primary router in this cell"));
3474 server->id_entry->router = NULL;
3475 server->router = NULL;
3476 server->standalone = TRUE;
3479 /* We stop here to take a breath */
3482 if (server->backup_router) {
3483 server->server_type = SILC_ROUTER;
3485 /* We'll need to constantly try to reconnect to the primary
3486 router so that we'll see when it comes back online. */
3487 silc_server_backup_reconnect(server, sock->ip, sock->port,
3488 silc_server_backup_connected,
3492 /* Mark this connection as replaced */
3493 silc_server_backup_replaced_add(server, user_data->id,
3496 } else if (backup_router) {
3497 SILC_LOG_INFO(("Enabling the use of backup router %s",
3498 backup_router->server_name));
3500 /* Mark this connection as replaced */
3501 silc_server_backup_replaced_add(server, user_data->id,
3503 } else if (server->server_type == SILC_SERVER &&
3504 sock->type == SILC_SOCKET_TYPE_ROUTER) {
3505 /* Reconnect to the router (backup) */
3506 if (!server->no_reconnect)
3507 silc_server_create_connections(server);
3510 if (user_data->server_name)
3511 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3512 ("Server %s signoff", user_data->server_name));
3514 if (!backup_router) {
3515 /* Remove all servers that are originated from this server, and
3516 remove the clients of those servers too. */
3517 silc_server_remove_servers_by_server(server, user_data, TRUE);
3520 /* Remove the clients that this server owns as they will become
3521 invalid now too. For backup router the server is actually
3522 coming from the primary router, so mark that as the owner
3524 if (server->server_type == SILC_BACKUP_ROUTER &&
3525 sock->type == SILC_SOCKET_TYPE_SERVER)
3526 silc_server_remove_clients_by_server(server, server->router,
3530 silc_server_remove_clients_by_server(server, user_data,
3533 /* Remove channels owned by this server */
3534 if (server->server_type == SILC_SERVER)
3535 silc_server_remove_channels_by_server(server, user_data);
3537 /* Enable local server connections that may be disabled */
3538 silc_server_local_servers_toggle_enabled(server, TRUE);
3540 /* Update the client entries of this server to the new backup
3541 router. If we are the backup router we also resolve the real
3542 servers for the clients. After updating is over this also
3543 removes the clients that this server explicitly owns. */
3544 silc_server_update_clients_by_server(server, user_data,
3545 backup_router, TRUE);
3547 /* If we are router and just lost our primary router (now standlaone)
3548 we remove everything that was behind it, since we don't know
3550 if (server->server_type == SILC_ROUTER && server->standalone)
3551 /* Remove all servers that are originated from this server, and
3552 remove the clients of those servers too. */
3553 silc_server_remove_servers_by_server(server, user_data, TRUE);
3555 /* Finally remove the clients that are explicitly owned by this
3556 server. They go down with the server. */
3557 silc_server_remove_clients_by_server(server, user_data,
3560 /* Update our server cache to use the new backup router too. */
3561 silc_server_update_servers_by_server(server, user_data, backup_router);
3562 if (server->server_type == SILC_SERVER)
3563 silc_server_update_channels_by_server(server, user_data,
3566 /* Send notify about primary router going down to local operators */
3567 if (server->backup_router)
3568 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3569 SILC_NOTIFY_TYPE_NONE,
3570 ("%s switched to backup router %s "
3571 "(we are primary router now)",
3572 server->server_name, server->server_name));
3573 else if (server->router)
3574 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3575 SILC_NOTIFY_TYPE_NONE,
3576 ("%s switched to backup router %s",
3577 server->server_name,
3578 server->router->server_name));
3580 server->backup_noswitch = FALSE;
3582 /* Free the server entry */
3583 silc_server_backup_del(server, user_data);
3584 silc_server_backup_replaced_del(server, user_data);
3585 silc_idlist_del_data(user_data);
3586 if (!silc_idlist_del_server(server->local_list, user_data))
3587 silc_idlist_del_server(server->global_list, user_data);
3588 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
3589 server->stat.my_servers--;
3591 server->stat.my_routers--;
3592 server->stat.routers--;
3594 server->stat.servers--;
3595 if (server->server_type == SILC_ROUTER)
3596 server->stat.cell_servers--;
3598 if (backup_router && backup_router != server->id_entry) {
3599 /* Announce all of our stuff that was created about 5 minutes ago.
3600 The backup router knows all the other stuff already. */
3601 if (server->server_type == SILC_ROUTER)
3602 silc_server_announce_servers(server, FALSE, time(0) - 300,
3603 backup_router->connection);
3605 /* Announce our clients and channels to the router */
3606 silc_server_announce_clients(server, time(0) - 300,
3607 backup_router->connection);
3608 silc_server_announce_channels(server, time(0) - 300,
3609 backup_router->connection);
3615 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
3617 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3619 silc_idlist_del_data(user_data);
3620 silc_free(user_data);
3625 sock->user_data = NULL;
3628 /* Removes client from all channels it has joined. This is used when client
3629 connection is disconnected. If the client on a channel is last, the
3630 channel is removed as well. This sends the SIGNOFF notify types. */
3632 void silc_server_remove_from_channels(SilcServer server,
3633 SilcSocketConnection sock,
3634 SilcClientEntry client,
3636 const char *signoff_message,
3640 SilcChannelEntry channel;
3641 SilcChannelClientEntry chl;
3642 SilcHashTableList htl;
3643 SilcBuffer clidp = NULL;
3648 if (notify && !client->id)
3651 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3652 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3655 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3660 /* Remove the client from all channels. The client is removed from
3661 the channels' user list. */
3662 silc_hash_table_list(client->channels, &htl);
3663 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3664 channel = chl->channel;
3666 /* Remove channel if this is last client leaving the channel, unless
3667 the channel is permanent. */
3668 if (server->server_type != SILC_SERVER &&
3669 silc_hash_table_count(channel->user_list) < 2) {
3670 silc_server_channel_delete(server, channel);
3674 silc_hash_table_del(client->channels, channel);
3675 silc_hash_table_del(channel->user_list, client);
3676 channel->user_count--;
3678 /* If there is no global users on the channel anymore mark the channel
3679 as local channel. Do not check if the removed client is local client. */
3680 if (server->server_type == SILC_SERVER && channel->global_users &&
3681 chl->client->router && !silc_server_channel_has_global(channel))
3682 channel->global_users = FALSE;
3684 memset(chl, 'A', sizeof(*chl));
3687 /* Update statistics */
3688 if (SILC_IS_LOCAL(client))
3689 server->stat.my_chanclients--;
3690 if (server->server_type == SILC_ROUTER) {
3691 server->stat.cell_chanclients--;
3692 server->stat.chanclients--;
3695 /* If there is not at least one local user on the channel then we don't
3696 need the channel entry anymore, we can remove it safely, unless the
3697 channel is permanent channel */
3698 if (server->server_type == SILC_SERVER &&
3699 !silc_server_channel_has_local(channel)) {
3700 /* Notify about leaving client if this channel has global users. */
3701 if (notify && channel->global_users)
3702 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3703 SILC_NOTIFY_TYPE_SIGNOFF,
3704 signoff_message ? 2 : 1,
3705 clidp->data, clidp->len,
3706 signoff_message, signoff_message ?
3707 strlen(signoff_message) : 0);
3709 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3710 silc_server_channel_delete(server, channel);
3714 /* Send notify to channel about client leaving SILC and channel too */
3716 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3717 SILC_NOTIFY_TYPE_SIGNOFF,
3718 signoff_message ? 2 : 1,
3719 clidp->data, clidp->len,
3720 signoff_message, signoff_message ?
3721 strlen(signoff_message) : 0);
3723 if (killed && clidp) {
3724 /* Remove the client from channel's invite list */
3725 if (channel->invite_list &&
3726 silc_hash_table_count(channel->invite_list)) {
3728 SilcArgumentPayload iargs;
3729 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3731 iargs = silc_argument_payload_parse(ab->data, ab->len, 1);
3732 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3733 silc_buffer_free(ab);
3734 silc_argument_payload_free(iargs);
3738 /* Don't create keys if we are shutting down */
3739 if (server->server_shutdown)
3742 /* Re-generate channel key if needed */
3743 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3744 if (!silc_server_create_channel_key(server, channel, 0))
3747 /* Send the channel key to the channel. The key of course is not sent
3748 to the client who was removed from the channel. */
3749 silc_server_send_channel_key(server, client->connection, channel,
3750 server->server_type == SILC_ROUTER ?
3751 FALSE : !server->standalone);
3755 silc_hash_table_list_reset(&htl);
3757 silc_buffer_free(clidp);
3760 /* Removes client from one channel. This is used for example when client
3761 calls LEAVE command to remove itself from the channel. Returns TRUE
3762 if channel still exists and FALSE if the channel is removed when
3763 last client leaves the channel. If `notify' is FALSE notify messages
3766 bool silc_server_remove_from_one_channel(SilcServer server,
3767 SilcSocketConnection sock,
3768 SilcChannelEntry channel,
3769 SilcClientEntry client,
3772 SilcChannelClientEntry chl;
3775 SILC_LOG_DEBUG(("Removing %s from channel %s",
3776 silc_id_render(client->id, SILC_ID_CLIENT),
3777 channel->channel_name));
3779 /* Get the entry to the channel, if this client is not on the channel
3781 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3784 /* Remove channel if this is last client leaving the channel, unless
3785 the channel is permanent. */
3786 if (server->server_type != SILC_SERVER &&
3787 silc_hash_table_count(channel->user_list) < 2) {
3788 silc_server_channel_delete(server, channel);
3792 silc_hash_table_del(client->channels, channel);
3793 silc_hash_table_del(channel->user_list, client);
3794 channel->user_count--;
3796 /* If there is no global users on the channel anymore mark the channel
3797 as local channel. Do not check if the client is local client. */
3798 if (server->server_type == SILC_SERVER && channel->global_users &&
3799 chl->client->router && !silc_server_channel_has_global(channel))
3800 channel->global_users = FALSE;
3802 memset(chl, 'O', sizeof(*chl));
3805 /* Update statistics */
3806 if (SILC_IS_LOCAL(client))
3807 server->stat.my_chanclients--;
3808 if (server->server_type == SILC_ROUTER) {
3809 server->stat.cell_chanclients--;
3810 server->stat.chanclients--;
3813 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3817 /* If there is not at least one local user on the channel then we don't
3818 need the channel entry anymore, we can remove it safely, unless the
3819 channel is permanent channel */
3820 if (server->server_type == SILC_SERVER &&
3821 !silc_server_channel_has_local(channel)) {
3822 /* Notify about leaving client if this channel has global users. */
3823 if (notify && channel->global_users)
3824 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3825 SILC_NOTIFY_TYPE_LEAVE, 1,
3826 clidp->data, clidp->len);
3828 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3829 silc_server_channel_delete(server, channel);
3830 silc_buffer_free(clidp);
3834 /* Send notify to channel about client leaving the channel */
3836 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3837 SILC_NOTIFY_TYPE_LEAVE, 1,
3838 clidp->data, clidp->len);
3840 silc_buffer_free(clidp);
3844 /* Timeout callback. This is called if connection is idle or for some
3845 other reason is not responding within some period of time. This
3846 disconnects the remote end. */
3848 SILC_TASK_CALLBACK(silc_server_timeout_remote)
3850 SilcServer server = (SilcServer)context;
3851 SilcSocketConnection sock = server->sockets[fd];
3852 SilcProtocolType protocol = 0;
3854 SILC_LOG_DEBUG(("Start"));
3859 SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
3860 sock->hostname, sock->ip));
3862 /* If we have protocol active we must assure that we call the protocol's
3863 final callback so that all the memory is freed. */
3864 if (sock->protocol && sock->protocol->protocol &&
3865 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3866 protocol = sock->protocol->protocol->type;
3867 silc_protocol_cancel(sock->protocol, server->schedule);
3868 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3869 silc_protocol_execute_final(sock->protocol, server->schedule);
3870 sock->protocol = NULL;
3874 silc_server_disconnect_remote(server, sock,
3876 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3877 SILC_STATUS_ERR_AUTH_FAILED :
3878 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3879 "Connection timeout");
3881 if (sock->user_data)
3882 silc_server_free_sock_user_data(server, sock, NULL);
3885 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3886 function may be used only by router. In real SILC network all channels
3887 are created by routers thus this function is never used by normal
3890 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3891 SilcServerID *router_id,
3897 SilcChannelID *channel_id;
3898 SilcChannelEntry entry;
3902 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3905 cipher = SILC_DEFAULT_CIPHER;
3907 hmac = SILC_DEFAULT_HMAC;
3909 /* Allocate cipher */
3910 if (!silc_cipher_alloc(cipher, &key))
3914 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3915 silc_cipher_free(key);
3919 channel_name = strdup(channel_name);
3921 /* Create the channel ID */
3922 if (!silc_id_create_channel_id(server, router_id, server->rng,
3924 silc_free(channel_name);
3925 silc_cipher_free(key);
3926 silc_hmac_free(newhmac);
3930 /* Create the channel */
3931 entry = silc_idlist_add_channel(server->local_list, channel_name,
3932 SILC_CHANNEL_MODE_NONE, channel_id,
3933 NULL, key, newhmac, 0);
3935 silc_free(channel_name);
3936 silc_cipher_free(key);
3937 silc_hmac_free(newhmac);
3938 silc_free(channel_id);
3942 entry->cipher = strdup(cipher);
3943 entry->hmac_name = strdup(hmac);
3945 /* Now create the actual key material */
3946 if (!silc_server_create_channel_key(server, entry,
3947 silc_cipher_get_key_len(key) / 8)) {
3948 silc_idlist_del_channel(server->local_list, entry);
3952 /* Notify other routers about the new channel. We send the packet
3953 to our primary route. */
3955 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3956 channel_name, entry->id,
3957 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3960 /* Distribute to backup routers */
3961 if (broadcast && server->server_type == SILC_ROUTER) {
3964 SilcUInt32 name_len = strlen(channel_name);
3965 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
3966 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
3968 packet = silc_channel_payload_encode(channel_name, name_len,
3969 cid, channel_id_len, entry->mode);
3970 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3971 packet->data, packet->len, FALSE, TRUE);
3973 silc_buffer_free(packet);
3976 server->stat.my_channels++;
3977 if (server->server_type == SILC_ROUTER) {
3978 server->stat.channels++;
3979 server->stat.cell_channels++;
3980 entry->users_resolved = TRUE;
3986 /* Same as above but creates the channel with Channel ID `channel_id. */
3989 silc_server_create_new_channel_with_id(SilcServer server,
3993 SilcChannelID *channel_id,
3996 SilcChannelEntry entry;
4000 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
4003 cipher = SILC_DEFAULT_CIPHER;
4005 hmac = SILC_DEFAULT_HMAC;
4007 /* Allocate cipher */
4008 if (!silc_cipher_alloc(cipher, &key))
4012 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
4013 silc_cipher_free(key);
4017 channel_name = strdup(channel_name);
4019 /* Create the channel */
4020 entry = silc_idlist_add_channel(server->local_list, channel_name,
4021 SILC_CHANNEL_MODE_NONE, channel_id,
4022 NULL, key, newhmac, 0);
4024 silc_cipher_free(key);
4025 silc_hmac_free(newhmac);
4026 silc_free(channel_name);
4030 /* Now create the actual key material */
4031 if (!silc_server_create_channel_key(server, entry,
4032 silc_cipher_get_key_len(key) / 8)) {
4033 silc_idlist_del_channel(server->local_list, entry);
4037 /* Notify other routers about the new channel. We send the packet
4038 to our primary route. */
4040 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
4041 channel_name, entry->id,
4042 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
4045 /* Distribute to backup routers */
4046 if (broadcast && server->server_type == SILC_ROUTER) {
4049 SilcUInt32 name_len = strlen(channel_name);
4050 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
4051 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
4053 packet = silc_channel_payload_encode(channel_name, name_len,
4054 cid, channel_id_len, entry->mode);
4055 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
4056 packet->data, packet->len, FALSE, TRUE);
4058 silc_buffer_free(packet);
4061 server->stat.my_channels++;
4062 if (server->server_type == SILC_ROUTER) {
4063 server->stat.channels++;
4064 server->stat.cell_channels++;
4065 entry->users_resolved = TRUE;
4071 /* Channel's key re-key timeout callback. */
4073 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
4075 SilcServer server = app_context;
4076 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
4080 /* Return now if we are shutting down */
4081 if (server->server_shutdown)
4084 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
4087 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
4090 /* Generates new channel key. This is used to create the initial channel key
4091 but also to re-generate new key for channel. If `key_len' is provided
4092 it is the bytes of the key length. */
4094 bool silc_server_create_channel_key(SilcServer server,
4095 SilcChannelEntry channel,
4099 unsigned char channel_key[32], hash[32];
4102 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
4103 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
4107 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
4109 if (!channel->channel_key)
4110 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
4111 channel->channel_key = NULL;
4117 else if (channel->key_len)
4118 len = channel->key_len / 8;
4120 len = silc_cipher_get_key_len(channel->channel_key) / 8;
4122 /* Create channel key */
4123 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
4126 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
4128 /* Remove old key if exists */
4130 memset(channel->key, 0, channel->key_len / 8);
4131 silc_free(channel->key);
4135 channel->key_len = len * 8;
4136 channel->key = silc_memdup(channel_key, len);
4137 memset(channel_key, 0, sizeof(channel_key));
4139 /* Generate HMAC key from the channel key data and set it */
4141 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4142 memset(channel->key, 0, channel->key_len / 8);
4143 silc_free(channel->key);
4144 channel->channel_key = NULL;
4147 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
4148 silc_hmac_set_key(channel->hmac, hash,
4149 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4150 memset(hash, 0, sizeof(hash));
4152 if (server->server_type == SILC_ROUTER) {
4153 if (!channel->rekey)
4154 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4155 channel->rekey->channel = channel;
4156 channel->rekey->key_len = key_len;
4157 if (channel->rekey->task)
4158 silc_schedule_task_del(server->schedule, channel->rekey->task);
4160 channel->rekey->task =
4161 silc_schedule_task_add(server->schedule, 0,
4162 silc_server_channel_key_rekey,
4163 (void *)channel->rekey,
4164 server->config->channel_rekey_secs, 0,
4166 SILC_TASK_PRI_NORMAL);
4172 /* Saves the channel key found in the encoded `key_payload' buffer. This
4173 function is used when we receive Channel Key Payload and also when we're
4174 processing JOIN command reply. Returns entry to the channel. */
4176 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4177 SilcBuffer key_payload,
4178 SilcChannelEntry channel)
4180 SilcChannelKeyPayload payload = NULL;
4181 SilcChannelID *id = NULL;
4182 unsigned char *tmp, hash[32];
4186 /* Decode channel key payload */
4187 payload = silc_channel_key_payload_parse(key_payload->data,
4190 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4195 /* Get the channel entry */
4198 /* Get channel ID */
4199 tmp = silc_channel_key_get_id(payload, &tmp_len);
4200 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
4206 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4208 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4210 if (server->server_type == SILC_ROUTER)
4211 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4212 silc_id_render(id, SILC_ID_CHANNEL)));
4218 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4220 tmp = silc_channel_key_get_key(payload, &tmp_len);
4226 cipher = silc_channel_key_get_cipher(payload, NULL);
4232 /* Remove old key if exists */
4234 memset(channel->key, 0, channel->key_len / 8);
4235 silc_free(channel->key);
4236 silc_cipher_free(channel->channel_key);
4239 /* Create new cipher */
4240 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
4241 channel->channel_key = NULL;
4246 if (channel->cipher)
4247 silc_free(channel->cipher);
4248 channel->cipher = strdup(cipher);
4251 channel->key_len = tmp_len * 8;
4252 channel->key = silc_memdup(tmp, tmp_len);
4253 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
4255 /* Generate HMAC key from the channel key data and set it */
4257 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4258 memset(channel->key, 0, channel->key_len / 8);
4259 silc_free(channel->key);
4260 channel->channel_key = NULL;
4263 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4264 silc_hmac_set_key(channel->hmac, hash,
4265 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4267 memset(hash, 0, sizeof(hash));
4268 memset(tmp, 0, tmp_len);
4270 if (server->server_type == SILC_ROUTER) {
4271 if (!channel->rekey)
4272 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4273 channel->rekey->channel = channel;
4274 if (channel->rekey->task)
4275 silc_schedule_task_del(server->schedule, channel->rekey->task);
4277 channel->rekey->task =
4278 silc_schedule_task_add(server->schedule, 0,
4279 silc_server_channel_key_rekey,
4280 (void *)channel->rekey,
4281 server->config->channel_rekey_secs, 0,
4283 SILC_TASK_PRI_NORMAL);
4289 silc_channel_key_payload_free(payload);
4294 /* Heartbeat callback. This function is set as argument for the
4295 silc_socket_set_heartbeat function. The library will call this function
4296 at the set time interval. */
4298 void silc_server_perform_heartbeat(SilcSocketConnection sock,
4301 SilcServer server = hb_context;
4303 SILC_LOG_DEBUG(("Sending heartbeat to %s:%d (%s)", sock->hostname,
4304 sock->port, sock->ip));
4306 /* Send the heartbeat */
4307 silc_server_send_heartbeat(server, sock);
4310 /* Returns assembled of all servers in the given ID list. The packet's
4311 form is dictated by the New ID payload. */
4313 static void silc_server_announce_get_servers(SilcServer server,
4314 SilcServerEntry remote,
4316 SilcBuffer *servers,
4317 unsigned long creation_time)
4319 SilcIDCacheList list;
4320 SilcIDCacheEntry id_cache;
4321 SilcServerEntry entry;
4324 /* Go through all clients in the list */
4325 if (silc_idcache_get_all(id_list->servers, &list)) {
4326 if (silc_idcache_list_first(list, &id_cache)) {
4328 entry = (SilcServerEntry)id_cache->context;
4330 /* Do not announce the one we've sending our announcements and
4331 do not announce ourself. Also check the creation time if it's
4333 if ((entry == remote) || (entry == server->id_entry) ||
4334 (creation_time && entry->data.created < creation_time)) {
4335 if (!silc_idcache_list_next(list, &id_cache))
4340 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4342 *servers = silc_buffer_realloc(*servers,
4344 (*servers)->truelen + idp->len :
4346 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4347 silc_buffer_put(*servers, idp->data, idp->len);
4348 silc_buffer_pull(*servers, idp->len);
4349 silc_buffer_free(idp);
4351 if (!silc_idcache_list_next(list, &id_cache))
4356 silc_idcache_list_free(list);
4361 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4367 p = silc_notify_payload_encode(notify, argc, ap);
4373 /* This function is used by router to announce existing servers to our
4374 primary router when we've connected to it. If `creation_time' is non-zero
4375 then only the servers that has been created after the `creation_time'
4376 will be announced. */
4378 void silc_server_announce_servers(SilcServer server, bool global,
4379 unsigned long creation_time,
4380 SilcSocketConnection remote)
4382 SilcBuffer servers = NULL;
4384 SILC_LOG_DEBUG(("Announcing servers"));
4386 /* Get servers in local list */
4387 silc_server_announce_get_servers(server, remote->user_data,
4388 server->local_list, &servers,
4392 /* Get servers in global list */
4393 silc_server_announce_get_servers(server, remote->user_data,
4394 server->global_list, &servers,
4398 silc_buffer_push(servers, servers->data - servers->head);
4399 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
4401 /* Send the packet */
4402 silc_server_packet_send(server, remote,
4403 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4404 servers->data, servers->len, TRUE);
4406 silc_buffer_free(servers);
4410 /* Returns assembled packet of all clients in the given ID list. The
4411 packet's form is dictated by the New ID Payload. */
4413 static void silc_server_announce_get_clients(SilcServer server,
4415 SilcBuffer *clients,
4417 unsigned long creation_time)
4419 SilcIDCacheList list;
4420 SilcIDCacheEntry id_cache;
4421 SilcClientEntry client;
4424 unsigned char mode[4];
4426 /* Go through all clients in the list */
4427 if (silc_idcache_get_all(id_list->clients, &list)) {
4428 if (silc_idcache_list_first(list, &id_cache)) {
4430 client = (SilcClientEntry)id_cache->context;
4432 if (creation_time && client->data.created < creation_time) {
4433 if (!silc_idcache_list_next(list, &id_cache))
4437 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) &&
4438 !client->connection && !client->router && !SILC_IS_LOCAL(client)) {
4439 if (!silc_idcache_list_next(list, &id_cache))
4444 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4446 *clients = silc_buffer_realloc(*clients,
4448 (*clients)->truelen + idp->len :
4450 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4451 silc_buffer_put(*clients, idp->data, idp->len);
4452 silc_buffer_pull(*clients, idp->len);
4454 SILC_PUT32_MSB(client->mode, mode);
4456 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4457 2, idp->data, idp->len,
4459 *umodes = silc_buffer_realloc(*umodes,
4461 (*umodes)->truelen + tmp->len :
4463 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4464 silc_buffer_put(*umodes, tmp->data, tmp->len);
4465 silc_buffer_pull(*umodes, tmp->len);
4466 silc_buffer_free(tmp);
4468 silc_buffer_free(idp);
4470 if (!silc_idcache_list_next(list, &id_cache))
4475 silc_idcache_list_free(list);
4479 /* This function is used to announce our existing clients to our router
4480 when we've connected to it. If `creation_time' is non-zero then only
4481 the clients that has been created after the `creation_time' will be
4484 void silc_server_announce_clients(SilcServer server,
4485 unsigned long creation_time,
4486 SilcSocketConnection remote)
4488 SilcBuffer clients = NULL;
4489 SilcBuffer umodes = NULL;
4491 SILC_LOG_DEBUG(("Announcing clients"));
4493 /* Get clients in local list */
4494 silc_server_announce_get_clients(server, server->local_list,
4495 &clients, &umodes, creation_time);
4497 /* As router we announce our global list as well */
4498 if (server->server_type == SILC_ROUTER)
4499 silc_server_announce_get_clients(server, server->global_list,
4500 &clients, &umodes, creation_time);
4503 silc_buffer_push(clients, clients->data - clients->head);
4504 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
4506 /* Send the packet */
4507 silc_server_packet_send(server, remote,
4508 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4509 clients->data, clients->len, TRUE);
4511 silc_buffer_free(clients);
4515 silc_buffer_push(umodes, umodes->data - umodes->head);
4516 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
4518 /* Send the packet */
4519 silc_server_packet_send(server, remote,
4520 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4521 umodes->data, umodes->len, TRUE);
4523 silc_buffer_free(umodes);
4527 /* Returns channel's topic for announcing it */
4529 void silc_server_announce_get_channel_topic(SilcServer server,
4530 SilcChannelEntry channel,
4535 if (channel->topic) {
4536 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4537 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4538 chidp->data, chidp->len,
4540 strlen(channel->topic));
4541 silc_buffer_free(chidp);
4545 /* Returns channel's invite and ban lists */
4547 void silc_server_announce_get_inviteban(SilcServer server,
4548 SilcChannelEntry channel,
4552 SilcBuffer list, idp, idp2, tmp2;
4554 SilcHashTableList htl;
4555 const unsigned char a[1] = { 0x03 };
4557 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4559 /* Encode invite list */
4560 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4561 list = silc_buffer_alloc_size(2);
4562 type = silc_hash_table_count(channel->invite_list);
4563 SILC_PUT16_MSB(type, list->data);
4564 silc_hash_table_list(channel->invite_list, &htl);
4565 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4566 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4568 silc_hash_table_list_reset(&htl);
4570 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4572 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4573 idp->data, idp->len,
4574 channel->channel_name,
4575 strlen(channel->channel_name),
4576 idp2->data, idp2->len,
4578 list->data, list->len);
4579 silc_buffer_free(idp2);
4580 silc_buffer_free(list);
4583 /* Encode ban list */
4584 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4585 list = silc_buffer_alloc_size(2);
4586 type = silc_hash_table_count(channel->ban_list);
4587 SILC_PUT16_MSB(type, list->data);
4588 silc_hash_table_list(channel->ban_list, &htl);
4589 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4590 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4592 silc_hash_table_list_reset(&htl);
4595 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4596 idp->data, idp->len,
4598 list->data, list->len);
4599 silc_buffer_free(list);
4602 silc_buffer_free(idp);
4605 /* Returns assembled packets for channel users of the `channel'. */
4607 void silc_server_announce_get_channel_users(SilcServer server,
4608 SilcChannelEntry channel,
4609 SilcBuffer *channel_modes,
4610 SilcBuffer *channel_users,
4611 SilcBuffer *channel_users_modes)
4613 SilcChannelClientEntry chl;
4614 SilcHashTableList htl;
4615 SilcBuffer chidp, clidp, csidp;
4616 SilcBuffer tmp, fkey = NULL, chpklist;
4618 unsigned char mode[4];
4621 SILC_LOG_DEBUG(("Start"));
4623 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4624 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4625 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4628 SILC_PUT32_MSB(channel->mode, mode);
4629 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4630 if (channel->founder_key)
4631 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
4633 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4634 7, csidp->data, csidp->len,
4637 hmac, hmac ? strlen(hmac) : 0,
4638 channel->passphrase,
4639 channel->passphrase ?
4640 strlen(channel->passphrase) : 0,
4641 fkey ? fkey->data : NULL,
4642 fkey ? fkey->len : 0,
4643 chpklist ? chpklist->data : NULL,
4644 chpklist ? chpklist->len : 0);
4647 silc_buffer_realloc(*channel_modes,
4649 (*channel_modes)->truelen + len : len));
4650 silc_buffer_pull_tail(*channel_modes,
4651 ((*channel_modes)->end -
4652 (*channel_modes)->data));
4653 silc_buffer_put(*channel_modes, tmp->data, tmp->len);
4654 silc_buffer_pull(*channel_modes, len);
4655 silc_buffer_free(tmp);
4656 silc_buffer_free(fkey);
4659 /* Now find all users on the channel */
4660 silc_hash_table_list(channel->user_list, &htl);
4661 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4662 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4665 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4666 clidp->data, clidp->len,
4667 chidp->data, chidp->len);
4670 silc_buffer_realloc(*channel_users,
4672 (*channel_users)->truelen + len : len));
4673 silc_buffer_pull_tail(*channel_users,
4674 ((*channel_users)->end -
4675 (*channel_users)->data));
4677 silc_buffer_put(*channel_users, tmp->data, tmp->len);
4678 silc_buffer_pull(*channel_users, len);
4679 silc_buffer_free(tmp);
4681 /* CUMODE notify for mode change on the channel */
4682 SILC_PUT32_MSB(chl->mode, mode);
4683 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4684 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
4685 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4686 4, csidp->data, csidp->len,
4688 clidp->data, clidp->len,
4689 fkey ? fkey->data : NULL,
4690 fkey ? fkey->len : 0);
4692 *channel_users_modes =
4693 silc_buffer_realloc(*channel_users_modes,
4694 (*channel_users_modes ?
4695 (*channel_users_modes)->truelen + len : len));
4696 silc_buffer_pull_tail(*channel_users_modes,
4697 ((*channel_users_modes)->end -
4698 (*channel_users_modes)->data));
4700 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
4701 silc_buffer_pull(*channel_users_modes, len);
4702 silc_buffer_free(tmp);
4703 silc_buffer_free(fkey);
4705 silc_buffer_free(clidp);
4707 silc_hash_table_list_reset(&htl);
4708 silc_buffer_free(chidp);
4709 silc_buffer_free(csidp);
4712 /* Returns assembled packets for all channels and users on those channels
4713 from the given ID List. The packets are in the form dictated by the
4714 New Channel and New Channel User payloads. */
4716 void silc_server_announce_get_channels(SilcServer server,
4718 SilcBuffer *channels,
4719 SilcBuffer **channel_modes,
4720 SilcBuffer *channel_users,
4721 SilcBuffer **channel_users_modes,
4722 SilcUInt32 *channel_users_modes_c,
4723 SilcBuffer **channel_topics,
4724 SilcBuffer **channel_invites,
4725 SilcBuffer **channel_bans,
4726 SilcChannelID ***channel_ids,
4727 unsigned long creation_time)
4729 SilcIDCacheList list;
4730 SilcIDCacheEntry id_cache;
4731 SilcChannelEntry channel;
4734 SilcUInt16 name_len;
4736 int i = *channel_users_modes_c;
4739 SILC_LOG_DEBUG(("Start"));
4741 /* Go through all channels in the list */
4742 if (silc_idcache_get_all(id_list->channels, &list)) {
4743 if (silc_idcache_list_first(list, &id_cache)) {
4745 channel = (SilcChannelEntry)id_cache->context;
4747 if (creation_time && channel->created < creation_time)
4752 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
4753 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
4754 name_len = strlen(channel->channel_name);
4757 len = 4 + name_len + id_len + 4;
4759 silc_buffer_realloc(*channels,
4760 (*channels ? (*channels)->truelen +
4762 silc_buffer_pull_tail(*channels,
4763 ((*channels)->end - (*channels)->data));
4764 silc_buffer_format(*channels,
4765 SILC_STR_UI_SHORT(name_len),
4766 SILC_STR_UI_XNSTRING(channel->channel_name,
4768 SILC_STR_UI_SHORT(id_len),
4769 SILC_STR_UI_XNSTRING(cid, id_len),
4770 SILC_STR_UI_INT(channel->mode),
4772 silc_buffer_pull(*channels, len);
4775 if (creation_time && channel->updated < creation_time)
4781 /* Channel user modes */
4782 *channel_users_modes = silc_realloc(*channel_users_modes,
4783 sizeof(**channel_users_modes) *
4785 (*channel_users_modes)[i] = NULL;
4786 *channel_modes = silc_realloc(*channel_modes,
4787 sizeof(**channel_modes) * (i + 1));
4788 (*channel_modes)[i] = NULL;
4789 *channel_ids = silc_realloc(*channel_ids,
4790 sizeof(**channel_ids) * (i + 1));
4791 (*channel_ids)[i] = NULL;
4792 silc_server_announce_get_channel_users(server, channel,
4793 &(*channel_modes)[i],
4795 &(*channel_users_modes)[i]);
4796 (*channel_ids)[i] = channel->id;
4798 /* Channel's topic */
4799 *channel_topics = silc_realloc(*channel_topics,
4800 sizeof(**channel_topics) * (i + 1));
4801 (*channel_topics)[i] = NULL;
4802 silc_server_announce_get_channel_topic(server, channel,
4803 &(*channel_topics)[i]);
4805 /* Channel's invite and ban list */
4806 *channel_invites = silc_realloc(*channel_invites,
4807 sizeof(**channel_invites) * (i + 1));
4808 (*channel_invites)[i] = NULL;
4809 *channel_bans = silc_realloc(*channel_bans,
4810 sizeof(**channel_bans) * (i + 1));
4811 (*channel_bans)[i] = NULL;
4812 silc_server_announce_get_inviteban(server, channel,
4813 &(*channel_invites)[i],
4814 &(*channel_bans)[i]);
4816 (*channel_users_modes_c)++;
4822 if (!silc_idcache_list_next(list, &id_cache))
4827 silc_idcache_list_free(list);
4831 /* This function is used to announce our existing channels to our router
4832 when we've connected to it. This also announces the users on the
4833 channels to the router. If the `creation_time' is non-zero only the
4834 channels that was created after the `creation_time' are announced.
4835 Note that the channel users are still announced even if the `creation_time'
4838 void silc_server_announce_channels(SilcServer server,
4839 unsigned long creation_time,
4840 SilcSocketConnection remote)
4842 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4843 SilcBuffer *channel_users_modes = NULL;
4844 SilcBuffer *channel_topics = NULL;
4845 SilcBuffer *channel_invites = NULL;
4846 SilcBuffer *channel_bans = NULL;
4847 SilcUInt32 channel_users_modes_c = 0;
4848 SilcChannelID **channel_ids = NULL;
4850 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4852 /* Get channels and channel users in local list */
4853 silc_server_announce_get_channels(server, server->local_list,
4854 &channels, &channel_modes,
4856 &channel_users_modes,
4857 &channel_users_modes_c,
4861 &channel_ids, creation_time);
4863 /* Get channels and channel users in global list */
4864 if (server->server_type != SILC_SERVER)
4865 silc_server_announce_get_channels(server, server->global_list,
4866 &channels, &channel_modes,
4868 &channel_users_modes,
4869 &channel_users_modes_c,
4873 &channel_ids, creation_time);
4876 silc_buffer_push(channels, channels->data - channels->head);
4877 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
4879 /* Send the packet */
4880 silc_server_packet_send(server, remote,
4881 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4882 channels->data, channels->len,
4885 silc_buffer_free(channels);
4888 if (channel_users) {
4889 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4890 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4891 channel_users->len);
4893 /* Send the packet */
4894 silc_server_packet_send(server, remote,
4895 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4896 channel_users->data, channel_users->len,
4899 silc_buffer_free(channel_users);
4902 if (channel_modes) {
4905 for (i = 0; i < channel_users_modes_c; i++) {
4906 if (!channel_modes[i])
4908 silc_buffer_push(channel_modes[i],
4909 channel_modes[i]->data -
4910 channel_modes[i]->head);
4911 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4912 channel_modes[i]->len);
4913 silc_server_packet_send_dest(server, remote,
4914 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4915 channel_ids[i], SILC_ID_CHANNEL,
4916 channel_modes[i]->data,
4917 channel_modes[i]->len,
4919 silc_buffer_free(channel_modes[i]);
4921 silc_free(channel_modes);
4924 if (channel_users_modes) {
4927 for (i = 0; i < channel_users_modes_c; i++) {
4928 if (!channel_users_modes[i])
4930 silc_buffer_push(channel_users_modes[i],
4931 channel_users_modes[i]->data -
4932 channel_users_modes[i]->head);
4933 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4934 channel_users_modes[i]->len);
4935 silc_server_packet_send_dest(server, remote,
4936 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4937 channel_ids[i], SILC_ID_CHANNEL,
4938 channel_users_modes[i]->data,
4939 channel_users_modes[i]->len,
4941 silc_buffer_free(channel_users_modes[i]);
4943 silc_free(channel_users_modes);
4946 if (channel_topics) {
4949 for (i = 0; i < channel_users_modes_c; i++) {
4950 if (!channel_topics[i])
4953 silc_buffer_push(channel_topics[i],
4954 channel_topics[i]->data -
4955 channel_topics[i]->head);
4956 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4957 channel_topics[i]->len);
4958 silc_server_packet_send_dest(server, remote,
4959 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4960 channel_ids[i], SILC_ID_CHANNEL,
4961 channel_topics[i]->data,
4962 channel_topics[i]->len,
4964 silc_buffer_free(channel_topics[i]);
4966 silc_free(channel_topics);
4969 if (channel_invites) {
4972 for (i = 0; i < channel_users_modes_c; i++) {
4973 if (!channel_invites[i])
4976 silc_buffer_push(channel_invites[i],
4977 channel_invites[i]->data -
4978 channel_invites[i]->head);
4979 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4980 channel_invites[i]->len);
4981 silc_server_packet_send_dest(server, remote,
4982 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4983 channel_ids[i], SILC_ID_CHANNEL,
4984 channel_invites[i]->data,
4985 channel_invites[i]->len,
4987 silc_buffer_free(channel_invites[i]);
4989 silc_free(channel_invites);
4995 for (i = 0; i < channel_users_modes_c; i++) {
4996 if (!channel_bans[i])
4999 silc_buffer_push(channel_bans[i],
5000 channel_bans[i]->data -
5001 channel_bans[i]->head);
5002 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
5003 channel_bans[i]->len);
5004 silc_server_packet_send_dest(server, remote,
5005 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
5006 channel_ids[i], SILC_ID_CHANNEL,
5007 channel_bans[i]->data,
5008 channel_bans[i]->len,
5010 silc_buffer_free(channel_bans[i]);
5012 silc_free(channel_bans);
5015 silc_free(channel_ids);
5018 /* Assembles user list and users mode list from the `channel'. */
5020 bool silc_server_get_users_on_channel(SilcServer server,
5021 SilcChannelEntry channel,
5022 SilcBuffer *user_list,
5023 SilcBuffer *mode_list,
5024 SilcUInt32 *user_count)
5026 SilcChannelClientEntry chl;
5027 SilcHashTableList htl;
5028 SilcBuffer client_id_list;
5029 SilcBuffer client_mode_list;
5031 SilcUInt32 list_count = 0, len = 0;
5033 if (!silc_hash_table_count(channel->user_list))
5036 silc_hash_table_list(channel->user_list, &htl);
5037 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
5038 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
5039 silc_hash_table_list_reset(&htl);
5041 client_id_list = silc_buffer_alloc(len);
5043 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
5044 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
5045 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
5047 silc_hash_table_list(channel->user_list, &htl);
5048 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5050 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
5051 silc_buffer_put(client_id_list, idp->data, idp->len);
5052 silc_buffer_pull(client_id_list, idp->len);
5053 silc_buffer_free(idp);
5055 /* Client's mode on channel */
5056 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
5057 silc_buffer_pull(client_mode_list, 4);
5061 silc_hash_table_list_reset(&htl);
5062 silc_buffer_push(client_id_list,
5063 client_id_list->data - client_id_list->head);
5064 silc_buffer_push(client_mode_list,
5065 client_mode_list->data - client_mode_list->head);
5067 *user_list = client_id_list;
5068 *mode_list = client_mode_list;
5069 *user_count = list_count;
5073 /* Saves users and their modes to the `channel'. */
5075 void silc_server_save_users_on_channel(SilcServer server,
5076 SilcSocketConnection sock,
5077 SilcChannelEntry channel,
5078 SilcClientID *noadd,
5079 SilcBuffer user_list,
5080 SilcBuffer mode_list,
5081 SilcUInt32 user_count)
5086 SilcClientID *client_id;
5087 SilcClientEntry client;
5088 SilcIDCacheEntry cache;
5089 SilcChannelClientEntry chl;
5091 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5092 channel->channel_name));
5094 for (i = 0; i < user_count; i++) {
5096 SILC_GET16_MSB(idp_len, user_list->data + 2);
5098 client_id = silc_id_payload_parse_id(user_list->data, idp_len, NULL);
5099 silc_buffer_pull(user_list, idp_len);
5104 SILC_GET32_MSB(mode, mode_list->data);
5105 silc_buffer_pull(mode_list, 4);
5107 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
5108 silc_free(client_id);
5114 /* Check if we have this client cached already. */
5115 client = silc_idlist_find_client_by_id(server->local_list, client_id,
5116 server->server_type, &cache);
5118 client = silc_idlist_find_client_by_id(server->global_list,
5119 client_id, server->server_type,
5122 /* If router did not find such Client ID in its lists then this must
5123 be bogus client or some router in the net is buggy. */
5124 if (server->server_type != SILC_SERVER) {
5125 silc_free(client_id);
5129 /* We don't have that client anywhere, add it. The client is added
5130 to global list since server didn't have it in the lists so it must be
5132 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5133 silc_id_dup(client_id, SILC_ID_CLIENT),
5134 sock->user_data, NULL, 0);
5136 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5137 silc_free(client_id);
5141 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5146 silc_free(client_id);
5148 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5149 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5150 "%s", channel->channel_name));
5154 if (!silc_server_client_on_channel(client, channel, &chl)) {
5155 /* Client was not on the channel, add it. */
5156 chl = silc_calloc(1, sizeof(*chl));
5157 chl->client = client;
5159 chl->channel = channel;
5160 silc_hash_table_add(channel->user_list, chl->client, chl);
5161 silc_hash_table_add(client->channels, chl->channel, chl);
5162 channel->user_count++;
5170 /* Saves channels and channels user modes to the `client'. Removes
5171 the client from those channels that are not sent in the list but
5174 void silc_server_save_user_channels(SilcServer server,
5175 SilcSocketConnection sock,
5176 SilcClientEntry client,
5177 SilcBuffer channels,
5178 SilcBuffer channels_user_modes)
5181 SilcUInt32 *chumodes;
5182 SilcChannelPayload entry;
5183 SilcChannelEntry channel;
5184 SilcChannelID *channel_id;
5185 SilcChannelClientEntry chl;
5186 SilcHashTable ht = NULL;
5187 SilcHashTableList htl;
5191 if (!channels || !channels_user_modes ||
5192 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5195 ch = silc_channel_payload_parse_list(channels->data, channels->len);
5196 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5198 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5199 NULL, NULL, NULL, TRUE);
5200 silc_dlist_start(ch);
5201 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5202 /* Check if we have this channel, and add it if we don't have it.
5203 Also add the client on the channel unless it is there already. */
5204 channel_id = silc_channel_get_id_parse(entry);
5205 channel = silc_idlist_find_channel_by_id(server->local_list,
5208 channel = silc_idlist_find_channel_by_id(server->global_list,
5211 if (server->server_type != SILC_SERVER) {
5212 silc_free(channel_id);
5217 /* We don't have that channel anywhere, add it. */
5218 name = silc_channel_get_name(entry, NULL);
5219 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5220 channel_id, server->router,
5223 silc_free(channel_id);
5230 channel->mode = silc_channel_get_mode(entry);
5232 /* Add the client on the channel */
5233 if (!silc_server_client_on_channel(client, channel, &chl)) {
5234 chl = silc_calloc(1, sizeof(*chl));
5235 chl->client = client;
5236 chl->mode = chumodes[i++];
5237 chl->channel = channel;
5238 silc_hash_table_add(channel->user_list, chl->client, chl);
5239 silc_hash_table_add(client->channels, chl->channel, chl);
5240 channel->user_count++;
5243 chl->mode = chumodes[i++];
5246 silc_hash_table_add(ht, channel, channel);
5247 silc_free(channel_id);
5249 silc_channel_payload_list_free(ch);
5250 silc_free(chumodes);
5254 /* Go through the list again and remove client from channels that
5255 are no part of the list. */
5257 silc_hash_table_list(client->channels, &htl);
5258 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5259 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5260 silc_hash_table_del(chl->channel->user_list, chl->client);
5261 silc_hash_table_del(chl->client->channels, chl->channel);
5265 silc_hash_table_list_reset(&htl);
5266 silc_hash_table_free(ht);
5268 silc_hash_table_list(client->channels, &htl);
5269 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5270 silc_hash_table_del(chl->channel->user_list, chl->client);
5271 silc_hash_table_del(chl->client->channels, chl->channel);
5274 silc_hash_table_list_reset(&htl);
5278 /* Lookups route to the client indicated by the `id_data'. The connection
5279 object and internal data object is returned. Returns NULL if route
5280 could not be found to the client. If the `client_id' is specified then
5281 it is used and the `id_data' is ignored. */
5283 SilcSocketConnection
5284 silc_server_get_client_route(SilcServer server,
5285 unsigned char *id_data,
5287 SilcClientID *client_id,
5288 SilcIDListData *idata,
5289 SilcClientEntry *client_entry)
5292 SilcClientEntry client;
5294 SILC_LOG_DEBUG(("Start"));
5297 *client_entry = NULL;
5299 /* Decode destination Client ID */
5301 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
5303 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
5307 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5310 /* If the destination belongs to our server we don't have to route
5311 the packet anywhere but to send it to the local destination. */
5312 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5316 /* If we are router and the client has router then the client is in
5317 our cell but not directly connected to us. */
5318 if (server->server_type == SILC_ROUTER && client->router) {
5319 /* We are of course in this case the client's router thus the route
5320 to the client is the server who owns the client. So, we will send
5321 the packet to that server. */
5323 *idata = (SilcIDListData)client->router;
5324 return client->router->connection;
5327 /* Seems that client really is directly connected to us */
5329 *idata = (SilcIDListData)client;
5331 *client_entry = client;
5332 return client->connection;
5335 /* Destination belongs to someone not in this server. If we are normal
5336 server our action is to send the packet to our router. */
5337 if (server->server_type != SILC_ROUTER && !server->standalone) {
5340 *idata = (SilcIDListData)server->router;
5341 return SILC_PRIMARY_ROUTE(server);
5344 /* We are router and we will perform route lookup for the destination
5345 and send the packet to fastest route. */
5346 if (server->server_type == SILC_ROUTER && !server->standalone) {
5347 /* Check first that the ID is valid */
5348 client = silc_idlist_find_client_by_id(server->global_list, id,
5351 SilcSocketConnection dst_sock;
5353 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5357 *idata = (SilcIDListData)dst_sock->user_data;
5366 /* Encodes and returns channel list of channels the `client' has joined.
5367 Secret channels are not put to the list. */
5369 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5370 SilcClientEntry client,
5373 SilcBuffer *user_mode_list)
5375 SilcBuffer buffer = NULL;
5376 SilcChannelEntry channel;
5377 SilcChannelClientEntry chl;
5378 SilcHashTableList htl;
5381 SilcUInt16 name_len;
5385 *user_mode_list = NULL;
5387 silc_hash_table_list(client->channels, &htl);
5388 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5389 channel = chl->channel;
5391 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5393 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5396 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
5397 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
5398 name_len = strlen(channel->channel_name);
5400 len = 4 + name_len + id_len + 4;
5401 buffer = silc_buffer_realloc(buffer,
5402 (buffer ? buffer->truelen + len : len));
5403 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5404 silc_buffer_format(buffer,
5405 SILC_STR_UI_SHORT(name_len),
5406 SILC_STR_UI_XNSTRING(channel->channel_name,
5408 SILC_STR_UI_SHORT(id_len),
5409 SILC_STR_UI_XNSTRING(cid, id_len),
5410 SILC_STR_UI_INT(chl->channel->mode),
5412 silc_buffer_pull(buffer, len);
5415 if (user_mode_list) {
5416 *user_mode_list = silc_buffer_realloc(*user_mode_list,
5418 (*user_mode_list)->truelen + 4 :
5420 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5421 (*user_mode_list)->data));
5422 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5423 silc_buffer_pull(*user_mode_list, 4);
5426 silc_hash_table_list_reset(&htl);
5429 silc_buffer_push(buffer, buffer->data - buffer->head);
5430 if (user_mode_list && *user_mode_list)
5431 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5432 (*user_mode_list)->head));
5437 /* Timeout callback for unsuccessful rekey. The rekey did not go through
5440 SILC_TASK_CALLBACK(silc_server_rekey_timeout)
5442 SilcServerRekeyInternalContext *ctx = context;
5443 SilcServer server = app_context;
5444 SilcSocketConnection sock = ctx->sock;
5446 SILC_LOG_DEBUG(("Timeout occurred in rekey protocol with %s:%d [%s]",
5447 sock->hostname, sock->port,
5448 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5449 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5450 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5453 SILC_LOG_WARNING(("Timeout occurred in rekey protocol with %s:%d [%s]",
5454 sock->hostname, sock->port,
5455 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5456 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5457 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5460 if (sock->protocol) {
5461 silc_protocol_cancel(sock->protocol, server->schedule);
5462 silc_protocol_free(sock->protocol);
5463 sock->protocol = NULL;
5466 silc_packet_context_free(ctx->packet);
5468 silc_ske_free(ctx->ske);
5469 silc_socket_free(sock);
5472 /* Disconnect since we failed to rekey, the keys are probably wrong. */
5473 silc_server_disconnect_remote(server, sock,
5474 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
5475 if (sock->user_data)
5476 silc_server_free_sock_user_data(server, sock, NULL);
5479 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
5480 silc_server_create_connections(server);
5483 /* A timeout callback for the re-key. We will be the initiator of the
5486 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_callback)
5488 SilcServer server = app_context;
5489 SilcSocketConnection sock = (SilcSocketConnection)context;
5490 SilcIDListData idata = (SilcIDListData)sock->user_data;
5491 SilcProtocol protocol;
5492 SilcServerRekeyInternalContext *proto_ctx;
5497 /* Do not execute rekey with disabled connections, as it would not
5498 go through anyway. */
5499 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
5502 /* If rekey protocol is active already wait for it to finish */
5503 if (sock->protocol && sock->protocol->protocol &&
5504 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)
5507 /* If any other protocol is active do not start this protocol yet. */
5508 if (sock->protocol) {
5509 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
5510 silc_schedule_task_add(server->schedule, sock->sock,
5511 silc_server_rekey_callback,
5512 sock, 60, 0, SILC_TASK_TIMEOUT,
5513 SILC_TASK_PRI_NORMAL);
5517 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
5518 sock->hostname, sock->port,
5519 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5520 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5521 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5524 /* Allocate internal protocol context. This is sent as context
5526 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
5527 proto_ctx->server = (void *)server;
5528 proto_ctx->sock = silc_socket_dup(sock);
5529 proto_ctx->responder = FALSE;
5530 proto_ctx->pfs = idata->rekey->pfs;
5532 /* Perform rekey protocol. Will call the final callback after the
5533 protocol is over. */
5534 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
5535 &protocol, proto_ctx, silc_server_rekey_final);
5536 sock->protocol = protocol;
5538 /* Register timeout callback in case the rekey does not go through. */
5539 proto_ctx->timeout_task =
5540 silc_schedule_task_add(server->schedule, sock->sock,
5541 silc_server_rekey_timeout,
5543 (idata->rekey->timeout >
5544 server->config->key_exchange_timeout ?
5545 idata->rekey->timeout :
5546 server->config->key_exchange_timeout * 4), 0,
5550 /* Run the protocol */
5551 silc_protocol_execute(protocol, server->schedule, 0, 0);
5554 /* The final callback for the REKEY protocol. This will actually take the
5555 new key material into use. */
5557 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
5559 SilcProtocol protocol = (SilcProtocol)context;
5560 SilcServerRekeyInternalContext *ctx =
5561 (SilcServerRekeyInternalContext *)protocol->context;
5562 SilcServer server = (SilcServer)ctx->server;
5563 SilcSocketConnection sock = ctx->sock;
5564 SilcIDListData idata = (SilcIDListData)sock->user_data;
5566 if (ctx->timeout_task)
5567 silc_schedule_task_del(server->schedule, ctx->timeout_task);
5569 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
5570 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
5571 /* Error occured during protocol */
5572 SILC_LOG_ERROR(("Error occurred during rekey protocol with "
5573 "%s (%s)", sock->hostname, sock->ip));
5574 silc_protocol_cancel(protocol, server->schedule);
5575 silc_protocol_free(protocol);
5576 sock->protocol = NULL;
5578 silc_packet_context_free(ctx->packet);
5580 silc_ske_free(ctx->ske);
5581 silc_socket_free(sock);
5583 silc_server_disconnect_remote(server, sock,
5584 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
5585 if (sock->user_data)
5586 silc_server_free_sock_user_data(server, sock, NULL);
5589 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
5590 silc_server_create_connections(server);
5594 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
5595 sock->hostname, sock->port,
5596 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5597 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5598 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5601 /* Purge the outgoing data queue to assure that all rekey packets really
5602 go to the network before we quit the protocol. */
5603 silc_server_packet_queue_purge(server, sock);
5605 /* Re-register re-key timeout */
5606 if (ctx->responder == FALSE)
5607 silc_schedule_task_add(server->schedule, sock->sock,
5608 silc_server_rekey_callback,
5609 sock, idata->rekey->timeout, 0,
5610 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
5613 silc_protocol_free(protocol);
5614 sock->protocol = NULL;
5616 silc_packet_context_free(ctx->packet);
5618 silc_ske_free(ctx->ske);
5619 silc_socket_free(sock);
5623 /* Task callback used to retrieve network statistical information from
5624 router server once in a while. */
5626 SILC_TASK_CALLBACK(silc_server_get_stats)
5628 SilcServer server = (SilcServer)context;
5629 SilcBuffer idp, packet;
5631 if (!server->standalone) {
5632 SILC_LOG_DEBUG(("Retrieving stats from router"));
5633 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5634 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5635 ++server->cmd_ident, 1,
5636 1, idp->data, idp->len);
5637 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5638 SILC_PACKET_COMMAND, 0, packet->data,
5639 packet->len, FALSE);
5640 silc_buffer_free(packet);
5641 silc_buffer_free(idp);
5644 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
5645 server, 120, 0, SILC_TASK_TIMEOUT,