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);
184 silc_hash_free(server->md5hash);
185 silc_hash_free(server->sha1hash);
186 silc_hmac_unregister_all();
187 silc_hash_unregister_all();
188 silc_cipher_unregister_all();
189 silc_pkcs_unregister_all();
191 silc_free(server->local_list);
192 silc_free(server->global_list);
193 silc_free(server->server_name);
194 silc_free(server->id_string);
195 silc_free(server->purge_i);
196 silc_free(server->purge_g);
200 /* Creates a new server listener. */
202 static bool silc_server_listen(SilcServer server, const char *server_ip,
203 SilcUInt16 port, int *sock)
205 *sock = silc_net_create_server(port, server_ip);
207 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
214 /* Adds a secondary listener. */
216 bool silc_server_init_secondary(SilcServer server)
218 int sock = 0, sock_list[server->config->param.connections_max];
219 SilcSocketConnection newsocket = NULL;
220 SilcServerConfigServerInfoInterface *interface;
222 for (interface = server->config->server_info->secondary; interface;
223 interface = interface->next, sock++) {
225 if (!silc_server_listen(server,
226 interface->server_ip, interface->port, &sock_list[sock]))
229 /* Set socket to non-blocking mode */
230 silc_net_set_socket_nonblock(sock_list[sock]);
232 /* Add ourselves also to the socket table. The entry allocated above
233 is sent as argument for fast referencing in the future. */
234 silc_socket_alloc(sock_list[sock],
235 SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
236 server->sockets[sock_list[sock]] = newsocket;
237 SILC_SET_LISTENER(newsocket);
239 /* Perform name and address lookups to resolve the listenning address
241 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
243 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
245 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
246 newsocket->hostname ? newsocket->hostname :
247 newsocket->ip ? newsocket->ip : ""));
248 server->stat.conn_failures++;
251 if (!newsocket->hostname)
252 newsocket->hostname = strdup(newsocket->ip);
254 newsocket->port = silc_net_get_local_port(sock);
256 newsocket->user_data = (void *)server->id_entry;
257 silc_schedule_task_add(server->schedule, sock_list[sock],
258 silc_server_accept_new_connection,
259 (void *)server, 0, 0,
261 SILC_TASK_PRI_NORMAL);
267 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
271 /* Initializes the entire SILC server. This is called always before running
272 the server. This is called only once at the initialization of the program.
273 This binds the server to its listenning port. After this function returns
274 one should call silc_server_run to start the server. This returns TRUE
275 when everything is ok to run the server. Configuration file must be
276 read and parsed before calling this. */
278 bool silc_server_init(SilcServer server)
282 SilcServerEntry id_entry;
283 SilcIDListPurge purge;
284 SilcSocketConnection newsocket = NULL;
286 SILC_LOG_DEBUG(("Initializing server"));
288 server->starttime = time(NULL);
290 /* Take config object for us */
291 silc_server_config_ref(&server->config_ref, server->config,
295 /* Set debugging on if configured */
296 if (server->config->debug_string) {
298 silc_log_set_debug_string(server->config->debug_string);
300 #endif /* SILC_DEBUG */
302 /* Steal public and private key from the config object */
303 server->public_key = server->config->server_info->public_key;
304 server->private_key = server->config->server_info->private_key;
305 server->config->server_info->public_key = NULL;
306 server->config->server_info->private_key = NULL;
308 /* Register all configured ciphers, PKCS and hash functions. */
309 if (!silc_server_config_register_ciphers(server))
310 silc_cipher_register_default();
311 if (!silc_server_config_register_pkcs(server))
312 silc_pkcs_register_default();
313 if (!silc_server_config_register_hashfuncs(server))
314 silc_hash_register_default();
315 if (!silc_server_config_register_hmacs(server))
316 silc_hmac_register_default();
318 /* Initialize random number generator for the server. */
319 server->rng = silc_rng_alloc();
320 silc_rng_init(server->rng);
321 silc_rng_global_init(server->rng);
323 /* Initialize hash functions for server to use */
324 silc_hash_alloc("md5", &server->md5hash);
325 silc_hash_alloc("sha1", &server->sha1hash);
327 /* Allocate PKCS context for local public and private keys */
328 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
330 silc_pkcs_public_key_set(server->pkcs, server->public_key);
331 silc_pkcs_private_key_set(server->pkcs, server->private_key);
333 /* Initialize the scheduler */
334 server->schedule = silc_schedule_init(server->config->param.connections_max,
336 if (!server->schedule)
339 /* First, register log files configuration for error output */
340 silc_server_config_setlogfiles(server);
342 /* Initialize ID caches */
343 server->local_list->clients =
344 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
345 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
346 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
348 /* These are allocated for normal server as well as these hold some
349 global information that the server has fetched from its router. For
350 router these are used as they are supposed to be used on router. */
351 server->global_list->clients =
352 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
353 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
354 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
356 /* Init watcher list */
357 server->watcher_list =
358 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
359 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
361 if (!server->watcher_list)
364 /* Init public key list */
366 silc_hash_table_alloc(0, silc_hash_public_key, NULL,
367 silc_hash_public_key_compare, NULL,
370 if (!server->pk_hash)
373 /* Create a listening server */
374 if (!silc_server_listen(server,
375 server->config->server_info->primary == NULL ? NULL :
376 server->config->server_info->primary->server_ip,
377 server->config->server_info->primary == NULL ? 0 :
378 server->config->server_info->primary->port,
382 /* Set socket to non-blocking mode */
383 silc_net_set_socket_nonblock(sock);
386 /* Allocate the entire socket list that is used in server. Eventually
387 all connections will have entry in this table (it is a table of
388 pointers to the actual object that is allocated individually
390 server->sockets = silc_calloc(server->config->param.connections_max,
391 sizeof(*server->sockets));
392 if (!server->sockets)
395 /* Add ourselves also to the socket table. The entry allocated above
396 is sent as argument for fast referencing in the future. */
397 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
398 server->sockets[sock] = newsocket;
399 SILC_SET_LISTENER(newsocket);
401 /* Perform name and address lookups to resolve the listenning address
403 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
405 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
407 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
408 newsocket->hostname ? newsocket->hostname :
409 newsocket->ip ? newsocket->ip : ""));
410 server->stat.conn_failures++;
413 if (!newsocket->hostname)
414 newsocket->hostname = strdup(newsocket->ip);
416 newsocket->port = silc_net_get_local_port(sock);
418 /* Create a Server ID for the server. */
419 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
424 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
425 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
426 server->server_name = server->config->server_info->server_name;
427 server->config->server_info->server_name = NULL;
429 /* Add ourselves to the server list. We don't have a router yet
430 beacuse we haven't established a route yet. It will be done later.
431 For now, NULL is sent as router. This allocates new entry to
434 silc_idlist_add_server(server->local_list, strdup(server->server_name),
435 server->server_type, server->id, NULL, NULL);
437 SILC_LOG_ERROR(("Could not add ourselves to cache"));
440 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
442 /* Put the allocated socket pointer also to the entry allocated above
443 for fast back-referencing to the socket list. */
444 newsocket->user_data = (void *)id_entry;
445 id_entry->connection = (void *)newsocket;
446 server->id_entry = id_entry;
448 /* Register protocols */
449 silc_server_protocols_register();
451 /* Create connections to configured routers. */
452 silc_server_create_connections(server);
454 /* Add listener task to the scheduler. This task receives new connections
455 to the server. This task remains on the queue until the end of the
457 silc_schedule_task_add(server->schedule, sock,
458 silc_server_accept_new_connection,
459 (void *)server, 0, 0,
461 SILC_TASK_PRI_NORMAL);
463 if (silc_server_init_secondary(server) == FALSE)
466 server->listenning = TRUE;
468 /* If server connections has been configured then we must be router as
469 normal server cannot have server connections, only router connections. */
470 if (server->config->servers) {
471 SilcServerConfigServer *ptr = server->config->servers;
473 server->server_type = SILC_ROUTER;
475 if (ptr->backup_router) {
476 server->server_type = SILC_BACKUP_ROUTER;
477 server->backup_router = TRUE;
478 server->id_entry->server_type = SILC_BACKUP_ROUTER;
485 /* Register the ID Cache purge task. This periodically purges the ID cache
486 and removes the expired cache entries. */
488 /* Clients local list */
489 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
490 purge->cache = server->local_list->clients;
491 purge->timeout = 600;
492 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
493 (void *)purge, purge->timeout, 0,
494 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
496 /* Clients global list */
497 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
498 purge->cache = server->global_list->clients;
499 purge->timeout = 300;
500 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
501 (void *)purge, purge->timeout, 0,
502 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
504 /* If we are normal server we'll retrieve network statisticial information
505 once in a while from the router. */
506 if (server->server_type != SILC_ROUTER)
507 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
508 server, 10, 0, SILC_TASK_TIMEOUT,
511 if (server->server_type == SILC_ROUTER)
512 server->stat.routers++;
514 SILC_LOG_DEBUG(("Server initialized"));
516 /* We are done here, return succesfully */
520 silc_server_config_unref(&server->config_ref);
521 silc_net_close_server(sock);
525 /* Task callback to close a socket connection after rehash */
527 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
529 SilcServer server = context;
530 SilcSocketConnection sock = server->sockets[fd];
535 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
536 sock->hostname, sock->port,
537 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
538 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
539 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
541 silc_schedule_task_del_by_context(server->schedule, sock);
542 silc_server_disconnect_remote(server, sock,
543 SILC_STATUS_ERR_BANNED_FROM_SERVER,
544 "This connection is removed from "
547 silc_server_free_sock_user_data(server, sock, NULL);
550 /* This function basically reads the config file again and switches the config
551 object pointed by the server object. After that, we have to fix various
552 things such as the server_name and the listening ports.
553 Keep in mind that we no longer have the root privileges at this point. */
555 bool silc_server_rehash(SilcServer server)
557 SilcServerConfig newconfig;
559 SILC_LOG_INFO(("Rehashing server"));
561 /* Reset the logging system */
562 silc_log_quick = TRUE;
563 silc_log_flush_all();
565 /* Start the main rehash phase (read again the config file) */
566 newconfig = silc_server_config_alloc(server->config_file);
568 SILC_LOG_ERROR(("Rehash FAILED."));
572 /* Reinit scheduler if necessary */
573 if (newconfig->param.connections_max > server->config->param.connections_max)
574 if (!silc_schedule_reinit(server->schedule,
575 newconfig->param.connections_max))
578 /* Fix the server_name field */
579 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
580 silc_free(server->server_name);
581 server->server_name = newconfig->server_info->server_name;
582 newconfig->server_info->server_name = NULL;
584 /* Update the idcache list with a fresh pointer */
585 silc_free(server->id_entry->server_name);
586 server->id_entry->server_name = strdup(server->server_name);
587 if (!silc_idcache_del_by_context(server->local_list->servers,
590 if (!silc_idcache_add(server->local_list->servers,
591 server->id_entry->server_name,
592 server->id_entry->id, server->id_entry, 0, NULL))
597 silc_server_config_setlogfiles(server);
599 /* Change new key pair if necessary */
600 if (newconfig->server_info->public_key &&
601 !silc_pkcs_public_key_compare(server->public_key,
602 newconfig->server_info->public_key)) {
603 silc_pkcs_public_key_free(server->public_key);
604 silc_pkcs_private_key_free(server->private_key);
605 server->public_key = newconfig->server_info->public_key;
606 server->private_key = newconfig->server_info->private_key;
607 newconfig->server_info->public_key = NULL;
608 newconfig->server_info->private_key = NULL;
610 /* Allocate PKCS context for local public and private keys */
611 silc_pkcs_free(server->pkcs);
612 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
614 silc_pkcs_public_key_set(server->pkcs, server->public_key);
615 silc_pkcs_private_key_set(server->pkcs, server->private_key);
618 /* Check for unconfigured server and router connections and close
619 connections that were unconfigured. */
621 if (server->config->routers) {
622 SilcServerConfigRouter *ptr;
623 SilcServerConfigRouter *newptr;
626 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
629 /* Check whether new config has this one too */
630 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
631 if (silc_string_compare(newptr->host, ptr->host) &&
632 newptr->port == ptr->port &&
633 newptr->initiator == ptr->initiator) {
639 if (!found && ptr->host) {
640 /* Remove this connection */
641 SilcSocketConnection sock;
642 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_ROUTER,
643 ptr->host, ptr->port);
644 if (sock && !SILC_IS_LISTENER(sock))
645 silc_schedule_task_add(server->schedule, sock->sock,
646 silc_server_rehash_close_connection,
647 server, 0, 1, SILC_TASK_TIMEOUT,
648 SILC_TASK_PRI_NORMAL);
653 if (server->config->servers) {
654 SilcServerConfigServer *ptr;
655 SilcServerConfigServer *newptr;
658 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
661 /* Check whether new config has this one too */
662 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
663 if (silc_string_compare(newptr->host, ptr->host)) {
669 if (!found && ptr->host) {
670 /* Remove this connection */
671 SilcSocketConnection sock;
672 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_SERVER,
674 if (sock && !SILC_IS_LISTENER(sock))
675 silc_schedule_task_add(server->schedule, sock->sock,
676 silc_server_rehash_close_connection,
677 server, 0, 1, SILC_TASK_TIMEOUT,
678 SILC_TASK_PRI_NORMAL);
683 if (server->config->clients) {
684 SilcServerConfigClient *ptr;
685 SilcServerConfigClient *newptr;
688 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
691 /* Check whether new config has this one too */
692 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
693 if (silc_string_compare(newptr->host, ptr->host)) {
699 if (!found && ptr->host) {
700 /* Remove this connection */
701 SilcSocketConnection sock;
702 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_CLIENT,
705 silc_schedule_task_add(server->schedule, sock->sock,
706 silc_server_rehash_close_connection,
707 server, 0, 1, SILC_TASK_TIMEOUT,
708 SILC_TASK_PRI_NORMAL);
713 /* Create connections after rehash */
714 silc_server_create_connections(server);
716 /* Check whether our router status has changed */
717 if (newconfig->servers) {
718 SilcServerConfigServer *ptr = newconfig->servers;
720 server->server_type = SILC_ROUTER;
722 if (ptr->backup_router) {
723 server->server_type = SILC_BACKUP_ROUTER;
724 server->backup_router = TRUE;
725 server->id_entry->server_type = SILC_BACKUP_ROUTER;
732 /* Our old config is gone now. We'll unreference our reference made in
733 silc_server_init and then destroy it since we are destroying it
734 underneath the application (layer which called silc_server_init). */
735 silc_server_config_unref(&server->config_ref);
736 silc_server_config_destroy(server->config);
738 /* Take new config context */
739 server->config = newconfig;
740 silc_server_config_ref(&server->config_ref, server->config, server->config);
743 /* Set debugging on if configured */
744 if (server->config->debug_string) {
746 silc_log_set_debug_string(server->config->debug_string);
750 #endif /* SILC_DEBUG */
752 SILC_LOG_DEBUG(("Server rehashed"));
757 /* The heart of the server. This runs the scheduler thus runs the server.
758 When this returns the server has been stopped and the program will
761 void silc_server_run(SilcServer server)
763 SILC_LOG_INFO(("SILC Server started"));
765 /* Start the scheduler, the heart of the SILC server. When this returns
766 the program will be terminated. */
767 silc_schedule(server->schedule);
770 /* Stops the SILC server. This function is used to shutdown the server.
771 This is usually called after the scheduler has returned. After stopping
772 the server one should call silc_server_free. */
774 void silc_server_stop(SilcServer server)
776 SILC_LOG_INFO(("SILC Server shutting down"));
778 if (server->schedule) {
781 server->server_shutdown = TRUE;
783 /* Close all connections */
784 for (i = 0; i < server->config->param.connections_max; i++) {
785 if (!server->sockets[i])
787 if (!SILC_IS_LISTENER(server->sockets[i])) {
788 SilcSocketConnection sock = server->sockets[i];
789 SilcIDListData idata = sock->user_data;
792 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
794 silc_schedule_task_del_by_context(server->schedule,
796 silc_schedule_task_del_by_fd(server->schedule,
797 server->sockets[i]->sock);
798 silc_server_disconnect_remote(server, server->sockets[i],
800 "Server is shutting down");
801 if (server->sockets[i]) {
803 silc_server_free_sock_user_data(server, sock,
804 "Server is shutting down");
805 silc_socket_free(sock);
808 silc_socket_free(server->sockets[i]);
809 server->sockets[i] = NULL;
813 /* We are not connected to network anymore */
814 server->standalone = TRUE;
816 silc_schedule_stop(server->schedule);
817 silc_schedule_uninit(server->schedule);
818 server->schedule = NULL;
820 silc_free(server->sockets);
821 server->sockets = NULL;
824 silc_server_protocols_unregister();
826 SILC_LOG_DEBUG(("Server stopped"));
829 /* Function that is called when the network connection to a router has
830 been established. This will continue with the key exchange protocol
831 with the remote router. */
833 void silc_server_start_key_exchange(SilcServer server,
834 SilcServerConnection sconn,
837 SilcSocketConnection newsocket;
838 SilcProtocol protocol;
839 SilcServerKEInternalContext *proto_ctx;
840 SilcServerConfigRouter *conn =
841 (SilcServerConfigRouter *) sconn->conn.ref_ptr;
844 /* Cancel any possible retry timeouts */
845 silc_schedule_task_del_by_callback(server->schedule,
846 silc_server_connect_to_router_retry);
848 /* Set socket options */
849 silc_net_set_socket_nonblock(sock);
850 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
852 /* Create socket connection for the connection. Even though we
853 know that we are connecting to a router we will mark the socket
854 to be unknown connection until we have executed authentication
856 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
857 server->sockets[sock] = newsocket;
858 newsocket->hostname = strdup(sconn->remote_host);
859 newsocket->ip = strdup(sconn->remote_host);
860 newsocket->port = sconn->remote_port;
861 sconn->sock = newsocket;
863 /* Allocate internal protocol context. This is sent as context
865 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
866 proto_ctx->server = (void *)server;
867 proto_ctx->context = (void *)sconn;
868 proto_ctx->sock = newsocket;
869 proto_ctx->rng = server->rng;
870 proto_ctx->responder = FALSE;
872 /* Set Key Exchange flags from configuration, but fall back to global
874 SILC_GET_SKE_FLAGS(conn, proto_ctx);
875 if (server->config->param.key_exchange_pfs)
876 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
878 /* Perform key exchange protocol. silc_server_connect_to_router_second
879 will be called after the protocol is finished. */
880 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
881 &protocol, proto_ctx,
882 silc_server_connect_to_router_second);
883 newsocket->protocol = protocol;
885 /* Register a timeout task that will be executed if the protocol
886 is not executed within set limit. */
887 proto_ctx->timeout_task =
888 silc_schedule_task_add(server->schedule, sock,
889 silc_server_timeout_remote,
890 server, server->config->key_exchange_timeout, 0,
894 /* Register the connection for network input and output. This sets
895 that scheduler will listen for incoming packets for this connection
896 and sets that outgoing packets may be sent to this connection as
897 well. However, this doesn't set the scheduler for outgoing traffic,
898 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
899 later when outgoing data is available. */
900 context = (void *)server;
901 SILC_REGISTER_CONNECTION_FOR_IO(sock);
903 /* Run the protocol */
904 silc_protocol_execute(protocol, server->schedule, 0, 0);
907 /* Timeout callback that will be called to retry connecting to remote
908 router. This is used by both normal and router server. This will wait
909 before retrying the connecting. The timeout is generated by exponential
910 backoff algorithm. */
912 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
914 SilcServer server = app_context;
915 SilcServerConnection sconn = (SilcServerConnection)context;
916 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
917 SilcServerConfigConnParams *param =
918 (conn->param ? conn->param : &server->config->param);
920 /* Don't retry if we are shutting down. */
921 if (server->server_shutdown) {
922 silc_server_config_unref(&sconn->conn);
923 silc_free(sconn->remote_host);
924 silc_free(sconn->backup_replace_ip);
929 SILC_LOG_INFO(("Retrying connecting to a router"));
931 /* Calculate next timeout */
932 if (sconn->retry_count >= 1) {
933 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
934 if (sconn->retry_timeout > param->reconnect_interval_max)
935 sconn->retry_timeout = param->reconnect_interval_max;
937 sconn->retry_timeout = param->reconnect_interval;
939 sconn->retry_count++;
940 sconn->retry_timeout = sconn->retry_timeout +
941 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
943 /* If we've reached max retry count, give up. */
944 if ((sconn->retry_count > param->reconnect_count) &&
945 !param->reconnect_keep_trying) {
946 SILC_LOG_ERROR(("Could not connect to router, giving up"));
947 silc_server_config_unref(&sconn->conn);
948 silc_free(sconn->remote_host);
949 silc_free(sconn->backup_replace_ip);
954 SILC_LOG_DEBUG(("Retrying connecting to a router in %d seconds",
955 sconn->retry_timeout));
957 /* We will lookup a fresh pointer later */
958 silc_server_config_unref(&sconn->conn);
960 /* Wait one before retrying */
961 silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
962 context, sconn->retry_timeout, 0,
963 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
966 /* callback for async connection to remote router */
968 SILC_TASK_CALLBACK(silc_server_connection_established)
970 SilcServer server = app_context;
971 SilcServerConnection sconn = (SilcServerConnection)context;
973 int opt = EINVAL, optlen = sizeof(opt);
975 silc_schedule_task_del_by_fd(server->schedule, sock);
976 silc_schedule_unset_listen_fd(server->schedule, sock);
978 if (silc_net_get_socket_opt(sock, SOL_SOCKET, SO_ERROR, &opt, &optlen) ||
980 SILC_LOG_ERROR(("Could not connect to router %s:%d: %s",
981 sconn->remote_host, sconn->remote_port,
983 if (!sconn->no_reconnect)
984 silc_schedule_task_add(server->schedule, 0,
985 silc_server_connect_to_router_retry,
986 context, 0, 1, SILC_TASK_TIMEOUT,
987 SILC_TASK_PRI_NORMAL);
989 silc_server_config_unref(&sconn->conn);
990 silc_free(sconn->remote_host);
991 silc_free(sconn->backup_replace_ip);
997 SILC_LOG_DEBUG(("Connection to router %s:%d established", sconn->remote_host,
998 sconn->remote_port));
1000 /* Continue with key exchange protocol */
1001 silc_server_start_key_exchange(server, sconn, sock);
1003 /* Generic routine to use connect to a router. */
1005 SILC_TASK_CALLBACK(silc_server_connect_router)
1007 SilcServer server = app_context;
1008 SilcServerConnection sconn = (SilcServerConnection)context;
1009 SilcServerConfigRouter *rconn;
1012 /* Don't connect if we are shutting down. */
1013 if (server->server_shutdown) {
1014 silc_free(sconn->remote_host);
1015 silc_free(sconn->backup_replace_ip);
1020 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1021 (sconn->backup ? "backup router" : "router"),
1022 sconn->remote_host, sconn->remote_port));
1024 server->router_connect = time(NULL);
1025 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1026 sconn->remote_port);
1028 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1029 (sconn->backup ? "backup router" : "router"),
1030 sconn->remote_host, sconn->remote_port));
1031 silc_free(sconn->remote_host);
1032 silc_free(sconn->backup_replace_ip);
1036 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1038 /* Connect to remote host */
1039 sock = silc_net_create_connection_async(
1040 (!server->config->server_info->primary ? NULL :
1041 server->config->server_info->primary->server_ip),
1042 sconn->remote_port, sconn->remote_host);
1044 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1045 sconn->remote_host, sconn->remote_port));
1046 if (!sconn->no_reconnect)
1047 silc_schedule_task_add(server->schedule, 0,
1048 silc_server_connect_to_router_retry,
1049 context, 0, 1, SILC_TASK_TIMEOUT,
1050 SILC_TASK_PRI_NORMAL);
1052 silc_server_config_unref(&sconn->conn);
1053 silc_free(sconn->remote_host);
1054 silc_free(sconn->backup_replace_ip);
1060 /* wait for the connection to be established */
1061 silc_schedule_task_add(server->schedule, sock,
1062 silc_server_connection_established,
1063 context, 0, 0, SILC_TASK_FD,
1064 SILC_TASK_PRI_NORMAL);
1065 silc_schedule_set_listen_fd(server->schedule, sock,
1066 SILC_TASK_WRITE, FALSE);
1069 /* This function connects to our primary router or if we are a router this
1070 establishes all our primary routes. This is called at the start of the
1071 server to do authentication and key exchange with our router - called
1074 SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router)
1076 SilcServer server = (SilcServer)context;
1077 SilcServerConnection sconn;
1078 SilcServerConfigRouter *ptr;
1080 /* Don't connect if we are shutting down. */
1081 if (server->server_shutdown)
1084 SILC_LOG_DEBUG(("We are %s",
1085 (server->server_type == SILC_SERVER ?
1086 "normal server" : server->server_type == SILC_ROUTER ?
1087 "router" : "backup router/normal server")));
1089 if (!server->config->routers) {
1090 /* There wasn't a configured router, we will continue but we don't
1091 have a connection to outside world. We will be standalone server. */
1092 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1093 server->standalone = TRUE;
1097 /* Cancel any possible retry timeouts */
1098 silc_schedule_task_del_by_callback(server->schedule,
1099 silc_server_connect_router);
1100 silc_schedule_task_del_by_callback(server->schedule,
1101 silc_server_connect_to_router_retry);
1103 /* Create the connections to all our routes */
1104 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1106 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1107 ptr->backup_router ? "Backup router" : "Router",
1108 ptr->initiator ? "Initiator" : "Responder",
1109 ptr->host, ptr->port));
1111 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1112 ptr->initiator == FALSE && !server->backup_router &&
1113 !silc_server_config_get_backup_router(server))
1114 server->wait_backup = TRUE;
1116 if (ptr->initiator) {
1117 /* Check whether we are connecting or connected to this host already */
1118 if (silc_server_num_sockets_by_remote(server,
1119 silc_net_is_ip(ptr->host) ?
1121 silc_net_is_ip(ptr->host) ?
1122 NULL : ptr->host, ptr->port,
1123 SILC_SOCKET_TYPE_ROUTER)) {
1124 SILC_LOG_DEBUG(("We are already connected to this router"));
1126 /* If we don't have primary router and this connection is our
1127 primary router we are in desync. Reconnect to the primary. */
1128 if (server->standalone && !server->router) {
1129 SilcServerConfigRouter *primary =
1130 silc_server_config_get_primary_router(server);
1131 if (primary == ptr) {
1132 SilcSocketConnection sock =
1133 silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_ROUTER,
1134 ptr->host, ptr->port);
1136 server->backup_noswitch = TRUE;
1137 if (sock->user_data)
1138 silc_server_free_sock_user_data(server, sock, NULL);
1139 silc_server_disconnect_remote(server, sock, 0, NULL);
1140 server->backup_noswitch = FALSE;
1141 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1152 if (silc_server_num_sockets_by_remote(server,
1153 silc_net_is_ip(ptr->host) ?
1155 silc_net_is_ip(ptr->host) ?
1156 NULL : ptr->host, ptr->port,
1157 SILC_SOCKET_TYPE_UNKNOWN)) {
1158 SILC_LOG_DEBUG(("We are already connecting to this router"));
1162 /* Allocate connection object for hold connection specific stuff. */
1163 sconn = silc_calloc(1, sizeof(*sconn));
1164 sconn->remote_host = strdup(ptr->host);
1165 sconn->remote_port = ptr->port;
1166 sconn->backup = ptr->backup_router;
1167 if (sconn->backup) {
1168 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1169 sconn->backup_replace_port = ptr->backup_replace_port;
1172 if (!server->router_conn && !sconn->backup)
1173 server->router_conn = sconn;
1175 silc_schedule_task_add(server->schedule, 0,
1176 silc_server_connect_router,
1177 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
1178 SILC_TASK_PRI_NORMAL);
1183 /* Second part of connecting to router(s). Key exchange protocol has been
1184 executed and now we will execute authentication protocol. */
1186 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
1188 SilcProtocol protocol = (SilcProtocol)context;
1189 SilcServerKEInternalContext *ctx =
1190 (SilcServerKEInternalContext *)protocol->context;
1191 SilcServer server = (SilcServer)ctx->server;
1192 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1193 SilcSocketConnection sock = ctx->sock;
1194 SilcServerConnAuthInternalContext *proto_ctx;
1195 SilcServerConfigRouter *conn = NULL;
1197 SILC_LOG_DEBUG(("Start"));
1199 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1200 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1201 /* Error occured during protocol */
1202 silc_protocol_free(protocol);
1203 sock->protocol = NULL;
1204 silc_ske_free_key_material(ctx->keymat);
1206 silc_packet_context_free(ctx->packet);
1208 silc_ske_free(ctx->ske);
1209 silc_free(ctx->dest_id);
1211 silc_server_disconnect_remote(server, sock,
1212 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1214 /* Try reconnecting if configuration wants it */
1215 if (!sconn->no_reconnect) {
1216 silc_schedule_task_add(server->schedule, 0,
1217 silc_server_connect_to_router_retry,
1218 sconn, 0, 1, SILC_TASK_TIMEOUT,
1219 SILC_TASK_PRI_NORMAL);
1223 /* Call completion to indicate error */
1224 if (sconn->callback)
1225 (*sconn->callback)(server, NULL, sconn->callback_context);
1227 silc_server_config_unref(&sconn->conn);
1228 silc_free(sconn->remote_host);
1229 silc_free(sconn->backup_replace_ip);
1234 /* We now have the key material as the result of the key exchange
1235 protocol. Take the key material into use. Free the raw key material
1236 as soon as we've set them into use. */
1237 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1238 ctx->sock, ctx->keymat,
1239 ctx->ske->prop->cipher,
1240 ctx->ske->prop->pkcs,
1241 ctx->ske->prop->hash,
1242 ctx->ske->prop->hmac,
1243 ctx->ske->prop->group,
1245 silc_protocol_free(protocol);
1246 sock->protocol = NULL;
1247 silc_ske_free_key_material(ctx->keymat);
1249 silc_packet_context_free(ctx->packet);
1251 silc_ske_free(ctx->ske);
1252 silc_free(ctx->dest_id);
1254 silc_server_disconnect_remote(server, sock,
1255 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1257 /* Try reconnecting if configuration wants it */
1258 if (!sconn->no_reconnect) {
1259 silc_schedule_task_add(server->schedule, 0,
1260 silc_server_connect_to_router_retry,
1261 sconn, 0, 1, SILC_TASK_TIMEOUT,
1262 SILC_TASK_PRI_NORMAL);
1266 /* Call completion to indicate error */
1267 if (sconn->callback)
1268 (*sconn->callback)(server, NULL, sconn->callback_context);
1270 silc_server_config_unref(&sconn->conn);
1271 silc_free(sconn->remote_host);
1272 silc_free(sconn->backup_replace_ip);
1276 silc_ske_free_key_material(ctx->keymat);
1278 /* Allocate internal context for the authentication protocol. This
1279 is sent as context for the protocol. */
1280 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1281 proto_ctx->server = (void *)server;
1282 proto_ctx->context = (void *)sconn;
1283 proto_ctx->sock = sock;
1284 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1285 proto_ctx->dest_id_type = ctx->dest_id_type;
1286 proto_ctx->dest_id = ctx->dest_id;
1288 /* Resolve the authentication method used in this connection. Check if
1289 we find a match from user configured connections */
1290 if (!sconn->conn.ref_ptr)
1291 conn = silc_server_config_find_router_conn(server, sock->hostname,
1294 conn = sconn->conn.ref_ptr;
1297 /* Match found. Use the configured authentication method. Take only
1298 the passphrase, since for public key auth we automatically use
1299 our local key pair. */
1300 if (conn->passphrase) {
1301 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1302 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
1304 proto_ctx->auth_data = strdup(conn->passphrase);
1305 proto_ctx->auth_data_len = strlen(conn->passphrase);
1306 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
1308 } else if (conn->publickeys) {
1309 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
1311 proto_ctx->auth_meth = SILC_AUTH_NONE;
1314 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
1315 sock->hostname, sock->ip, sock->port));
1316 silc_protocol_free(protocol);
1317 sock->protocol = NULL;
1319 silc_packet_context_free(ctx->packet);
1321 silc_ske_free(ctx->ske);
1322 silc_free(ctx->dest_id);
1324 silc_server_config_unref(&sconn->conn);
1325 silc_free(sconn->remote_host);
1326 silc_free(sconn->backup_replace_ip);
1328 silc_server_disconnect_remote(server, sock,
1329 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1333 /* Free old protocol as it is finished now */
1334 silc_protocol_free(protocol);
1336 silc_packet_context_free(ctx->packet);
1338 sock->protocol = NULL;
1340 /* Allocate the authentication protocol. This is allocated here
1341 but we won't start it yet. We will be receiving party of this
1342 protocol thus we will wait that connecting party will make
1343 their first move. */
1344 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1345 &sock->protocol, proto_ctx,
1346 silc_server_connect_to_router_final);
1348 /* Register timeout task. If the protocol is not executed inside
1349 this timelimit the connection will be terminated. */
1350 proto_ctx->timeout_task =
1351 silc_schedule_task_add(server->schedule, sock->sock,
1352 silc_server_timeout_remote,
1354 server->config->conn_auth_timeout, 0,
1358 /* Run the protocol */
1359 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1362 /* Finalizes the connection to router. Registers a server task to the
1363 queue so that we can accept new connections. */
1365 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
1367 SilcProtocol protocol = (SilcProtocol)context;
1368 SilcServerConnAuthInternalContext *ctx =
1369 (SilcServerConnAuthInternalContext *)protocol->context;
1370 SilcServer server = (SilcServer)ctx->server;
1371 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1372 SilcSocketConnection sock = ctx->sock;
1373 SilcServerEntry id_entry = NULL;
1375 unsigned char *id_string;
1377 SilcIDListData idata;
1378 SilcServerConfigRouter *conn = NULL;
1379 SilcServerConfigConnParams *param = NULL;
1381 SILC_LOG_DEBUG(("Start"));
1383 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1384 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1385 /* Error occured during protocol */
1386 silc_free(ctx->dest_id);
1387 sock->protocol = NULL;
1388 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1390 sock->protocol = protocol;
1392 /* Try reconnecting if configuration wants it */
1393 if (!sconn->no_reconnect) {
1394 silc_schedule_task_add(server->schedule, 0,
1395 silc_server_connect_to_router_retry,
1396 sconn, 0, 1, SILC_TASK_TIMEOUT,
1397 SILC_TASK_PRI_NORMAL);
1404 /* Add a task to the queue. This task receives new connections to the
1405 server. This task remains on the queue until the end of the program. */
1406 if (!server->listenning && !sconn->backup) {
1407 silc_schedule_task_add(server->schedule, server->sock,
1408 silc_server_accept_new_connection,
1409 (void *)server, 0, 0,
1411 SILC_TASK_PRI_NORMAL);
1412 server->listenning = TRUE;
1415 /* Send NEW_SERVER packet to the router. We will become registered
1416 to the SILC network after sending this packet. */
1417 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
1418 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
1419 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
1420 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1421 silc_buffer_format(packet,
1422 SILC_STR_UI_SHORT(id_len),
1423 SILC_STR_UI_XNSTRING(id_string, id_len),
1424 SILC_STR_UI_SHORT(strlen(server->server_name)),
1425 SILC_STR_UI_XNSTRING(server->server_name,
1426 strlen(server->server_name)),
1429 /* Send the packet */
1430 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
1431 packet->data, packet->len, TRUE);
1432 silc_buffer_free(packet);
1433 silc_free(id_string);
1435 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
1437 /* Check that we do not have this ID already */
1438 id_entry = silc_idlist_find_server_by_id(server->local_list,
1439 ctx->dest_id, TRUE, NULL);
1441 silc_idcache_del_by_context(server->local_list->servers, id_entry);
1443 id_entry = silc_idlist_find_server_by_id(server->global_list,
1444 ctx->dest_id, TRUE, NULL);
1446 silc_idcache_del_by_context(server->global_list->servers, id_entry);
1449 SILC_LOG_DEBUG(("New server id(%s)",
1450 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
1452 /* Add the connected router to global server list. Router is sent
1453 as NULL since it's local to us. */
1454 id_entry = silc_idlist_add_server(server->global_list,
1455 strdup(sock->hostname),
1456 SILC_ROUTER, ctx->dest_id, NULL, sock);
1458 silc_free(ctx->dest_id);
1459 SILC_LOG_ERROR(("Cannot add new server entry to cache"));
1460 sock->protocol = NULL;
1461 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1463 sock->protocol = protocol;
1467 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1468 silc_free(sock->user_data);
1469 sock->user_data = (void *)id_entry;
1470 sock->type = SILC_SOCKET_TYPE_ROUTER;
1471 idata = (SilcIDListData)sock->user_data;
1472 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1473 SILC_IDLIST_STATUS_LOCAL);
1475 conn = sconn->conn.ref_ptr;
1476 param = &server->config->param;
1477 if (conn && conn->param)
1478 param = conn->param;
1480 /* Perform keepalive. */
1481 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
1482 silc_server_perform_heartbeat,
1485 /* Register re-key timeout */
1486 idata->rekey->timeout = param->key_exchange_rekey;
1487 silc_schedule_task_add(server->schedule, sock->sock,
1488 silc_server_rekey_callback,
1489 (void *)sock, idata->rekey->timeout, 0,
1490 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1492 if (!sconn->backup) {
1493 /* Mark this router our primary router if we're still standalone */
1494 if (server->standalone) {
1495 SILC_LOG_DEBUG(("This connection is our primary router"));
1496 server->id_entry->router = id_entry;
1497 server->router = id_entry;
1498 server->router->server_type = SILC_ROUTER;
1499 server->standalone = FALSE;
1500 server->backup_primary = FALSE;
1502 /* Announce data if we are not backup router (unless not as primary
1503 currently). Backup router announces later at the end of
1504 resuming protocol. */
1505 if (server->backup_router && server->server_type == SILC_ROUTER) {
1506 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1508 /* If we are router then announce our possible servers. Backup
1509 router announces also global servers. */
1510 if (server->server_type == SILC_ROUTER)
1511 silc_server_announce_servers(server,
1512 server->backup_router ? TRUE : FALSE,
1513 0, SILC_PRIMARY_ROUTE(server));
1515 /* Announce our clients and channels to the router */
1516 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1517 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1520 /* If we are backup router then this primary router is whom we are
1522 if (server->server_type == SILC_BACKUP_ROUTER)
1523 silc_server_backup_add(server, server->id_entry, sock->ip,
1524 sconn->remote_port, TRUE);
1527 /* Add this server to be our backup router */
1528 id_entry->server_type = SILC_BACKUP_ROUTER;
1529 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1530 sconn->backup_replace_port, FALSE);
1533 sock->protocol = NULL;
1536 /* Call the completion callback to indicate that we've connected to
1538 if (sconn && sconn->callback)
1539 (*sconn->callback)(server, id_entry, sconn->callback_context);
1541 /* Free the temporary connection data context */
1543 silc_server_config_unref(&sconn->conn);
1544 silc_free(sconn->remote_host);
1545 silc_free(sconn->backup_replace_ip);
1548 if (sconn == server->router_conn)
1549 server->router_conn = NULL;
1552 /* Free the protocol object */
1553 if (sock->protocol == protocol)
1554 sock->protocol = NULL;
1555 silc_protocol_free(protocol);
1557 silc_packet_context_free(ctx->packet);
1559 silc_ske_free(ctx->ske);
1560 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1561 silc_free(ctx->auth_data);
1565 /* Host lookup callback that is called after the incoming connection's
1566 IP and FQDN lookup is performed. This will actually check the acceptance
1567 of the incoming connection and will register the key exchange protocol
1568 for this connection. */
1571 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1574 SilcServerKEInternalContext *proto_ctx =
1575 (SilcServerKEInternalContext *)context;
1576 SilcServer server = (SilcServer)proto_ctx->server;
1577 SilcServerConfigClient *cconfig = NULL;
1578 SilcServerConfigServer *sconfig = NULL;
1579 SilcServerConfigRouter *rconfig = NULL;
1580 SilcServerConfigDeny *deny;
1583 /* Check whether we could resolve both IP and FQDN. */
1584 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1585 server->config->require_reverse_lookup)) {
1586 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1587 sock->hostname ? sock->hostname :
1588 sock->ip ? sock->ip : ""));
1589 server->stat.conn_failures++;
1590 silc_server_disconnect_remote(server, sock,
1591 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1592 "Unknown host or IP");
1593 silc_free(proto_ctx);
1597 /* Register the connection for network input and output. This sets
1598 that scheduler will listen for incoming packets for this connection
1599 and sets that outgoing packets may be sent to this connection as well.
1600 However, this doesn't set the scheduler for outgoing traffic, it
1601 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1602 later when outgoing data is available. */
1603 context = (void *)server;
1604 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1606 SILC_LOG_INFO(("Incoming connection %s (%s)", sock->hostname,
1609 /* Listenning port */
1610 if (!server->sockets[SILC_PTR_TO_32(proto_ctx->context)]) {
1611 silc_server_disconnect_remote(server, sock,
1612 SILC_STATUS_ERR_RESOURCE_LIMIT,
1613 "Connection refused");
1614 server->stat.conn_failures++;
1615 silc_free(proto_ctx);
1618 port = server->sockets[SILC_PTR_TO_32(proto_ctx->context)]->port;
1620 /* Check whether this connection is denied to connect to us. */
1621 deny = silc_server_config_find_denied(server, sock->ip);
1623 deny = silc_server_config_find_denied(server, sock->hostname);
1625 /* The connection is denied */
1626 SILC_LOG_INFO(("Connection %s (%s) is denied",
1627 sock->hostname, sock->ip));
1628 silc_server_disconnect_remote(server, sock,
1629 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1631 server->stat.conn_failures++;
1632 silc_free(proto_ctx);
1636 /* Check whether we have configured this sort of connection at all. We
1637 have to check all configurations since we don't know what type of
1638 connection this is. */
1639 if (!(cconfig = silc_server_config_find_client(server, sock->ip)))
1640 cconfig = silc_server_config_find_client(server, sock->hostname);
1641 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1642 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1643 if (server->server_type == SILC_ROUTER) {
1644 if (!(rconfig = silc_server_config_find_router_conn(server,
1645 sock->ip, sock->port)))
1646 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1649 if (!cconfig && !sconfig && !rconfig) {
1650 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1652 silc_server_disconnect_remote(server, sock,
1653 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
1654 server->stat.conn_failures++;
1655 silc_free(proto_ctx);
1659 /* The connection is allowed */
1661 /* Set internal context for key exchange protocol. This is
1662 sent as context for the protocol. */
1663 proto_ctx->sock = sock;
1664 proto_ctx->rng = server->rng;
1665 proto_ctx->responder = TRUE;
1666 silc_server_config_ref(&proto_ctx->cconfig, server->config, cconfig);
1667 silc_server_config_ref(&proto_ctx->sconfig, server->config, sconfig);
1668 silc_server_config_ref(&proto_ctx->rconfig, server->config, rconfig);
1670 /* Take flags for key exchange. Since we do not know what type of connection
1671 this is, we go through all found configurations and use the global ones
1672 as well. This will result always into strictest key exchange flags. */
1673 SILC_GET_SKE_FLAGS(cconfig, proto_ctx);
1674 SILC_GET_SKE_FLAGS(sconfig, proto_ctx);
1675 SILC_GET_SKE_FLAGS(rconfig, proto_ctx);
1676 if (server->config->param.key_exchange_pfs)
1677 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
1679 /* Prepare the connection for key exchange protocol. We allocate the
1680 protocol but will not start it yet. The connector will be the
1681 initiator of the protocol thus we will wait for initiation from
1682 there before we start the protocol. */
1683 server->stat.auth_attempts++;
1684 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1685 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1686 &sock->protocol, proto_ctx,
1687 silc_server_accept_new_connection_second);
1689 /* Register a timeout task that will be executed if the connector
1690 will not start the key exchange protocol within specified timeout
1691 and the connection will be closed. */
1692 proto_ctx->timeout_task =
1693 silc_schedule_task_add(server->schedule, sock->sock,
1694 silc_server_timeout_remote,
1696 server->config->key_exchange_timeout, 0,
1701 /* Accepts new connections to the server. Accepting new connections are
1702 done in three parts to make it async. */
1704 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1706 SilcServer server = (SilcServer)context;
1707 SilcSocketConnection newsocket;
1708 SilcServerKEInternalContext *proto_ctx;
1711 SILC_LOG_DEBUG(("Accepting new connection"));
1713 server->stat.conn_attempts++;
1715 sock = silc_net_accept_connection(fd);
1717 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1718 server->stat.conn_failures++;
1722 /* Check for maximum allowed connections */
1723 if (sock > server->config->param.connections_max) {
1724 SILC_LOG_ERROR(("Refusing connection, server is full"));
1725 server->stat.conn_failures++;
1726 silc_net_close_connection(sock);
1730 /* Set socket options */
1731 silc_net_set_socket_nonblock(sock);
1732 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1734 /* We don't create a ID yet, since we don't know what type of connection
1735 this is yet. But, we do add the connection to the socket table. */
1736 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1737 server->sockets[sock] = newsocket;
1739 /* Perform asynchronous host lookup. This will lookup the IP and the
1740 FQDN of the remote connection. After the lookup is done the connection
1741 is accepted further. */
1742 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1743 proto_ctx->server = server;
1744 proto_ctx->context = SILC_32_TO_PTR(fd);
1745 silc_socket_host_lookup(newsocket, TRUE,
1746 silc_server_accept_new_connection_lookup,
1747 (void *)proto_ctx, server->schedule);
1750 /* Second part of accepting new connection. Key exchange protocol has been
1751 performed and now it is time to do little connection authentication
1752 protocol to figure out whether this connection is client or server
1753 and whether it has right to access this server (especially server
1754 connections needs to be authenticated). */
1756 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1758 SilcProtocol protocol = (SilcProtocol)context;
1759 SilcServerKEInternalContext *ctx =
1760 (SilcServerKEInternalContext *)protocol->context;
1761 SilcServer server = (SilcServer)ctx->server;
1762 SilcSocketConnection sock = ctx->sock;
1763 SilcServerConnAuthInternalContext *proto_ctx;
1765 SILC_LOG_DEBUG(("Start"));
1767 if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
1768 (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
1769 /* Error occured during protocol */
1770 SILC_LOG_DEBUG(("Error in key exchange protocol"));
1771 silc_protocol_free(protocol);
1772 sock->protocol = NULL;
1773 silc_ske_free_key_material(ctx->keymat);
1775 silc_packet_context_free(ctx->packet);
1777 silc_ske_free(ctx->ske);
1778 silc_free(ctx->dest_id);
1779 silc_server_config_unref(&ctx->cconfig);
1780 silc_server_config_unref(&ctx->sconfig);
1781 silc_server_config_unref(&ctx->rconfig);
1784 if (!SILC_IS_DISCONNECTING(sock)) {
1785 SILC_LOG_INFO(("Key exchange failed for %s:%d [%s]", sock->hostname,
1787 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1788 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1789 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1791 silc_server_disconnect_remote(server, sock,
1792 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
1796 server->stat.auth_failures++;
1800 /* We now have the key material as the result of the key exchange
1801 protocol. Take the key material into use. Free the raw key material
1802 as soon as we've set them into use. */
1803 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1804 ctx->sock, ctx->keymat,
1805 ctx->ske->prop->cipher,
1806 ctx->ske->prop->pkcs,
1807 ctx->ske->prop->hash,
1808 ctx->ske->prop->hmac,
1809 ctx->ske->prop->group,
1811 SILC_LOG_ERROR(("Error setting key material in use"));
1812 silc_protocol_free(protocol);
1813 sock->protocol = NULL;
1814 silc_ske_free_key_material(ctx->keymat);
1816 silc_packet_context_free(ctx->packet);
1818 silc_ske_free(ctx->ske);
1819 silc_free(ctx->dest_id);
1820 silc_server_config_unref(&ctx->cconfig);
1821 silc_server_config_unref(&ctx->sconfig);
1822 silc_server_config_unref(&ctx->rconfig);
1824 silc_server_disconnect_remote(server, sock,
1825 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1826 server->stat.auth_failures++;
1829 silc_ske_free_key_material(ctx->keymat);
1831 /* Allocate internal context for the authentication protocol. This
1832 is sent as context for the protocol. */
1833 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1834 proto_ctx->server = (void *)server;
1835 proto_ctx->sock = sock;
1836 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1837 proto_ctx->responder = TRUE;
1838 proto_ctx->dest_id_type = ctx->dest_id_type;
1839 proto_ctx->dest_id = ctx->dest_id;
1840 proto_ctx->cconfig = ctx->cconfig;
1841 proto_ctx->sconfig = ctx->sconfig;
1842 proto_ctx->rconfig = ctx->rconfig;
1844 /* Free old protocol as it is finished now */
1845 silc_protocol_free(protocol);
1847 silc_packet_context_free(ctx->packet);
1849 sock->protocol = NULL;
1851 /* Allocate the authentication protocol. This is allocated here
1852 but we won't start it yet. We will be receiving party of this
1853 protocol thus we will wait that connecting party will make
1854 their first move. */
1855 SILC_LOG_DEBUG(("Starting connection authentication protocol"));
1856 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1857 &sock->protocol, proto_ctx,
1858 silc_server_accept_new_connection_final);
1860 /* Register timeout task. If the protocol is not executed inside
1861 this timelimit the connection will be terminated. */
1862 proto_ctx->timeout_task =
1863 silc_schedule_task_add(server->schedule, sock->sock,
1864 silc_server_timeout_remote,
1866 server->config->conn_auth_timeout, 0,
1871 /* After this is called, server don't wait for backup router anymore.
1872 This gets called automatically even after we have backup router
1873 connection established. */
1875 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
1877 SilcServer server = context;
1878 server->wait_backup = FALSE;
1881 /* Final part of accepting new connection. The connection has now
1882 been authenticated and keys has been exchanged. We also know whether
1883 this is client or server connection. */
1885 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1887 SilcProtocol protocol = (SilcProtocol)context;
1888 SilcServerConnAuthInternalContext *ctx =
1889 (SilcServerConnAuthInternalContext *)protocol->context;
1890 SilcServer server = (SilcServer)ctx->server;
1891 SilcSocketConnection sock = ctx->sock;
1892 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1894 SilcServerConfigConnParams *param = &server->config->param;
1896 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1897 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1898 /* Error occured during protocol */
1899 SILC_LOG_DEBUG(("Error during authentication protocol"));
1900 silc_protocol_free(protocol);
1901 sock->protocol = NULL;
1903 silc_packet_context_free(ctx->packet);
1905 silc_ske_free(ctx->ske);
1906 silc_free(ctx->dest_id);
1907 silc_server_config_unref(&ctx->cconfig);
1908 silc_server_config_unref(&ctx->sconfig);
1909 silc_server_config_unref(&ctx->rconfig);
1912 if (!SILC_IS_DISCONNECTING(sock)) {
1913 SILC_LOG_INFO(("Authentication failed for %s:%d [%s]", sock->hostname,
1915 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1916 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1917 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1919 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1922 server->stat.auth_failures++;
1926 entry->data.last_receive = time(NULL);
1928 switch (ctx->conn_type) {
1929 case SILC_SOCKET_TYPE_CLIENT:
1931 SilcClientEntry client;
1932 SilcServerConfigClient *conn = ctx->cconfig.ref_ptr;
1934 /* Verify whether this connection is after all allowed to connect */
1935 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1936 &server->config->param,
1937 conn->param, ctx->ske)) {
1938 server->stat.auth_failures++;
1942 /* If we are primary router and we have backup router configured
1943 but it has not connected to use yet, do not accept any other
1945 if (server->wait_backup && server->server_type == SILC_ROUTER &&
1946 !server->backup_router) {
1947 SilcServerConfigRouter *router;
1948 router = silc_server_config_get_backup_router(server);
1949 if (router && strcmp(server->config->server_info->primary->server_ip,
1951 silc_server_find_socket_by_host(server,
1952 SILC_SOCKET_TYPE_SERVER,
1953 router->backup_replace_ip, 0)) {
1954 SILC_LOG_INFO(("Will not accept connections because we do "
1955 "not have backup router connection established"));
1956 sock->protocol = NULL;
1957 silc_server_disconnect_remote(server, sock,
1958 SILC_STATUS_ERR_PERM_DENIED,
1959 "We do not have connection to backup "
1960 "router established, try later");
1961 silc_free(sock->user_data);
1962 server->stat.auth_failures++;
1964 /* From here on, wait 20 seconds for the backup router to appear. */
1965 silc_schedule_task_add(server->schedule, 0,
1966 silc_server_backup_router_wait,
1967 (void *)server, 20, 0,
1968 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1973 SILC_LOG_DEBUG(("Remote host is client"));
1974 SILC_LOG_INFO(("Connection %s (%s) is client", sock->hostname,
1977 /* Add the client to the client ID cache. The nickname and Client ID
1978 and other information is created after we have received NEW_CLIENT
1979 packet from client. */
1980 client = silc_idlist_add_client(server->local_list,
1981 NULL, NULL, NULL, NULL, NULL, sock, 0);
1983 SILC_LOG_ERROR(("Could not add new client to cache"));
1984 silc_free(sock->user_data);
1985 sock->protocol = NULL;
1986 silc_server_disconnect_remote(server, sock,
1987 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1988 server->stat.auth_failures++;
1991 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1994 server->stat.my_clients++;
1995 server->stat.clients++;
1996 server->stat.cell_clients++;
1998 /* Get connection parameters */
2000 param = conn->param;
2002 if (!param->keepalive_secs)
2003 param->keepalive_secs = server->config->param.keepalive_secs;
2005 if (!param->qos && server->config->param.qos) {
2006 param->qos = server->config->param.qos;
2007 param->qos_rate_limit = server->config->param.qos_rate_limit;
2008 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2009 param->qos_limit_sec = server->config->param.qos_limit_sec;
2010 param->qos_limit_usec = server->config->param.qos_limit_usec;
2013 /* Check if to be anonymous connection */
2014 if (param->anonymous)
2015 client->mode |= SILC_UMODE_ANONYMOUS;
2018 /* Add public key to hash list (for whois using attributes) */
2019 silc_hash_table_add(server->pk_hash,
2020 entry->data.public_key, client);
2022 id_entry = (void *)client;
2025 case SILC_SOCKET_TYPE_SERVER:
2026 case SILC_SOCKET_TYPE_ROUTER:
2028 SilcServerEntry new_server;
2029 bool initiator = FALSE;
2030 bool backup_local = FALSE;
2031 bool backup_router = FALSE;
2032 char *backup_replace_ip = NULL;
2033 SilcUInt16 backup_replace_port = 0;
2034 SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
2035 SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
2037 /* If we are backup router and this is incoming server connection
2038 and we do not have connection to primary router, do not allow
2040 if (server->server_type == SILC_BACKUP_ROUTER &&
2041 ctx->conn_type == SILC_SOCKET_TYPE_SERVER &&
2042 !SILC_PRIMARY_ROUTE(server)) {
2043 SILC_LOG_INFO(("Will not accept server connection because we do "
2044 "not have primary router connection established"));
2045 sock->protocol = NULL;
2046 silc_server_disconnect_remote(server, sock,
2047 SILC_STATUS_ERR_PERM_DENIED,
2048 "We do not have connection to primary "
2049 "router established, try later");
2050 silc_free(sock->user_data);
2051 server->stat.auth_failures++;
2055 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
2056 /* Verify whether this connection is after all allowed to connect */
2057 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
2058 &server->config->param,
2059 rconn ? rconn->param : NULL,
2061 silc_free(sock->user_data);
2062 server->stat.auth_failures++;
2068 param = rconn->param;
2070 if (!param->keepalive_secs)
2071 param->keepalive_secs = server->config->param.keepalive_secs;
2073 if (!param->qos && server->config->param.qos) {
2074 param->qos = server->config->param.qos;
2075 param->qos_rate_limit = server->config->param.qos_rate_limit;
2076 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2077 param->qos_limit_sec = server->config->param.qos_limit_sec;
2078 param->qos_limit_usec = server->config->param.qos_limit_usec;
2082 initiator = rconn->initiator;
2083 backup_local = rconn->backup_local;
2084 backup_router = rconn->backup_router;
2085 backup_replace_ip = rconn->backup_replace_ip;
2086 backup_replace_port = rconn->backup_replace_port;
2090 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
2091 /* Verify whether this connection is after all allowed to connect */
2092 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
2093 &server->config->param,
2094 sconn ? sconn->param : NULL,
2096 silc_free(sock->user_data);
2097 server->stat.auth_failures++;
2102 param = sconn->param;
2104 if (!param->keepalive_secs)
2105 param->keepalive_secs = server->config->param.keepalive_secs;
2107 if (!param->qos && server->config->param.qos) {
2108 param->qos = server->config->param.qos;
2109 param->qos_rate_limit = server->config->param.qos_rate_limit;
2110 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2111 param->qos_limit_sec = server->config->param.qos_limit_sec;
2112 param->qos_limit_usec = server->config->param.qos_limit_usec;
2116 backup_router = sconn->backup_router;
2120 /* If we are primary router and we have backup router configured
2121 but it has not connected to use yet, do not accept any other
2123 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2124 !server->backup_router && !backup_router) {
2125 SilcServerConfigRouter *router;
2126 router = silc_server_config_get_backup_router(server);
2127 if (router && strcmp(server->config->server_info->primary->server_ip,
2129 silc_server_find_socket_by_host(server,
2130 SILC_SOCKET_TYPE_SERVER,
2131 router->backup_replace_ip, 0)) {
2132 SILC_LOG_INFO(("Will not accept connections because we do "
2133 "not have backup router connection established"));
2134 sock->protocol = NULL;
2135 silc_server_disconnect_remote(server, sock,
2136 SILC_STATUS_ERR_PERM_DENIED,
2137 "We do not have connection to backup "
2138 "router established, try later");
2139 silc_free(sock->user_data);
2140 server->stat.auth_failures++;
2142 /* From here on, wait 20 seconds for the backup router to appear. */
2143 silc_schedule_task_add(server->schedule, 0,
2144 silc_server_backup_router_wait,
2145 (void *)server, 20, 0,
2146 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2151 SILC_LOG_DEBUG(("Remote host is %s",
2152 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2153 "server" : (backup_router ?
2154 "backup router" : "router")));
2155 SILC_LOG_INFO(("Connection %s (%s) is %s", sock->hostname,
2156 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2157 "server" : (backup_router ?
2158 "backup router" : "router")));
2160 /* Add the server into server cache. The server name and Server ID
2161 is updated after we have received NEW_SERVER packet from the
2162 server. We mark ourselves as router for this server if we really
2165 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2166 server->local_list : (backup_router ?
2167 server->local_list :
2168 server->global_list)),
2170 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2171 SILC_SERVER : SILC_ROUTER),
2173 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2174 server->id_entry : (backup_router ?
2175 server->id_entry : NULL)),
2178 SILC_LOG_ERROR(("Could not add new server to cache"));
2179 silc_free(sock->user_data);
2180 sock->protocol = NULL;
2181 silc_server_disconnect_remote(server, sock,
2182 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2183 server->stat.auth_failures++;
2186 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2188 id_entry = (void *)new_server;
2190 /* If the incoming connection is router and marked as backup router
2191 then add it to be one of our backups */
2192 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
2193 /* Change it back to SERVER type since that's what it really is. */
2195 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
2196 new_server->server_type = SILC_BACKUP_ROUTER;
2198 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2199 ("Backup router %s is now online",
2202 /* Remove the backup waiting with timeout */
2203 silc_schedule_task_add(server->schedule, 0,
2204 silc_server_backup_router_wait,
2205 (void *)server, 10, 0,
2206 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2210 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
2211 server->stat.my_servers++;
2213 server->stat.my_routers++;
2214 server->stat.routers++;
2216 server->stat.servers++;
2218 /* Check whether this connection is to be our primary router connection
2219 if we do not already have the primary route. */
2220 if (!backup_router &&
2221 server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
2222 if (silc_server_config_is_primary_route(server) && !initiator)
2225 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2226 server->standalone = FALSE;
2227 if (!server->id_entry->router) {
2228 server->id_entry->router = id_entry;
2229 server->router = id_entry;
2240 sock->type = ctx->conn_type;
2242 /* Add the common data structure to the ID entry. */
2243 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
2245 /* Add to sockets internal pointer for fast referencing */
2246 silc_free(sock->user_data);
2247 sock->user_data = id_entry;
2249 /* Connection has been fully established now. Everything is ok. */
2250 SILC_LOG_DEBUG(("New connection authenticated"));
2252 /* Perform keepalive. */
2253 if (param->keepalive_secs)
2254 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
2255 silc_server_perform_heartbeat,
2258 /* Perform Quality of Service */
2260 silc_socket_set_qos(sock, param->qos_rate_limit, param->qos_bytes_limit,
2261 param->qos_limit_sec, param->qos_limit_usec,
2265 if (sock->protocol == protocol)
2266 silc_protocol_free(protocol);
2268 silc_packet_context_free(ctx->packet);
2270 silc_ske_free(ctx->ske);
2271 silc_free(ctx->dest_id);
2272 silc_server_config_unref(&ctx->cconfig);
2273 silc_server_config_unref(&ctx->sconfig);
2274 silc_server_config_unref(&ctx->rconfig);
2276 sock->protocol = NULL;
2279 /* This function is used to read packets from network and send packets to
2280 network. This is usually a generic task. */
2282 SILC_TASK_CALLBACK(silc_server_packet_process)
2284 SilcServer server = (SilcServer)context;
2285 SilcSocketConnection sock = server->sockets[fd];
2286 SilcIDListData idata;
2287 SilcCipher cipher = NULL;
2288 SilcHmac hmac = NULL;
2289 SilcUInt32 sequence = 0;
2290 bool local_is_router;
2294 SILC_LOG_DEBUG(("Unknown socket connection"));
2298 /* Packet sending */
2300 if (type == SILC_TASK_WRITE) {
2301 /* Do not send data to disconnected connection */
2302 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2303 SILC_LOG_DEBUG(("Disconnected socket connection, cannot send"));
2304 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
2305 SILC_UNSET_OUTBUF_PENDING(sock);
2306 silc_buffer_clear(sock->outbuf);
2310 server->stat.packets_sent++;
2312 /* Send the packet */
2313 ret = silc_packet_send(sock, TRUE);
2315 /* If returned -2 could not write to connection now, will do
2320 /* The packet has been sent and now it is time to set the connection
2321 back to only for input. When there is again some outgoing data
2322 available for this connection it will be set for output as well.
2323 This call clears the output setting and sets it only for input. */
2324 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
2325 SILC_UNSET_OUTBUF_PENDING(sock);
2326 silc_buffer_clear(sock->outbuf);
2329 SILC_LOG_ERROR(("Error sending packet to connection "
2330 "%s:%d [%s]", sock->hostname, sock->port,
2331 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2332 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2333 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2336 if (sock->user_data) {
2337 /* If backup then mark that resuming will not be allowed */
2338 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2339 sock->type == SILC_SOCKET_TYPE_SERVER) {
2340 SilcServerEntry server_entry = sock->user_data;
2341 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2342 server->backup_closed = TRUE;
2345 silc_server_free_sock_user_data(server, sock, NULL);
2347 SILC_SET_DISCONNECTING(sock);
2348 silc_server_close_connection(server, sock);
2353 /* Packet receiving */
2355 /* Read some data from connection */
2356 ret = silc_packet_receive(sock);
2360 SILC_LOG_ERROR(("Error receiving packet from connection "
2361 "%s:%d [%s] %s", sock->hostname, sock->port,
2362 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2363 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2364 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2365 "Router"), strerror(errno)));
2367 if (sock->user_data) {
2368 /* If backup then mark that resuming will not be allowed */
2369 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2370 sock->type == SILC_SOCKET_TYPE_SERVER) {
2371 SilcServerEntry server_entry = sock->user_data;
2372 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2373 server->backup_closed = TRUE;
2376 silc_server_free_sock_user_data(server, sock, NULL);
2378 SILC_SET_DISCONNECTING(sock);
2379 silc_server_close_connection(server, sock);
2386 SILC_LOG_DEBUG(("Read EOF"));
2388 /* If connection is disconnecting already we will finally
2389 close the connection */
2390 if (SILC_IS_DISCONNECTING(sock)) {
2391 if (sock->user_data)
2392 silc_server_free_sock_user_data(server, sock, NULL);
2393 silc_server_close_connection(server, sock);
2397 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
2399 if (sock->user_data) {
2402 /* If backup disconnected then mark that resuming will not be allowed */
2403 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2404 sock->type == SILC_SOCKET_TYPE_SERVER && sock->user_data) {
2405 SilcServerEntry server_entry = sock->user_data;
2406 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2407 server->backup_closed = TRUE;
2410 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
2411 silc_server_free_sock_user_data(server, sock, tmp);
2413 silc_server_free_sock_user_data(server, sock, NULL);
2414 } else if (server->router_conn && server->router_conn->sock == sock &&
2415 !server->router && server->standalone) {
2416 silc_server_create_connections(server);
2419 SILC_SET_DISCONNECTING(sock);
2420 silc_server_close_connection(server, sock);
2424 /* If connection is disconnecting or disconnected we will ignore
2426 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2427 SILC_LOG_DEBUG(("Ignoring read data from disconnected connection"));
2431 /* Get keys and stuff from ID entry */
2432 idata = (SilcIDListData)sock->user_data;
2434 cipher = idata->receive_key;
2435 hmac = idata->hmac_receive;
2436 sequence = idata->psn_receive;
2439 /* Then, process the packet. This will call the parser that will then
2440 decrypt and parse the packet. */
2442 local_is_router = (server->server_type == SILC_ROUTER);
2444 /* If socket connection is our primary, we are backup and we are doing
2445 backup resuming, we won't process the packet as being a router
2446 (affects channel message decryption). */
2447 if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
2448 SILC_PRIMARY_ROUTE(server) == sock)
2449 local_is_router = FALSE;
2451 ret = silc_packet_receive_process(sock, local_is_router,
2452 cipher, hmac, sequence,
2453 silc_server_packet_parse, server);
2455 /* If processing failed the connection is closed. */
2457 /* On packet processing errors we may close our primary router
2458 connection but won't become primary router if we are the backup
2459 since this is local error condition. */
2460 if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
2461 server->backup_noswitch = TRUE;
2463 if (sock->user_data) {
2464 /* If we are router and backup errorred then mark that resuming
2465 will not be allowed */
2466 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2467 sock->type == SILC_SOCKET_TYPE_SERVER) {
2468 SilcServerEntry server_entry = sock->user_data;
2469 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2470 server->backup_closed = TRUE;
2473 silc_server_free_sock_user_data(server, sock, NULL);
2475 SILC_SET_DISCONNECTING(sock);
2476 silc_server_close_connection(server, sock);
2480 /* Parses whole packet, received earlier. */
2482 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
2484 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
2485 SilcServer server = (SilcServer)parse_ctx->context;
2486 SilcSocketConnection sock = parse_ctx->sock;
2487 SilcPacketContext *packet = parse_ctx->packet;
2488 SilcIDListData idata = (SilcIDListData)sock->user_data;
2491 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2492 SILC_LOG_DEBUG(("Connection is disconnected"));
2496 server->stat.packets_received++;
2498 /* Parse the packet */
2499 if (parse_ctx->normal)
2500 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
2502 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
2504 /* If entry is disabled ignore what we got. */
2505 if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
2506 ret != SILC_PACKET_HEARTBEAT && ret != SILC_PACKET_RESUME_ROUTER &&
2507 ret != SILC_PACKET_REKEY && ret != SILC_PACKET_REKEY_DONE) {
2508 SILC_LOG_DEBUG(("Connection is disabled"));
2512 if (ret == SILC_PACKET_NONE) {
2513 SILC_LOG_DEBUG(("Error parsing packet"));
2517 /* Check that the the current client ID is same as in the client's packet. */
2518 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2519 SilcClientEntry client = (SilcClientEntry)sock->user_data;
2520 if (client && client->id && packet->src_id) {
2521 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
2522 packet->src_id_type);
2523 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
2525 SILC_LOG_DEBUG(("Packet source is not same as sender"));
2532 if (server->server_type == SILC_ROUTER) {
2533 /* Route the packet if it is not destined to us. Other ID types but
2534 server are handled separately after processing them. */
2535 if (packet->dst_id && !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
2536 packet->dst_id_type == SILC_ID_SERVER &&
2537 sock->type != SILC_SOCKET_TYPE_CLIENT &&
2538 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
2540 /* Route the packet to fastest route for the destination ID */
2541 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
2542 packet->dst_id_type);
2545 silc_server_packet_route(server,
2546 silc_server_route_get(server, id,
2547 packet->dst_id_type),
2554 /* Parse the incoming packet type */
2555 silc_server_packet_parse_type(server, sock, packet);
2557 /* Broadcast packet if it is marked as broadcast packet and it is
2558 originated from router and we are router. */
2559 if (server->server_type == SILC_ROUTER &&
2560 sock->type == SILC_SOCKET_TYPE_ROUTER &&
2561 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
2562 /* Broadcast to our primary route */
2563 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
2565 /* If we have backup routers then we need to feed all broadcast
2566 data to those servers. */
2567 silc_server_backup_broadcast(server, sock, packet);
2571 silc_packet_context_free(packet);
2572 silc_free(parse_ctx);
2575 /* Parser callback called by silc_packet_receive_process. This merely
2576 registers timeout that will handle the actual parsing when appropriate. */
2578 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
2581 SilcServer server = (SilcServer)context;
2582 SilcSocketConnection sock = parser_context->sock;
2583 SilcIDListData idata = (SilcIDListData)sock->user_data;
2587 idata->psn_receive = parser_context->packet->sequence + 1;
2589 /* If protocol for this connection is key exchange or rekey then we'll
2590 process all packets synchronously, since there might be packets in
2591 queue that we are not able to decrypt without first processing the
2592 packets before them. */
2593 if (sock->protocol && sock->protocol->protocol &&
2594 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2595 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2596 silc_server_packet_parse_real(server->schedule, server, 0, sock->sock,
2599 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2600 SILC_LOG_DEBUG(("Connection is disconnected"));
2604 /* Reprocess data since we'll return FALSE here. This is because
2605 the idata->receive_key might have become valid in the last packet
2606 and we want to call this processor with valid cipher. */
2608 ret = silc_packet_receive_process(
2609 sock, server->server_type == SILC_ROUTER,
2611 idata->hmac_receive, idata->psn_receive,
2612 silc_server_packet_parse, server);
2614 ret = silc_packet_receive_process(
2615 sock, server->server_type == SILC_ROUTER,
2617 silc_server_packet_parse, server);
2620 /* On packet processing errors we may close our primary router
2621 connection but won't become primary router if we are the backup
2622 since this is local error condition. */
2623 if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
2624 server->backup_noswitch = TRUE;
2626 if (sock->user_data)
2627 silc_server_free_sock_user_data(server, sock, NULL);
2628 SILC_SET_DISCONNECTING(sock);
2629 silc_server_close_connection(server, sock);
2635 switch (sock->type) {
2636 case SILC_SOCKET_TYPE_UNKNOWN:
2637 case SILC_SOCKET_TYPE_CLIENT:
2638 /* Parse the packet with timeout */
2639 silc_schedule_task_add(server->schedule, sock->sock,
2640 silc_server_packet_parse_real,
2641 (void *)parser_context, 0, 100000,
2643 SILC_TASK_PRI_NORMAL);
2645 case SILC_SOCKET_TYPE_SERVER:
2646 case SILC_SOCKET_TYPE_ROUTER:
2647 /* Packets from servers are parsed immediately */
2648 silc_server_packet_parse_real(server->schedule, server, 0, sock->sock,
2656 /* Parses the packet type and calls what ever routines the packet type
2657 requires. This is done for all incoming packets. */
2659 void silc_server_packet_parse_type(SilcServer server,
2660 SilcSocketConnection sock,
2661 SilcPacketContext *packet)
2663 SilcPacketType type = packet->type;
2664 SilcIDListData idata = (SilcIDListData)sock->user_data;
2666 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
2667 silc_get_packet_name(type), packet->flags));
2669 /* Parse the packet type */
2671 case SILC_PACKET_DISCONNECT:
2674 char *message = NULL;
2676 if (packet->flags & SILC_PACKET_FLAG_LIST)
2678 if (packet->buffer->len < 1)
2681 status = (SilcStatus)packet->buffer->data[0];
2682 if (packet->buffer->len > 1 &&
2683 silc_utf8_valid(packet->buffer->data + 1, packet->buffer->len - 1))
2684 message = silc_memdup(packet->buffer->data + 1,
2685 packet->buffer->len - 1);
2687 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s",
2688 sock->ip, sock->hostname,
2689 silc_get_status_message(status), status,
2690 message ? message : ""));
2693 /* Do not switch to backup in case of error */
2694 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
2696 /* If backup disconnected then mark that resuming will not be allowed */
2697 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2698 sock->type == SILC_SOCKET_TYPE_SERVER && sock->user_data) {
2699 SilcServerEntry server_entry = sock->user_data;
2700 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2701 server->backup_closed = TRUE;
2704 /* Handle the disconnection from our end too */
2705 if (sock->user_data && SILC_IS_LOCAL(sock->user_data))
2706 silc_server_free_sock_user_data(server, sock, NULL);
2707 SILC_SET_DISCONNECTING(sock);
2708 silc_server_close_connection(server, sock);
2709 server->backup_noswitch = FALSE;
2713 case SILC_PACKET_SUCCESS:
2715 * Success received for something. For now we can have only
2716 * one protocol for connection executing at once hence this
2717 * success message is for whatever protocol is executing currently.
2719 if (packet->flags & SILC_PACKET_FLAG_LIST)
2722 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2725 case SILC_PACKET_FAILURE:
2727 * Failure received for something. For now we can have only
2728 * one protocol for connection executing at once hence this
2729 * failure message is for whatever protocol is executing currently.
2731 if (packet->flags & SILC_PACKET_FLAG_LIST)
2734 /* Check for failure START_USE from backup router */
2735 if (server->server_type == SILC_SERVER &&
2736 server->backup_primary && packet->buffer->len == 4) {
2738 SILC_GET32_MSB(type, packet->buffer->data);
2739 if (type == SILC_SERVER_BACKUP_START_USE) {
2740 /* Attempt to reconnect to primary */
2741 SILC_LOG_DEBUG(("Received failed START_USE from backup %s", sock->ip));
2743 /* Default action is to disconnect from backup and reconnect to
2744 primary. Since this failure can happen during switching to
2745 backup (backup might have not noticed the primary going down yet),
2746 we will wait a while and keep sending START_USE to backup.
2747 Only after that we'll give up. */
2748 if (server->router == sock->user_data &&
2749 (time(0) - server->router_connect) < 30) {
2750 SILC_LOG_DEBUG(("Resending START_USE to backup router"));
2751 silc_server_backup_send_start_use(server, sock, FALSE);
2755 /* If backup is our primary, disconnect now. */
2756 if (server->router == sock->user_data) {
2757 if (sock->user_data)
2758 silc_server_free_sock_user_data(server, sock, NULL);
2759 SILC_SET_DISCONNECTING(sock);
2760 silc_server_close_connection(server, sock);
2764 silc_server_create_connections(server);
2768 /* Execute protocol */
2769 if (sock->protocol) {
2770 sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
2771 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2776 case SILC_PACKET_REJECT:
2777 if (packet->flags & SILC_PACKET_FLAG_LIST)
2782 case SILC_PACKET_NOTIFY:
2784 * Received notify packet. Server can receive notify packets from
2785 * router. Server then relays the notify messages to clients if needed.
2787 if (packet->flags & SILC_PACKET_FLAG_LIST)
2788 silc_server_notify_list(server, sock, packet);
2790 silc_server_notify(server, sock, packet);
2796 case SILC_PACKET_CHANNEL_MESSAGE:
2798 * Received channel message. Channel messages are special packets
2799 * (although probably most common ones) thus they are handled
2802 if (packet->flags & SILC_PACKET_FLAG_LIST)
2804 idata->last_receive = time(NULL);
2805 silc_server_channel_message(server, sock, packet);
2808 case SILC_PACKET_CHANNEL_KEY:
2810 * Received key for channel. As channels are created by the router
2811 * the keys are as well. We will distribute the key to all of our
2812 * locally connected clients on the particular channel. Router
2813 * never receives this channel and thus is ignored.
2815 if (packet->flags & SILC_PACKET_FLAG_LIST)
2817 silc_server_channel_key(server, sock, packet);
2823 case SILC_PACKET_COMMAND:
2825 * Recived command. Processes the command request and allocates the
2826 * command context and calls the command.
2828 if (packet->flags & SILC_PACKET_FLAG_LIST)
2830 silc_server_command_process(server, sock, packet);
2833 case SILC_PACKET_COMMAND_REPLY:
2835 * Received command reply packet. Received command reply to command. It
2836 * may be reply to command sent by us or reply to command sent by client
2837 * that we've routed further.
2839 if (packet->flags & SILC_PACKET_FLAG_LIST)
2841 silc_server_command_reply(server, sock, packet);
2845 * Private Message packets
2847 case SILC_PACKET_PRIVATE_MESSAGE:
2849 * Received private message packet. The packet is coming from either
2852 if (packet->flags & SILC_PACKET_FLAG_LIST)
2854 idata->last_receive = time(NULL);
2855 silc_server_private_message(server, sock, packet);
2858 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
2860 * Private message key packet.
2862 if (packet->flags & SILC_PACKET_FLAG_LIST)
2864 silc_server_private_message_key(server, sock, packet);
2868 * Key Exchange protocol packets
2870 case SILC_PACKET_KEY_EXCHANGE:
2871 if (packet->flags & SILC_PACKET_FLAG_LIST)
2874 if (sock->protocol && sock->protocol->protocol &&
2875 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
2876 SilcServerKEInternalContext *proto_ctx =
2877 (SilcServerKEInternalContext *)sock->protocol->context;
2879 proto_ctx->packet = silc_packet_context_dup(packet);
2881 /* Let the protocol handle the packet */
2882 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
2884 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
2885 "protocol active (%s:%d [%s]).", sock->hostname,
2887 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2888 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2889 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2894 case SILC_PACKET_KEY_EXCHANGE_1:
2895 if (packet->flags & SILC_PACKET_FLAG_LIST)
2898 if (sock->protocol && sock->protocol->protocol &&
2899 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2900 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2902 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2903 SilcServerRekeyInternalContext *proto_ctx =
2904 (SilcServerRekeyInternalContext *)sock->protocol->context;
2906 if (proto_ctx->packet)
2907 silc_packet_context_free(proto_ctx->packet);
2909 proto_ctx->packet = silc_packet_context_dup(packet);
2911 /* Let the protocol handle the packet */
2912 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2914 SilcServerKEInternalContext *proto_ctx =
2915 (SilcServerKEInternalContext *)sock->protocol->context;
2917 if (proto_ctx->packet)
2918 silc_packet_context_free(proto_ctx->packet);
2920 proto_ctx->packet = silc_packet_context_dup(packet);
2921 proto_ctx->dest_id_type = packet->src_id_type;
2922 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2923 packet->src_id_type);
2924 if (!proto_ctx->dest_id)
2927 /* Let the protocol handle the packet */
2928 silc_protocol_execute(sock->protocol, server->schedule,
2932 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
2933 "protocol active (%s:%d [%s]).", sock->hostname,
2935 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2936 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2937 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2942 case SILC_PACKET_KEY_EXCHANGE_2:
2943 if (packet->flags & SILC_PACKET_FLAG_LIST)
2946 if (sock->protocol && sock->protocol->protocol &&
2947 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2948 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2950 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2951 SilcServerRekeyInternalContext *proto_ctx =
2952 (SilcServerRekeyInternalContext *)sock->protocol->context;
2954 if (proto_ctx->packet)
2955 silc_packet_context_free(proto_ctx->packet);
2957 proto_ctx->packet = silc_packet_context_dup(packet);
2959 /* Let the protocol handle the packet */
2960 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2962 SilcServerKEInternalContext *proto_ctx =
2963 (SilcServerKEInternalContext *)sock->protocol->context;
2965 if (proto_ctx->packet)
2966 silc_packet_context_free(proto_ctx->packet);
2968 proto_ctx->packet = silc_packet_context_dup(packet);
2969 proto_ctx->dest_id_type = packet->src_id_type;
2970 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2971 packet->src_id_type);
2972 if (!proto_ctx->dest_id)
2975 /* Let the protocol handle the packet */
2976 silc_protocol_execute(sock->protocol, server->schedule,
2980 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2981 "protocol active (%s:%d [%s]).", sock->hostname,
2983 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2984 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2985 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2990 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2992 * Connection authentication request packet. When we receive this packet
2993 * we will send to the other end information about our mandatory
2994 * authentication method for the connection. This packet maybe received
2997 if (packet->flags & SILC_PACKET_FLAG_LIST)
2999 silc_server_connection_auth_request(server, sock, packet);
3003 * Connection Authentication protocol packets
3005 case SILC_PACKET_CONNECTION_AUTH:
3006 /* Start of the authentication protocol. We receive here the
3007 authentication data and will verify it. */
3008 if (packet->flags & SILC_PACKET_FLAG_LIST)
3011 if (sock->protocol && sock->protocol->protocol->type
3012 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
3014 SilcServerConnAuthInternalContext *proto_ctx =
3015 (SilcServerConnAuthInternalContext *)sock->protocol->context;
3017 proto_ctx->packet = silc_packet_context_dup(packet);
3019 /* Let the protocol handle the packet */
3020 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
3022 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
3023 "protocol active (%s:%d [%s]).", sock->hostname,
3025 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3026 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3027 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3032 case SILC_PACKET_NEW_ID:
3034 * Received New ID packet. This includes some new ID that has been
3035 * created. It may be for client, server or channel. This is the way
3036 * to distribute information about new registered entities in the
3039 if (packet->flags & SILC_PACKET_FLAG_LIST)
3040 silc_server_new_id_list(server, sock, packet);
3042 silc_server_new_id(server, sock, packet);
3045 case SILC_PACKET_NEW_CLIENT:
3047 * Received new client packet. This includes client information that
3048 * we will use to create initial client ID. After creating new
3049 * ID we will send it to the client.
3051 if (packet->flags & SILC_PACKET_FLAG_LIST)
3053 silc_server_new_client(server, sock, packet);
3056 case SILC_PACKET_NEW_SERVER:
3058 * Received new server packet. This includes Server ID and some other
3059 * information that we may save. This is received after server has
3062 if (packet->flags & SILC_PACKET_FLAG_LIST)
3064 silc_server_new_server(server, sock, packet);
3067 case SILC_PACKET_NEW_CHANNEL:
3069 * Received new channel packet. Information about new channel in the
3070 * network are distributed using this packet.
3072 if (packet->flags & SILC_PACKET_FLAG_LIST)
3073 silc_server_new_channel_list(server, sock, packet);
3075 silc_server_new_channel(server, sock, packet);
3078 case SILC_PACKET_HEARTBEAT:
3080 * Received heartbeat.
3082 if (packet->flags & SILC_PACKET_FLAG_LIST)
3086 case SILC_PACKET_KEY_AGREEMENT:
3088 * Received heartbeat.
3090 if (packet->flags & SILC_PACKET_FLAG_LIST)
3092 silc_server_key_agreement(server, sock, packet);
3095 case SILC_PACKET_REKEY:
3097 * Received re-key packet. The sender wants to regenerate the session
3100 if (packet->flags & SILC_PACKET_FLAG_LIST)
3102 silc_server_rekey(server, sock, packet);
3105 case SILC_PACKET_REKEY_DONE:
3107 * The re-key is done.
3109 if (packet->flags & SILC_PACKET_FLAG_LIST)
3112 if (sock->protocol && sock->protocol->protocol &&
3113 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
3115 SilcServerRekeyInternalContext *proto_ctx =
3116 (SilcServerRekeyInternalContext *)sock->protocol->context;
3118 if (proto_ctx->packet)
3119 silc_packet_context_free(proto_ctx->packet);
3121 proto_ctx->packet = silc_packet_context_dup(packet);
3123 /* Let the protocol handle the packet */
3124 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
3126 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
3127 "protocol active (%s:%d [%s]).", sock->hostname,
3129 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3130 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3131 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3136 case SILC_PACKET_FTP:
3138 if (packet->flags & SILC_PACKET_FLAG_LIST)
3140 silc_server_ftp(server, sock, packet);
3143 case SILC_PACKET_RESUME_CLIENT:
3145 if (packet->flags & SILC_PACKET_FLAG_LIST)
3147 silc_server_resume_client(server, sock, packet);
3150 case SILC_PACKET_RESUME_ROUTER:
3151 /* Resume router packet received. This packet is received for backup
3152 router resuming protocol. */
3153 if (packet->flags & SILC_PACKET_FLAG_LIST)
3155 silc_server_backup_resume_router(server, sock, packet);
3159 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
3164 /* Creates connection to a remote router. */
3166 void silc_server_create_connection(SilcServer server,
3167 const char *remote_host, SilcUInt32 port)
3169 SilcServerConnection sconn;
3171 /* Allocate connection object for hold connection specific stuff. */
3172 sconn = silc_calloc(1, sizeof(*sconn));
3173 sconn->remote_host = strdup(remote_host);
3174 sconn->remote_port = port;
3175 sconn->no_reconnect = TRUE;
3177 silc_schedule_task_add(server->schedule, 0,
3178 silc_server_connect_router,
3179 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
3180 SILC_TASK_PRI_NORMAL);
3183 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3185 SilcServer server = app_context;
3186 SilcSocketConnection sock = context;
3188 SILC_LOG_DEBUG(("Deleting socket %p", sock));
3190 /* Close the actual connection */
3191 silc_net_close_connection(sock->sock);
3192 server->sockets[sock->sock] = NULL;
3194 /* We won't listen for this connection anymore */
3195 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
3196 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
3198 silc_socket_free(sock);
3201 /* Closes connection to socket connection */
3203 void silc_server_close_connection(SilcServer server,
3204 SilcSocketConnection sock)
3208 if (SILC_IS_DISCONNECTED(sock)) {
3209 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
3210 silc_schedule_task_add(server->schedule, sock->sock,
3211 silc_server_close_connection_final,
3212 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
3213 SILC_TASK_PRI_NORMAL);
3214 server->sockets[sock->sock] = NULL;
3218 /* If any protocol is active cancel its execution. It will call
3219 the final callback which will finalize the disconnection. */
3220 if (sock->protocol && sock->protocol->protocol &&
3221 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3222 SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
3223 silc_protocol_cancel(sock->protocol, server->schedule);
3224 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3225 silc_protocol_execute_final(sock->protocol, server->schedule);
3226 sock->protocol = NULL;
3230 memset(tmp, 0, sizeof(tmp));
3231 silc_socket_get_error(sock, tmp, sizeof(tmp));
3232 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", sock->hostname,
3234 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3235 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3236 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3237 "Router"), tmp[0] ? tmp : ""));
3239 SILC_SET_DISCONNECTED(sock);
3240 silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3241 silc_schedule_task_add(server->schedule, sock->sock,
3242 silc_server_close_connection_final,
3243 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
3244 SILC_TASK_PRI_NORMAL);
3245 server->sockets[sock->sock] = NULL;
3248 /* Sends disconnect message to remote connection and disconnects the
3249 connection. NOTE: If this is called from protocol callback
3250 then sock->protocol must be set NULL before calling this, since
3251 this routine dispatches protocol callbacks too. */
3253 void silc_server_disconnect_remote(SilcServer server,
3254 SilcSocketConnection sock,
3255 SilcStatus status, ...)
3258 unsigned char buf[512];
3266 if (SILC_IS_DISCONNECTING(sock)) {
3267 SILC_SET_DISCONNECTED(sock);
3268 silc_server_close_connection(server, sock);
3272 memset(buf, 0, sizeof(buf));
3273 va_start(ap, status);
3274 cp = va_arg(ap, char *);
3276 vsnprintf(buf, sizeof(buf) - 1, cp, ap);
3281 SILC_LOG_DEBUG(("Disconnecting remote host"));
3283 /* Notify remote end that the conversation is over. The notify message
3284 is tried to be sent immediately. */
3288 len += silc_utf8_encoded_len(buf, strlen(buf), SILC_STRING_ASCII);
3290 buffer = silc_buffer_alloc_size(len);
3294 buffer->data[0] = status;
3296 silc_utf8_encode(buf, strlen(buf), SILC_STRING_ASCII, buffer->data + 1,
3298 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
3299 buffer->data, buffer->len, TRUE);
3300 silc_buffer_free(buffer);
3303 silc_server_packet_queue_purge(server, sock);
3305 /* Mark the connection to be disconnected */
3306 SILC_SET_DISCONNECTING(sock);
3307 silc_server_close_connection(server, sock);
3310 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
3312 SilcServer server = app_context;
3313 SilcClientEntry client = context;
3315 assert(!silc_hash_table_count(client->channels));
3317 silc_idlist_del_data(client);
3318 silc_idcache_purge_by_context(server->local_list->clients, client);
3321 /* Frees client data and notifies about client's signoff. */
3323 void silc_server_free_client_data(SilcServer server,
3324 SilcSocketConnection sock,
3325 SilcClientEntry client,
3327 const char *signoff)
3329 SILC_LOG_DEBUG(("Freeing client data"));
3331 /* If there is pending outgoing data for the client then purge it
3332 to the network before removing the client entry. */
3333 silc_server_packet_queue_purge(server, sock);
3336 /* Check if anyone is watching this nickname */
3337 if (server->server_type == SILC_ROUTER)
3338 silc_server_check_watcher_list(server, client, NULL,
3339 SILC_NOTIFY_TYPE_SIGNOFF);
3341 /* Send SIGNOFF notify to routers. */
3343 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3344 SILC_BROADCAST(server), client->id,
3348 /* Remove client from all channels */
3350 silc_server_remove_from_channels(server, NULL, client,
3351 TRUE, (char *)signoff, TRUE, FALSE);
3353 silc_server_remove_from_channels(server, NULL, client,
3354 FALSE, NULL, FALSE, FALSE);
3356 /* Remove this client from watcher list if it is */
3357 silc_server_del_from_watcher_list(server, client);
3359 /* Remove this client from the public key hash list */
3360 if (client->data.public_key)
3361 silc_hash_table_del_by_context(server->pk_hash,
3362 client->data.public_key, client);
3364 /* Update statistics */
3365 server->stat.my_clients--;
3366 server->stat.clients--;
3367 if (server->stat.cell_clients)
3368 server->stat.cell_clients--;
3369 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3370 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3371 silc_schedule_task_del_by_context(server->schedule, client);
3373 /* We will not delete the client entry right away. We will take it
3374 into history (for WHOWAS command) for 5 minutes, unless we're
3375 shutting down server. */
3376 if (!server->server_shutdown) {
3377 silc_schedule_task_add(server->schedule, 0,
3378 silc_server_free_client_data_timeout,
3380 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
3381 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3382 client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3384 client->router = NULL;
3385 client->connection = NULL;
3387 /* Delete directly since we're shutting down server */
3388 silc_idlist_del_data(client);
3389 silc_idlist_del_client(server->local_list, client);
3393 /* Frees user_data pointer from socket connection object. This also sends
3394 appropriate notify packets to the network to inform about leaving
3397 void silc_server_free_sock_user_data(SilcServer server,
3398 SilcSocketConnection sock,
3399 const char *signoff_message)
3402 /* If any protocol is active cancel its execution */
3403 if (sock->protocol && sock->protocol->protocol &&
3404 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3405 SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
3406 silc_protocol_cancel(sock->protocol, server->schedule);
3407 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3408 silc_protocol_execute_final(sock->protocol, server->schedule);
3409 sock->protocol = NULL;
3412 switch (sock->type) {
3413 case SILC_SOCKET_TYPE_CLIENT:
3415 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
3416 silc_server_free_client_data(server, sock, user_data, TRUE,
3420 case SILC_SOCKET_TYPE_SERVER:
3421 case SILC_SOCKET_TYPE_ROUTER:
3423 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
3424 SilcServerEntry backup_router = NULL;
3426 SILC_LOG_DEBUG(("Freeing server data"));
3429 backup_router = silc_server_backup_get(server, user_data->id);
3431 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3432 backup_router == server->id_entry &&
3433 sock->type != SILC_SOCKET_TYPE_ROUTER)
3434 backup_router = NULL;
3436 if (server->server_shutdown || server->backup_noswitch)
3437 backup_router = NULL;
3439 /* If this was our primary router connection then we're lost to
3440 the outside world. */
3441 if (server->router == user_data) {
3442 /* Check whether we have a backup router connection */
3443 if (!backup_router || backup_router == user_data) {
3444 if (!server->no_reconnect)
3445 silc_server_create_connections(server);
3446 server->id_entry->router = NULL;
3447 server->router = NULL;
3448 server->standalone = TRUE;
3449 server->backup_primary = FALSE;
3450 backup_router = NULL;
3452 if (server->id_entry != backup_router) {
3453 SILC_LOG_INFO(("New primary router is backup router %s",
3454 backup_router->server_name));
3455 server->id_entry->router = backup_router;
3456 server->router = backup_router;
3457 server->router_connect = time(0);
3458 server->backup_primary = TRUE;
3459 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3461 /* Send START_USE to backup router to indicate we have switched */
3462 silc_server_backup_send_start_use(server,
3463 backup_router->connection,
3466 SILC_LOG_INFO(("We are now new primary router in this cell"));
3467 server->id_entry->router = NULL;
3468 server->router = NULL;
3469 server->standalone = TRUE;
3472 /* We stop here to take a breath */
3475 if (server->backup_router) {
3476 server->server_type = SILC_ROUTER;
3478 /* We'll need to constantly try to reconnect to the primary
3479 router so that we'll see when it comes back online. */
3480 silc_server_backup_reconnect(server, sock->ip, sock->port,
3481 silc_server_backup_connected,
3485 /* Mark this connection as replaced */
3486 silc_server_backup_replaced_add(server, user_data->id,
3489 } else if (backup_router) {
3490 SILC_LOG_INFO(("Enabling the use of backup router %s",
3491 backup_router->server_name));
3493 /* Mark this connection as replaced */
3494 silc_server_backup_replaced_add(server, user_data->id,
3496 } else if (server->server_type == SILC_SERVER &&
3497 sock->type == SILC_SOCKET_TYPE_ROUTER) {
3498 /* Reconnect to the router (backup) */
3499 if (!server->no_reconnect)
3500 silc_server_create_connections(server);
3503 if (user_data->server_name)
3504 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3505 ("Server %s signoff", user_data->server_name));
3507 if (!backup_router) {
3508 /* Remove all servers that are originated from this server, and
3509 remove the clients of those servers too. */
3510 silc_server_remove_servers_by_server(server, user_data, TRUE);
3513 /* Remove the clients that this server owns as they will become
3514 invalid now too. For backup router the server is actually
3515 coming from the primary router, so mark that as the owner
3517 if (server->server_type == SILC_BACKUP_ROUTER &&
3518 sock->type == SILC_SOCKET_TYPE_SERVER)
3519 silc_server_remove_clients_by_server(server, server->router,
3523 silc_server_remove_clients_by_server(server, user_data,
3526 /* Remove channels owned by this server */
3527 if (server->server_type == SILC_SERVER)
3528 silc_server_remove_channels_by_server(server, user_data);
3530 /* Enable local server connections that may be disabled */
3531 silc_server_local_servers_toggle_enabled(server, TRUE);
3533 /* Update the client entries of this server to the new backup
3534 router. If we are the backup router we also resolve the real
3535 servers for the clients. After updating is over this also
3536 removes the clients that this server explicitly owns. */
3537 silc_server_update_clients_by_server(server, user_data,
3538 backup_router, TRUE);
3540 /* If we are router and just lost our primary router (now standlaone)
3541 we remove everything that was behind it, since we don't know
3543 if (server->server_type == SILC_ROUTER && server->standalone)
3544 /* Remove all servers that are originated from this server, and
3545 remove the clients of those servers too. */
3546 silc_server_remove_servers_by_server(server, user_data, TRUE);
3548 /* Finally remove the clients that are explicitly owned by this
3549 server. They go down with the server. */
3550 silc_server_remove_clients_by_server(server, user_data,
3553 /* Update our server cache to use the new backup router too. */
3554 silc_server_update_servers_by_server(server, user_data, backup_router);
3555 if (server->server_type == SILC_SERVER)
3556 silc_server_update_channels_by_server(server, user_data,
3559 /* Send notify about primary router going down to local operators */
3560 if (server->backup_router)
3561 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3562 SILC_NOTIFY_TYPE_NONE,
3563 ("%s switched to backup router %s "
3564 "(we are primary router now)",
3565 server->server_name, server->server_name));
3566 else if (server->router)
3567 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3568 SILC_NOTIFY_TYPE_NONE,
3569 ("%s switched to backup router %s",
3570 server->server_name,
3571 server->router->server_name));
3573 server->backup_noswitch = FALSE;
3575 /* Free the server entry */
3576 silc_server_backup_del(server, user_data);
3577 silc_server_backup_replaced_del(server, user_data);
3578 silc_idlist_del_data(user_data);
3579 if (!silc_idlist_del_server(server->local_list, user_data))
3580 silc_idlist_del_server(server->global_list, user_data);
3581 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
3582 server->stat.my_servers--;
3584 server->stat.my_routers--;
3585 server->stat.routers--;
3587 server->stat.servers--;
3588 if (server->server_type == SILC_ROUTER)
3589 server->stat.cell_servers--;
3591 if (backup_router && backup_router != server->id_entry) {
3592 /* Announce all of our stuff that was created about 5 minutes ago.
3593 The backup router knows all the other stuff already. */
3594 if (server->server_type == SILC_ROUTER)
3595 silc_server_announce_servers(server, FALSE, time(0) - 300,
3596 backup_router->connection);
3598 /* Announce our clients and channels to the router */
3599 silc_server_announce_clients(server, time(0) - 300,
3600 backup_router->connection);
3601 silc_server_announce_channels(server, time(0) - 300,
3602 backup_router->connection);
3608 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
3610 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3612 silc_idlist_del_data(user_data);
3613 silc_free(user_data);
3618 sock->user_data = NULL;
3621 /* Removes client from all channels it has joined. This is used when client
3622 connection is disconnected. If the client on a channel is last, the
3623 channel is removed as well. This sends the SIGNOFF notify types. */
3625 void silc_server_remove_from_channels(SilcServer server,
3626 SilcSocketConnection sock,
3627 SilcClientEntry client,
3629 const char *signoff_message,
3633 SilcChannelEntry channel;
3634 SilcChannelClientEntry chl;
3635 SilcHashTableList htl;
3636 SilcBuffer clidp = NULL;
3641 if (notify && !client->id)
3644 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3645 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3648 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3653 /* Remove the client from all channels. The client is removed from
3654 the channels' user list. */
3655 silc_hash_table_list(client->channels, &htl);
3656 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3657 channel = chl->channel;
3659 /* Remove channel if this is last client leaving the channel, unless
3660 the channel is permanent. */
3661 if (server->server_type != SILC_SERVER &&
3662 silc_hash_table_count(channel->user_list) < 2) {
3663 silc_server_channel_delete(server, channel);
3667 silc_hash_table_del(client->channels, channel);
3668 silc_hash_table_del(channel->user_list, client);
3669 channel->user_count--;
3671 /* If there is no global users on the channel anymore mark the channel
3672 as local channel. Do not check if the removed client is local client. */
3673 if (server->server_type == SILC_SERVER && channel->global_users &&
3674 chl->client->router && !silc_server_channel_has_global(channel))
3675 channel->global_users = FALSE;
3677 memset(chl, 'A', sizeof(*chl));
3680 /* Update statistics */
3681 if (SILC_IS_LOCAL(client))
3682 server->stat.my_chanclients--;
3683 if (server->server_type == SILC_ROUTER) {
3684 server->stat.cell_chanclients--;
3685 server->stat.chanclients--;
3688 /* If there is not at least one local user on the channel then we don't
3689 need the channel entry anymore, we can remove it safely, unless the
3690 channel is permanent channel */
3691 if (server->server_type == SILC_SERVER &&
3692 !silc_server_channel_has_local(channel)) {
3693 /* Notify about leaving client if this channel has global users. */
3694 if (notify && channel->global_users)
3695 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3696 SILC_NOTIFY_TYPE_SIGNOFF,
3697 signoff_message ? 2 : 1,
3698 clidp->data, clidp->len,
3699 signoff_message, signoff_message ?
3700 strlen(signoff_message) : 0);
3702 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3703 silc_server_channel_delete(server, channel);
3707 /* Send notify to channel about client leaving SILC and channel too */
3709 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3710 SILC_NOTIFY_TYPE_SIGNOFF,
3711 signoff_message ? 2 : 1,
3712 clidp->data, clidp->len,
3713 signoff_message, signoff_message ?
3714 strlen(signoff_message) : 0);
3716 if (killed && clidp) {
3717 /* Remove the client from channel's invite list */
3718 if (channel->invite_list &&
3719 silc_hash_table_count(channel->invite_list)) {
3721 SilcArgumentPayload iargs;
3722 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3724 iargs = silc_argument_payload_parse(ab->data, ab->len, 1);
3725 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3726 silc_buffer_free(ab);
3727 silc_argument_payload_free(iargs);
3731 /* Don't create keys if we are shutting down */
3732 if (server->server_shutdown)
3735 /* Re-generate channel key if needed */
3736 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3737 if (!silc_server_create_channel_key(server, channel, 0))
3740 /* Send the channel key to the channel. The key of course is not sent
3741 to the client who was removed from the channel. */
3742 silc_server_send_channel_key(server, client->connection, channel,
3743 server->server_type == SILC_ROUTER ?
3744 FALSE : !server->standalone);
3748 silc_hash_table_list_reset(&htl);
3750 silc_buffer_free(clidp);
3753 /* Removes client from one channel. This is used for example when client
3754 calls LEAVE command to remove itself from the channel. Returns TRUE
3755 if channel still exists and FALSE if the channel is removed when
3756 last client leaves the channel. If `notify' is FALSE notify messages
3759 bool silc_server_remove_from_one_channel(SilcServer server,
3760 SilcSocketConnection sock,
3761 SilcChannelEntry channel,
3762 SilcClientEntry client,
3765 SilcChannelClientEntry chl;
3768 SILC_LOG_DEBUG(("Removing %s from channel %s",
3769 silc_id_render(client->id, SILC_ID_CLIENT),
3770 channel->channel_name));
3772 /* Get the entry to the channel, if this client is not on the channel
3774 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3777 /* Remove channel if this is last client leaving the channel, unless
3778 the channel is permanent. */
3779 if (server->server_type != SILC_SERVER &&
3780 silc_hash_table_count(channel->user_list) < 2) {
3781 silc_server_channel_delete(server, channel);
3785 silc_hash_table_del(client->channels, channel);
3786 silc_hash_table_del(channel->user_list, client);
3787 channel->user_count--;
3789 /* If there is no global users on the channel anymore mark the channel
3790 as local channel. Do not check if the client is local client. */
3791 if (server->server_type == SILC_SERVER && channel->global_users &&
3792 chl->client->router && !silc_server_channel_has_global(channel))
3793 channel->global_users = FALSE;
3795 memset(chl, 'O', sizeof(*chl));
3798 /* Update statistics */
3799 if (SILC_IS_LOCAL(client))
3800 server->stat.my_chanclients--;
3801 if (server->server_type == SILC_ROUTER) {
3802 server->stat.cell_chanclients--;
3803 server->stat.chanclients--;
3806 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3810 /* If there is not at least one local user on the channel then we don't
3811 need the channel entry anymore, we can remove it safely, unless the
3812 channel is permanent channel */
3813 if (server->server_type == SILC_SERVER &&
3814 !silc_server_channel_has_local(channel)) {
3815 /* Notify about leaving client if this channel has global users. */
3816 if (notify && channel->global_users)
3817 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3818 SILC_NOTIFY_TYPE_LEAVE, 1,
3819 clidp->data, clidp->len);
3821 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3822 silc_server_channel_delete(server, channel);
3823 silc_buffer_free(clidp);
3827 /* Send notify to channel about client leaving the channel */
3829 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3830 SILC_NOTIFY_TYPE_LEAVE, 1,
3831 clidp->data, clidp->len);
3833 silc_buffer_free(clidp);
3837 /* Timeout callback. This is called if connection is idle or for some
3838 other reason is not responding within some period of time. This
3839 disconnects the remote end. */
3841 SILC_TASK_CALLBACK(silc_server_timeout_remote)
3843 SilcServer server = (SilcServer)context;
3844 SilcSocketConnection sock = server->sockets[fd];
3845 SilcProtocolType protocol = 0;
3847 SILC_LOG_DEBUG(("Start"));
3852 SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
3853 sock->hostname, sock->ip));
3855 /* If we have protocol active we must assure that we call the protocol's
3856 final callback so that all the memory is freed. */
3857 if (sock->protocol && sock->protocol->protocol &&
3858 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3859 protocol = sock->protocol->protocol->type;
3860 silc_protocol_cancel(sock->protocol, server->schedule);
3861 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3862 silc_protocol_execute_final(sock->protocol, server->schedule);
3863 sock->protocol = NULL;
3867 silc_server_disconnect_remote(server, sock,
3869 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3870 SILC_STATUS_ERR_AUTH_FAILED :
3871 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3872 "Connection timeout");
3874 if (sock->user_data)
3875 silc_server_free_sock_user_data(server, sock, NULL);
3878 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3879 function may be used only by router. In real SILC network all channels
3880 are created by routers thus this function is never used by normal
3883 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3884 SilcServerID *router_id,
3890 SilcChannelID *channel_id;
3891 SilcChannelEntry entry;
3895 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3898 cipher = SILC_DEFAULT_CIPHER;
3900 hmac = SILC_DEFAULT_HMAC;
3902 /* Allocate cipher */
3903 if (!silc_cipher_alloc(cipher, &key))
3907 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3908 silc_cipher_free(key);
3912 channel_name = strdup(channel_name);
3914 /* Create the channel ID */
3915 if (!silc_id_create_channel_id(server, router_id, server->rng,
3917 silc_free(channel_name);
3918 silc_cipher_free(key);
3919 silc_hmac_free(newhmac);
3923 /* Create the channel */
3924 entry = silc_idlist_add_channel(server->local_list, channel_name,
3925 SILC_CHANNEL_MODE_NONE, channel_id,
3926 NULL, key, newhmac, 0);
3928 silc_free(channel_name);
3929 silc_cipher_free(key);
3930 silc_hmac_free(newhmac);
3931 silc_free(channel_id);
3935 entry->cipher = strdup(cipher);
3936 entry->hmac_name = strdup(hmac);
3938 /* Now create the actual key material */
3939 if (!silc_server_create_channel_key(server, entry,
3940 silc_cipher_get_key_len(key) / 8)) {
3941 silc_idlist_del_channel(server->local_list, entry);
3945 /* Notify other routers about the new channel. We send the packet
3946 to our primary route. */
3948 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3949 channel_name, entry->id,
3950 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3953 /* Distribute to backup routers */
3954 if (broadcast && server->server_type == SILC_ROUTER) {
3957 SilcUInt32 name_len = strlen(channel_name);
3958 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
3959 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
3961 packet = silc_channel_payload_encode(channel_name, name_len,
3962 cid, channel_id_len, entry->mode);
3963 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3964 packet->data, packet->len, FALSE, TRUE);
3966 silc_buffer_free(packet);
3969 server->stat.my_channels++;
3970 if (server->server_type == SILC_ROUTER) {
3971 server->stat.channels++;
3972 server->stat.cell_channels++;
3973 entry->users_resolved = TRUE;
3979 /* Same as above but creates the channel with Channel ID `channel_id. */
3982 silc_server_create_new_channel_with_id(SilcServer server,
3986 SilcChannelID *channel_id,
3989 SilcChannelEntry entry;
3993 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3996 cipher = SILC_DEFAULT_CIPHER;
3998 hmac = SILC_DEFAULT_HMAC;
4000 /* Allocate cipher */
4001 if (!silc_cipher_alloc(cipher, &key))
4005 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
4006 silc_cipher_free(key);
4010 channel_name = strdup(channel_name);
4012 /* Create the channel */
4013 entry = silc_idlist_add_channel(server->local_list, channel_name,
4014 SILC_CHANNEL_MODE_NONE, channel_id,
4015 NULL, key, newhmac, 0);
4017 silc_cipher_free(key);
4018 silc_hmac_free(newhmac);
4019 silc_free(channel_name);
4023 /* Now create the actual key material */
4024 if (!silc_server_create_channel_key(server, entry,
4025 silc_cipher_get_key_len(key) / 8)) {
4026 silc_idlist_del_channel(server->local_list, entry);
4030 /* Notify other routers about the new channel. We send the packet
4031 to our primary route. */
4033 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
4034 channel_name, entry->id,
4035 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
4038 /* Distribute to backup routers */
4039 if (broadcast && server->server_type == SILC_ROUTER) {
4042 SilcUInt32 name_len = strlen(channel_name);
4043 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
4044 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
4046 packet = silc_channel_payload_encode(channel_name, name_len,
4047 cid, channel_id_len, entry->mode);
4048 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
4049 packet->data, packet->len, FALSE, TRUE);
4051 silc_buffer_free(packet);
4054 server->stat.my_channels++;
4055 if (server->server_type == SILC_ROUTER) {
4056 server->stat.channels++;
4057 server->stat.cell_channels++;
4058 entry->users_resolved = TRUE;
4064 /* Channel's key re-key timeout callback. */
4066 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
4068 SilcServer server = app_context;
4069 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
4073 /* Return now if we are shutting down */
4074 if (server->server_shutdown)
4077 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
4080 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
4083 /* Generates new channel key. This is used to create the initial channel key
4084 but also to re-generate new key for channel. If `key_len' is provided
4085 it is the bytes of the key length. */
4087 bool silc_server_create_channel_key(SilcServer server,
4088 SilcChannelEntry channel,
4092 unsigned char channel_key[32], hash[32];
4095 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
4096 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
4100 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
4102 if (!channel->channel_key)
4103 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
4104 channel->channel_key = NULL;
4110 else if (channel->key_len)
4111 len = channel->key_len / 8;
4113 len = silc_cipher_get_key_len(channel->channel_key) / 8;
4115 /* Create channel key */
4116 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
4119 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
4121 /* Remove old key if exists */
4123 memset(channel->key, 0, channel->key_len / 8);
4124 silc_free(channel->key);
4128 channel->key_len = len * 8;
4129 channel->key = silc_memdup(channel_key, len);
4130 memset(channel_key, 0, sizeof(channel_key));
4132 /* Generate HMAC key from the channel key data and set it */
4134 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4135 memset(channel->key, 0, channel->key_len / 8);
4136 silc_free(channel->key);
4137 channel->channel_key = NULL;
4140 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
4141 silc_hmac_set_key(channel->hmac, hash,
4142 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4143 memset(hash, 0, sizeof(hash));
4145 if (server->server_type == SILC_ROUTER) {
4146 if (!channel->rekey)
4147 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4148 channel->rekey->channel = channel;
4149 channel->rekey->key_len = key_len;
4150 if (channel->rekey->task)
4151 silc_schedule_task_del(server->schedule, channel->rekey->task);
4153 channel->rekey->task =
4154 silc_schedule_task_add(server->schedule, 0,
4155 silc_server_channel_key_rekey,
4156 (void *)channel->rekey,
4157 server->config->channel_rekey_secs, 0,
4159 SILC_TASK_PRI_NORMAL);
4165 /* Saves the channel key found in the encoded `key_payload' buffer. This
4166 function is used when we receive Channel Key Payload and also when we're
4167 processing JOIN command reply. Returns entry to the channel. */
4169 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4170 SilcBuffer key_payload,
4171 SilcChannelEntry channel)
4173 SilcChannelKeyPayload payload = NULL;
4174 SilcChannelID *id = NULL;
4175 unsigned char *tmp, hash[32];
4179 /* Decode channel key payload */
4180 payload = silc_channel_key_payload_parse(key_payload->data,
4183 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4188 /* Get the channel entry */
4191 /* Get channel ID */
4192 tmp = silc_channel_key_get_id(payload, &tmp_len);
4193 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
4199 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4201 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4203 if (server->server_type == SILC_ROUTER)
4204 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4205 silc_id_render(id, SILC_ID_CHANNEL)));
4211 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4213 tmp = silc_channel_key_get_key(payload, &tmp_len);
4219 cipher = silc_channel_key_get_cipher(payload, NULL);
4225 /* Remove old key if exists */
4227 memset(channel->key, 0, channel->key_len / 8);
4228 silc_free(channel->key);
4229 silc_cipher_free(channel->channel_key);
4232 /* Create new cipher */
4233 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
4234 channel->channel_key = NULL;
4239 if (channel->cipher)
4240 silc_free(channel->cipher);
4241 channel->cipher = strdup(cipher);
4244 channel->key_len = tmp_len * 8;
4245 channel->key = silc_memdup(tmp, tmp_len);
4246 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
4248 /* Generate HMAC key from the channel key data and set it */
4250 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4251 memset(channel->key, 0, channel->key_len / 8);
4252 silc_free(channel->key);
4253 channel->channel_key = NULL;
4256 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4257 silc_hmac_set_key(channel->hmac, hash,
4258 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4260 memset(hash, 0, sizeof(hash));
4261 memset(tmp, 0, tmp_len);
4263 if (server->server_type == SILC_ROUTER) {
4264 if (!channel->rekey)
4265 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4266 channel->rekey->channel = channel;
4267 if (channel->rekey->task)
4268 silc_schedule_task_del(server->schedule, channel->rekey->task);
4270 channel->rekey->task =
4271 silc_schedule_task_add(server->schedule, 0,
4272 silc_server_channel_key_rekey,
4273 (void *)channel->rekey,
4274 server->config->channel_rekey_secs, 0,
4276 SILC_TASK_PRI_NORMAL);
4282 silc_channel_key_payload_free(payload);
4287 /* Heartbeat callback. This function is set as argument for the
4288 silc_socket_set_heartbeat function. The library will call this function
4289 at the set time interval. */
4291 void silc_server_perform_heartbeat(SilcSocketConnection sock,
4294 SilcServer server = hb_context;
4296 SILC_LOG_DEBUG(("Sending heartbeat to %s:%d (%s)", sock->hostname,
4297 sock->port, sock->ip));
4299 /* Send the heartbeat */
4300 silc_server_send_heartbeat(server, sock);
4303 /* Returns assembled of all servers in the given ID list. The packet's
4304 form is dictated by the New ID payload. */
4306 static void silc_server_announce_get_servers(SilcServer server,
4307 SilcServerEntry remote,
4309 SilcBuffer *servers,
4310 unsigned long creation_time)
4312 SilcIDCacheList list;
4313 SilcIDCacheEntry id_cache;
4314 SilcServerEntry entry;
4317 /* Go through all clients in the list */
4318 if (silc_idcache_get_all(id_list->servers, &list)) {
4319 if (silc_idcache_list_first(list, &id_cache)) {
4321 entry = (SilcServerEntry)id_cache->context;
4323 /* Do not announce the one we've sending our announcements and
4324 do not announce ourself. Also check the creation time if it's
4326 if ((entry == remote) || (entry == server->id_entry) ||
4327 (creation_time && entry->data.created < creation_time)) {
4328 if (!silc_idcache_list_next(list, &id_cache))
4333 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4335 *servers = silc_buffer_realloc(*servers,
4337 (*servers)->truelen + idp->len :
4339 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4340 silc_buffer_put(*servers, idp->data, idp->len);
4341 silc_buffer_pull(*servers, idp->len);
4342 silc_buffer_free(idp);
4344 if (!silc_idcache_list_next(list, &id_cache))
4349 silc_idcache_list_free(list);
4354 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4360 p = silc_notify_payload_encode(notify, argc, ap);
4366 /* This function is used by router to announce existing servers to our
4367 primary router when we've connected to it. If `creation_time' is non-zero
4368 then only the servers that has been created after the `creation_time'
4369 will be announced. */
4371 void silc_server_announce_servers(SilcServer server, bool global,
4372 unsigned long creation_time,
4373 SilcSocketConnection remote)
4375 SilcBuffer servers = NULL;
4377 SILC_LOG_DEBUG(("Announcing servers"));
4379 /* Get servers in local list */
4380 silc_server_announce_get_servers(server, remote->user_data,
4381 server->local_list, &servers,
4385 /* Get servers in global list */
4386 silc_server_announce_get_servers(server, remote->user_data,
4387 server->global_list, &servers,
4391 silc_buffer_push(servers, servers->data - servers->head);
4392 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
4394 /* Send the packet */
4395 silc_server_packet_send(server, remote,
4396 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4397 servers->data, servers->len, TRUE);
4399 silc_buffer_free(servers);
4403 /* Returns assembled packet of all clients in the given ID list. The
4404 packet's form is dictated by the New ID Payload. */
4406 static void silc_server_announce_get_clients(SilcServer server,
4408 SilcBuffer *clients,
4410 unsigned long creation_time)
4412 SilcIDCacheList list;
4413 SilcIDCacheEntry id_cache;
4414 SilcClientEntry client;
4417 unsigned char mode[4];
4419 /* Go through all clients in the list */
4420 if (silc_idcache_get_all(id_list->clients, &list)) {
4421 if (silc_idcache_list_first(list, &id_cache)) {
4423 client = (SilcClientEntry)id_cache->context;
4425 if (creation_time && client->data.created < creation_time) {
4426 if (!silc_idcache_list_next(list, &id_cache))
4430 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) &&
4431 !client->connection && !client->router && !SILC_IS_LOCAL(client)) {
4432 if (!silc_idcache_list_next(list, &id_cache))
4437 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4439 *clients = silc_buffer_realloc(*clients,
4441 (*clients)->truelen + idp->len :
4443 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4444 silc_buffer_put(*clients, idp->data, idp->len);
4445 silc_buffer_pull(*clients, idp->len);
4447 SILC_PUT32_MSB(client->mode, mode);
4449 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4450 2, idp->data, idp->len,
4452 *umodes = silc_buffer_realloc(*umodes,
4454 (*umodes)->truelen + tmp->len :
4456 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4457 silc_buffer_put(*umodes, tmp->data, tmp->len);
4458 silc_buffer_pull(*umodes, tmp->len);
4459 silc_buffer_free(tmp);
4461 silc_buffer_free(idp);
4463 if (!silc_idcache_list_next(list, &id_cache))
4468 silc_idcache_list_free(list);
4472 /* This function is used to announce our existing clients to our router
4473 when we've connected to it. If `creation_time' is non-zero then only
4474 the clients that has been created after the `creation_time' will be
4477 void silc_server_announce_clients(SilcServer server,
4478 unsigned long creation_time,
4479 SilcSocketConnection remote)
4481 SilcBuffer clients = NULL;
4482 SilcBuffer umodes = NULL;
4484 SILC_LOG_DEBUG(("Announcing clients"));
4486 /* Get clients in local list */
4487 silc_server_announce_get_clients(server, server->local_list,
4488 &clients, &umodes, creation_time);
4490 /* As router we announce our global list as well */
4491 if (server->server_type == SILC_ROUTER)
4492 silc_server_announce_get_clients(server, server->global_list,
4493 &clients, &umodes, creation_time);
4496 silc_buffer_push(clients, clients->data - clients->head);
4497 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
4499 /* Send the packet */
4500 silc_server_packet_send(server, remote,
4501 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4502 clients->data, clients->len, TRUE);
4504 silc_buffer_free(clients);
4508 silc_buffer_push(umodes, umodes->data - umodes->head);
4509 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
4511 /* Send the packet */
4512 silc_server_packet_send(server, remote,
4513 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4514 umodes->data, umodes->len, TRUE);
4516 silc_buffer_free(umodes);
4520 /* Returns channel's topic for announcing it */
4522 void silc_server_announce_get_channel_topic(SilcServer server,
4523 SilcChannelEntry channel,
4528 if (channel->topic) {
4529 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4530 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4531 chidp->data, chidp->len,
4533 strlen(channel->topic));
4534 silc_buffer_free(chidp);
4538 /* Returns channel's invite and ban lists */
4540 void silc_server_announce_get_inviteban(SilcServer server,
4541 SilcChannelEntry channel,
4545 SilcBuffer list, idp, idp2, tmp2;
4547 SilcHashTableList htl;
4548 const unsigned char a[1] = { 0x03 };
4550 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4552 /* Encode invite list */
4553 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4554 list = silc_buffer_alloc_size(2);
4555 type = silc_hash_table_count(channel->invite_list);
4556 SILC_PUT16_MSB(type, list->data);
4557 silc_hash_table_list(channel->invite_list, &htl);
4558 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4559 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4561 silc_hash_table_list_reset(&htl);
4563 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4565 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4566 idp->data, idp->len,
4567 channel->channel_name,
4568 strlen(channel->channel_name),
4569 idp2->data, idp2->len,
4571 list->data, list->len);
4572 silc_buffer_free(idp2);
4573 silc_buffer_free(list);
4576 /* Encode ban list */
4577 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4578 list = silc_buffer_alloc_size(2);
4579 type = silc_hash_table_count(channel->ban_list);
4580 SILC_PUT16_MSB(type, list->data);
4581 silc_hash_table_list(channel->ban_list, &htl);
4582 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4583 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4585 silc_hash_table_list_reset(&htl);
4588 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4589 idp->data, idp->len,
4591 list->data, list->len);
4592 silc_buffer_free(list);
4595 silc_buffer_free(idp);
4598 /* Returns assembled packets for channel users of the `channel'. */
4600 void silc_server_announce_get_channel_users(SilcServer server,
4601 SilcChannelEntry channel,
4602 SilcBuffer *channel_modes,
4603 SilcBuffer *channel_users,
4604 SilcBuffer *channel_users_modes)
4606 SilcChannelClientEntry chl;
4607 SilcHashTableList htl;
4608 SilcBuffer chidp, clidp, csidp;
4609 SilcBuffer tmp, fkey = NULL, chpklist;
4611 unsigned char mode[4];
4614 SILC_LOG_DEBUG(("Start"));
4616 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4617 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4618 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4621 SILC_PUT32_MSB(channel->mode, mode);
4622 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4623 if (channel->founder_key)
4624 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
4626 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4627 7, csidp->data, csidp->len,
4630 hmac, hmac ? strlen(hmac) : 0,
4631 channel->passphrase,
4632 channel->passphrase ?
4633 strlen(channel->passphrase) : 0,
4634 fkey ? fkey->data : NULL,
4635 fkey ? fkey->len : 0,
4636 chpklist ? chpklist->data : NULL,
4637 chpklist ? chpklist->len : 0);
4640 silc_buffer_realloc(*channel_modes,
4642 (*channel_modes)->truelen + len : len));
4643 silc_buffer_pull_tail(*channel_modes,
4644 ((*channel_modes)->end -
4645 (*channel_modes)->data));
4646 silc_buffer_put(*channel_modes, tmp->data, tmp->len);
4647 silc_buffer_pull(*channel_modes, len);
4648 silc_buffer_free(tmp);
4649 silc_buffer_free(fkey);
4652 /* Now find all users on the channel */
4653 silc_hash_table_list(channel->user_list, &htl);
4654 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4655 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4658 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4659 clidp->data, clidp->len,
4660 chidp->data, chidp->len);
4663 silc_buffer_realloc(*channel_users,
4665 (*channel_users)->truelen + len : len));
4666 silc_buffer_pull_tail(*channel_users,
4667 ((*channel_users)->end -
4668 (*channel_users)->data));
4670 silc_buffer_put(*channel_users, tmp->data, tmp->len);
4671 silc_buffer_pull(*channel_users, len);
4672 silc_buffer_free(tmp);
4674 /* CUMODE notify for mode change on the channel */
4675 SILC_PUT32_MSB(chl->mode, mode);
4676 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4677 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
4678 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4679 4, csidp->data, csidp->len,
4681 clidp->data, clidp->len,
4682 fkey ? fkey->data : NULL,
4683 fkey ? fkey->len : 0);
4685 *channel_users_modes =
4686 silc_buffer_realloc(*channel_users_modes,
4687 (*channel_users_modes ?
4688 (*channel_users_modes)->truelen + len : len));
4689 silc_buffer_pull_tail(*channel_users_modes,
4690 ((*channel_users_modes)->end -
4691 (*channel_users_modes)->data));
4693 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
4694 silc_buffer_pull(*channel_users_modes, len);
4695 silc_buffer_free(tmp);
4696 silc_buffer_free(fkey);
4698 silc_buffer_free(clidp);
4700 silc_hash_table_list_reset(&htl);
4701 silc_buffer_free(chidp);
4702 silc_buffer_free(csidp);
4705 /* Returns assembled packets for all channels and users on those channels
4706 from the given ID List. The packets are in the form dictated by the
4707 New Channel and New Channel User payloads. */
4709 void silc_server_announce_get_channels(SilcServer server,
4711 SilcBuffer *channels,
4712 SilcBuffer **channel_modes,
4713 SilcBuffer *channel_users,
4714 SilcBuffer **channel_users_modes,
4715 SilcUInt32 *channel_users_modes_c,
4716 SilcBuffer **channel_topics,
4717 SilcBuffer **channel_invites,
4718 SilcBuffer **channel_bans,
4719 SilcChannelID ***channel_ids,
4720 unsigned long creation_time)
4722 SilcIDCacheList list;
4723 SilcIDCacheEntry id_cache;
4724 SilcChannelEntry channel;
4727 SilcUInt16 name_len;
4729 int i = *channel_users_modes_c;
4732 SILC_LOG_DEBUG(("Start"));
4734 /* Go through all channels in the list */
4735 if (silc_idcache_get_all(id_list->channels, &list)) {
4736 if (silc_idcache_list_first(list, &id_cache)) {
4738 channel = (SilcChannelEntry)id_cache->context;
4740 if (creation_time && channel->created < creation_time)
4745 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
4746 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
4747 name_len = strlen(channel->channel_name);
4750 len = 4 + name_len + id_len + 4;
4752 silc_buffer_realloc(*channels,
4753 (*channels ? (*channels)->truelen +
4755 silc_buffer_pull_tail(*channels,
4756 ((*channels)->end - (*channels)->data));
4757 silc_buffer_format(*channels,
4758 SILC_STR_UI_SHORT(name_len),
4759 SILC_STR_UI_XNSTRING(channel->channel_name,
4761 SILC_STR_UI_SHORT(id_len),
4762 SILC_STR_UI_XNSTRING(cid, id_len),
4763 SILC_STR_UI_INT(channel->mode),
4765 silc_buffer_pull(*channels, len);
4768 if (creation_time && channel->updated < creation_time)
4774 /* Channel user modes */
4775 *channel_users_modes = silc_realloc(*channel_users_modes,
4776 sizeof(**channel_users_modes) *
4778 (*channel_users_modes)[i] = NULL;
4779 *channel_modes = silc_realloc(*channel_modes,
4780 sizeof(**channel_modes) * (i + 1));
4781 (*channel_modes)[i] = NULL;
4782 *channel_ids = silc_realloc(*channel_ids,
4783 sizeof(**channel_ids) * (i + 1));
4784 (*channel_ids)[i] = NULL;
4785 silc_server_announce_get_channel_users(server, channel,
4786 &(*channel_modes)[i],
4788 &(*channel_users_modes)[i]);
4789 (*channel_ids)[i] = channel->id;
4791 /* Channel's topic */
4792 *channel_topics = silc_realloc(*channel_topics,
4793 sizeof(**channel_topics) * (i + 1));
4794 (*channel_topics)[i] = NULL;
4795 silc_server_announce_get_channel_topic(server, channel,
4796 &(*channel_topics)[i]);
4798 /* Channel's invite and ban list */
4799 *channel_invites = silc_realloc(*channel_invites,
4800 sizeof(**channel_invites) * (i + 1));
4801 (*channel_invites)[i] = NULL;
4802 *channel_bans = silc_realloc(*channel_bans,
4803 sizeof(**channel_bans) * (i + 1));
4804 (*channel_bans)[i] = NULL;
4805 silc_server_announce_get_inviteban(server, channel,
4806 &(*channel_invites)[i],
4807 &(*channel_bans)[i]);
4809 (*channel_users_modes_c)++;
4815 if (!silc_idcache_list_next(list, &id_cache))
4820 silc_idcache_list_free(list);
4824 /* This function is used to announce our existing channels to our router
4825 when we've connected to it. This also announces the users on the
4826 channels to the router. If the `creation_time' is non-zero only the
4827 channels that was created after the `creation_time' are announced.
4828 Note that the channel users are still announced even if the `creation_time'
4831 void silc_server_announce_channels(SilcServer server,
4832 unsigned long creation_time,
4833 SilcSocketConnection remote)
4835 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4836 SilcBuffer *channel_users_modes = NULL;
4837 SilcBuffer *channel_topics = NULL;
4838 SilcBuffer *channel_invites = NULL;
4839 SilcBuffer *channel_bans = NULL;
4840 SilcUInt32 channel_users_modes_c = 0;
4841 SilcChannelID **channel_ids = NULL;
4843 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4845 /* Get channels and channel users in local list */
4846 silc_server_announce_get_channels(server, server->local_list,
4847 &channels, &channel_modes,
4849 &channel_users_modes,
4850 &channel_users_modes_c,
4854 &channel_ids, creation_time);
4856 /* Get channels and channel users in global list */
4857 if (server->server_type != SILC_SERVER)
4858 silc_server_announce_get_channels(server, server->global_list,
4859 &channels, &channel_modes,
4861 &channel_users_modes,
4862 &channel_users_modes_c,
4866 &channel_ids, creation_time);
4869 silc_buffer_push(channels, channels->data - channels->head);
4870 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
4872 /* Send the packet */
4873 silc_server_packet_send(server, remote,
4874 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4875 channels->data, channels->len,
4878 silc_buffer_free(channels);
4881 if (channel_users) {
4882 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4883 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4884 channel_users->len);
4886 /* Send the packet */
4887 silc_server_packet_send(server, remote,
4888 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4889 channel_users->data, channel_users->len,
4892 silc_buffer_free(channel_users);
4895 if (channel_modes) {
4898 for (i = 0; i < channel_users_modes_c; i++) {
4899 if (!channel_modes[i])
4901 silc_buffer_push(channel_modes[i],
4902 channel_modes[i]->data -
4903 channel_modes[i]->head);
4904 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4905 channel_modes[i]->len);
4906 silc_server_packet_send_dest(server, remote,
4907 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4908 channel_ids[i], SILC_ID_CHANNEL,
4909 channel_modes[i]->data,
4910 channel_modes[i]->len,
4912 silc_buffer_free(channel_modes[i]);
4914 silc_free(channel_modes);
4917 if (channel_users_modes) {
4920 for (i = 0; i < channel_users_modes_c; i++) {
4921 if (!channel_users_modes[i])
4923 silc_buffer_push(channel_users_modes[i],
4924 channel_users_modes[i]->data -
4925 channel_users_modes[i]->head);
4926 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4927 channel_users_modes[i]->len);
4928 silc_server_packet_send_dest(server, remote,
4929 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4930 channel_ids[i], SILC_ID_CHANNEL,
4931 channel_users_modes[i]->data,
4932 channel_users_modes[i]->len,
4934 silc_buffer_free(channel_users_modes[i]);
4936 silc_free(channel_users_modes);
4939 if (channel_topics) {
4942 for (i = 0; i < channel_users_modes_c; i++) {
4943 if (!channel_topics[i])
4946 silc_buffer_push(channel_topics[i],
4947 channel_topics[i]->data -
4948 channel_topics[i]->head);
4949 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4950 channel_topics[i]->len);
4951 silc_server_packet_send_dest(server, remote,
4952 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4953 channel_ids[i], SILC_ID_CHANNEL,
4954 channel_topics[i]->data,
4955 channel_topics[i]->len,
4957 silc_buffer_free(channel_topics[i]);
4959 silc_free(channel_topics);
4962 if (channel_invites) {
4965 for (i = 0; i < channel_users_modes_c; i++) {
4966 if (!channel_invites[i])
4969 silc_buffer_push(channel_invites[i],
4970 channel_invites[i]->data -
4971 channel_invites[i]->head);
4972 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4973 channel_invites[i]->len);
4974 silc_server_packet_send_dest(server, remote,
4975 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4976 channel_ids[i], SILC_ID_CHANNEL,
4977 channel_invites[i]->data,
4978 channel_invites[i]->len,
4980 silc_buffer_free(channel_invites[i]);
4982 silc_free(channel_invites);
4988 for (i = 0; i < channel_users_modes_c; i++) {
4989 if (!channel_bans[i])
4992 silc_buffer_push(channel_bans[i],
4993 channel_bans[i]->data -
4994 channel_bans[i]->head);
4995 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4996 channel_bans[i]->len);
4997 silc_server_packet_send_dest(server, remote,
4998 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4999 channel_ids[i], SILC_ID_CHANNEL,
5000 channel_bans[i]->data,
5001 channel_bans[i]->len,
5003 silc_buffer_free(channel_bans[i]);
5005 silc_free(channel_bans);
5008 silc_free(channel_ids);
5011 /* Assembles user list and users mode list from the `channel'. */
5013 bool silc_server_get_users_on_channel(SilcServer server,
5014 SilcChannelEntry channel,
5015 SilcBuffer *user_list,
5016 SilcBuffer *mode_list,
5017 SilcUInt32 *user_count)
5019 SilcChannelClientEntry chl;
5020 SilcHashTableList htl;
5021 SilcBuffer client_id_list;
5022 SilcBuffer client_mode_list;
5024 SilcUInt32 list_count = 0, len = 0;
5026 if (!silc_hash_table_count(channel->user_list))
5029 silc_hash_table_list(channel->user_list, &htl);
5030 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
5031 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
5032 silc_hash_table_list_reset(&htl);
5034 client_id_list = silc_buffer_alloc(len);
5036 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
5037 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
5038 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
5040 silc_hash_table_list(channel->user_list, &htl);
5041 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5043 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
5044 silc_buffer_put(client_id_list, idp->data, idp->len);
5045 silc_buffer_pull(client_id_list, idp->len);
5046 silc_buffer_free(idp);
5048 /* Client's mode on channel */
5049 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
5050 silc_buffer_pull(client_mode_list, 4);
5054 silc_hash_table_list_reset(&htl);
5055 silc_buffer_push(client_id_list,
5056 client_id_list->data - client_id_list->head);
5057 silc_buffer_push(client_mode_list,
5058 client_mode_list->data - client_mode_list->head);
5060 *user_list = client_id_list;
5061 *mode_list = client_mode_list;
5062 *user_count = list_count;
5066 /* Saves users and their modes to the `channel'. */
5068 void silc_server_save_users_on_channel(SilcServer server,
5069 SilcSocketConnection sock,
5070 SilcChannelEntry channel,
5071 SilcClientID *noadd,
5072 SilcBuffer user_list,
5073 SilcBuffer mode_list,
5074 SilcUInt32 user_count)
5079 SilcClientID *client_id;
5080 SilcClientEntry client;
5081 SilcIDCacheEntry cache;
5082 SilcChannelClientEntry chl;
5084 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5085 channel->channel_name));
5087 for (i = 0; i < user_count; i++) {
5089 SILC_GET16_MSB(idp_len, user_list->data + 2);
5091 client_id = silc_id_payload_parse_id(user_list->data, idp_len, NULL);
5092 silc_buffer_pull(user_list, idp_len);
5097 SILC_GET32_MSB(mode, mode_list->data);
5098 silc_buffer_pull(mode_list, 4);
5100 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
5101 silc_free(client_id);
5107 /* Check if we have this client cached already. */
5108 client = silc_idlist_find_client_by_id(server->local_list, client_id,
5109 server->server_type, &cache);
5111 client = silc_idlist_find_client_by_id(server->global_list,
5112 client_id, server->server_type,
5115 /* If router did not find such Client ID in its lists then this must
5116 be bogus client or some router in the net is buggy. */
5117 if (server->server_type != SILC_SERVER) {
5118 silc_free(client_id);
5122 /* We don't have that client anywhere, add it. The client is added
5123 to global list since server didn't have it in the lists so it must be
5125 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5126 silc_id_dup(client_id, SILC_ID_CLIENT),
5127 sock->user_data, NULL, 0);
5129 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5130 silc_free(client_id);
5134 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5139 silc_free(client_id);
5141 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5142 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5143 "%s", channel->channel_name));
5147 if (!silc_server_client_on_channel(client, channel, &chl)) {
5148 /* Client was not on the channel, add it. */
5149 chl = silc_calloc(1, sizeof(*chl));
5150 chl->client = client;
5152 chl->channel = channel;
5153 silc_hash_table_add(channel->user_list, chl->client, chl);
5154 silc_hash_table_add(client->channels, chl->channel, chl);
5155 channel->user_count++;
5163 /* Saves channels and channels user modes to the `client'. Removes
5164 the client from those channels that are not sent in the list but
5167 void silc_server_save_user_channels(SilcServer server,
5168 SilcSocketConnection sock,
5169 SilcClientEntry client,
5170 SilcBuffer channels,
5171 SilcBuffer channels_user_modes)
5174 SilcUInt32 *chumodes;
5175 SilcChannelPayload entry;
5176 SilcChannelEntry channel;
5177 SilcChannelID *channel_id;
5178 SilcChannelClientEntry chl;
5179 SilcHashTable ht = NULL;
5180 SilcHashTableList htl;
5184 if (!channels || !channels_user_modes ||
5185 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5188 ch = silc_channel_payload_parse_list(channels->data, channels->len);
5189 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5191 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5192 NULL, NULL, NULL, TRUE);
5193 silc_dlist_start(ch);
5194 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5195 /* Check if we have this channel, and add it if we don't have it.
5196 Also add the client on the channel unless it is there already. */
5197 channel_id = silc_channel_get_id_parse(entry);
5198 channel = silc_idlist_find_channel_by_id(server->local_list,
5201 channel = silc_idlist_find_channel_by_id(server->global_list,
5204 if (server->server_type != SILC_SERVER) {
5205 silc_free(channel_id);
5210 /* We don't have that channel anywhere, add it. */
5211 name = silc_channel_get_name(entry, NULL);
5212 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5213 channel_id, server->router,
5216 silc_free(channel_id);
5223 channel->mode = silc_channel_get_mode(entry);
5225 /* Add the client on the channel */
5226 if (!silc_server_client_on_channel(client, channel, &chl)) {
5227 chl = silc_calloc(1, sizeof(*chl));
5228 chl->client = client;
5229 chl->mode = chumodes[i++];
5230 chl->channel = channel;
5231 silc_hash_table_add(channel->user_list, chl->client, chl);
5232 silc_hash_table_add(client->channels, chl->channel, chl);
5233 channel->user_count++;
5236 chl->mode = chumodes[i++];
5239 silc_hash_table_add(ht, channel, channel);
5240 silc_free(channel_id);
5242 silc_channel_payload_list_free(ch);
5243 silc_free(chumodes);
5247 /* Go through the list again and remove client from channels that
5248 are no part of the list. */
5250 silc_hash_table_list(client->channels, &htl);
5251 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5252 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5253 silc_hash_table_del(chl->channel->user_list, chl->client);
5254 silc_hash_table_del(chl->client->channels, chl->channel);
5258 silc_hash_table_list_reset(&htl);
5259 silc_hash_table_free(ht);
5261 silc_hash_table_list(client->channels, &htl);
5262 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5263 silc_hash_table_del(chl->channel->user_list, chl->client);
5264 silc_hash_table_del(chl->client->channels, chl->channel);
5267 silc_hash_table_list_reset(&htl);
5271 /* Lookups route to the client indicated by the `id_data'. The connection
5272 object and internal data object is returned. Returns NULL if route
5273 could not be found to the client. If the `client_id' is specified then
5274 it is used and the `id_data' is ignored. */
5276 SilcSocketConnection
5277 silc_server_get_client_route(SilcServer server,
5278 unsigned char *id_data,
5280 SilcClientID *client_id,
5281 SilcIDListData *idata,
5282 SilcClientEntry *client_entry)
5285 SilcClientEntry client;
5287 SILC_LOG_DEBUG(("Start"));
5290 *client_entry = NULL;
5292 /* Decode destination Client ID */
5294 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
5296 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
5300 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5303 /* If the destination belongs to our server we don't have to route
5304 the packet anywhere but to send it to the local destination. */
5305 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5309 /* If we are router and the client has router then the client is in
5310 our cell but not directly connected to us. */
5311 if (server->server_type == SILC_ROUTER && client->router) {
5312 /* We are of course in this case the client's router thus the route
5313 to the client is the server who owns the client. So, we will send
5314 the packet to that server. */
5316 *idata = (SilcIDListData)client->router;
5317 return client->router->connection;
5320 /* Seems that client really is directly connected to us */
5322 *idata = (SilcIDListData)client;
5324 *client_entry = client;
5325 return client->connection;
5328 /* Destination belongs to someone not in this server. If we are normal
5329 server our action is to send the packet to our router. */
5330 if (server->server_type != SILC_ROUTER && !server->standalone) {
5333 *idata = (SilcIDListData)server->router;
5334 return SILC_PRIMARY_ROUTE(server);
5337 /* We are router and we will perform route lookup for the destination
5338 and send the packet to fastest route. */
5339 if (server->server_type == SILC_ROUTER && !server->standalone) {
5340 /* Check first that the ID is valid */
5341 client = silc_idlist_find_client_by_id(server->global_list, id,
5344 SilcSocketConnection dst_sock;
5346 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5350 *idata = (SilcIDListData)dst_sock->user_data;
5359 /* Encodes and returns channel list of channels the `client' has joined.
5360 Secret channels are not put to the list. */
5362 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5363 SilcClientEntry client,
5366 SilcBuffer *user_mode_list)
5368 SilcBuffer buffer = NULL;
5369 SilcChannelEntry channel;
5370 SilcChannelClientEntry chl;
5371 SilcHashTableList htl;
5374 SilcUInt16 name_len;
5378 *user_mode_list = NULL;
5380 silc_hash_table_list(client->channels, &htl);
5381 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5382 channel = chl->channel;
5384 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5386 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5389 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
5390 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
5391 name_len = strlen(channel->channel_name);
5393 len = 4 + name_len + id_len + 4;
5394 buffer = silc_buffer_realloc(buffer,
5395 (buffer ? buffer->truelen + len : len));
5396 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5397 silc_buffer_format(buffer,
5398 SILC_STR_UI_SHORT(name_len),
5399 SILC_STR_UI_XNSTRING(channel->channel_name,
5401 SILC_STR_UI_SHORT(id_len),
5402 SILC_STR_UI_XNSTRING(cid, id_len),
5403 SILC_STR_UI_INT(chl->channel->mode),
5405 silc_buffer_pull(buffer, len);
5408 if (user_mode_list) {
5409 *user_mode_list = silc_buffer_realloc(*user_mode_list,
5411 (*user_mode_list)->truelen + 4 :
5413 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5414 (*user_mode_list)->data));
5415 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5416 silc_buffer_pull(*user_mode_list, 4);
5419 silc_hash_table_list_reset(&htl);
5422 silc_buffer_push(buffer, buffer->data - buffer->head);
5423 if (user_mode_list && *user_mode_list)
5424 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5425 (*user_mode_list)->head));
5430 /* Timeout callback for unsuccessful rekey. The rekey did not go through
5433 SILC_TASK_CALLBACK(silc_server_rekey_timeout)
5435 SilcServerRekeyInternalContext *ctx = context;
5436 SilcServer server = app_context;
5437 SilcSocketConnection sock = ctx->sock;
5439 SILC_LOG_DEBUG(("Timeout occurred in rekey protocol with %s:%d [%s]",
5440 sock->hostname, sock->port,
5441 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5442 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5443 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5446 SILC_LOG_WARNING(("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 if (sock->protocol) {
5454 silc_protocol_cancel(sock->protocol, server->schedule);
5455 silc_protocol_free(sock->protocol);
5456 sock->protocol = NULL;
5459 silc_packet_context_free(ctx->packet);
5461 silc_ske_free(ctx->ske);
5462 silc_socket_free(sock);
5465 /* Disconnect since we failed to rekey, the keys are probably wrong. */
5466 silc_server_disconnect_remote(server, sock,
5467 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
5468 if (sock->user_data)
5469 silc_server_free_sock_user_data(server, sock, NULL);
5472 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
5473 silc_server_create_connections(server);
5476 /* A timeout callback for the re-key. We will be the initiator of the
5479 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_callback)
5481 SilcServer server = app_context;
5482 SilcSocketConnection sock = (SilcSocketConnection)context;
5483 SilcIDListData idata = (SilcIDListData)sock->user_data;
5484 SilcProtocol protocol;
5485 SilcServerRekeyInternalContext *proto_ctx;
5490 /* Do not execute rekey with disabled connections, as it would not
5491 go through anyway. */
5492 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
5495 /* If rekey protocol is active already wait for it to finish */
5496 if (sock->protocol && sock->protocol->protocol &&
5497 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)
5500 /* If any other protocol is active do not start this protocol yet. */
5501 if (sock->protocol) {
5502 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
5503 silc_schedule_task_add(server->schedule, sock->sock,
5504 silc_server_rekey_callback,
5505 sock, 60, 0, SILC_TASK_TIMEOUT,
5506 SILC_TASK_PRI_NORMAL);
5510 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
5511 sock->hostname, sock->port,
5512 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5513 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5514 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5517 /* Allocate internal protocol context. This is sent as context
5519 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
5520 proto_ctx->server = (void *)server;
5521 proto_ctx->sock = silc_socket_dup(sock);
5522 proto_ctx->responder = FALSE;
5523 proto_ctx->pfs = idata->rekey->pfs;
5525 /* Perform rekey protocol. Will call the final callback after the
5526 protocol is over. */
5527 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
5528 &protocol, proto_ctx, silc_server_rekey_final);
5529 sock->protocol = protocol;
5531 /* Register timeout callback in case the rekey does not go through. */
5532 proto_ctx->timeout_task =
5533 silc_schedule_task_add(server->schedule, sock->sock,
5534 silc_server_rekey_timeout,
5536 (idata->rekey->timeout >
5537 server->config->key_exchange_timeout ?
5538 idata->rekey->timeout :
5539 server->config->key_exchange_timeout * 4), 0,
5543 /* Run the protocol */
5544 silc_protocol_execute(protocol, server->schedule, 0, 0);
5547 /* The final callback for the REKEY protocol. This will actually take the
5548 new key material into use. */
5550 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
5552 SilcProtocol protocol = (SilcProtocol)context;
5553 SilcServerRekeyInternalContext *ctx =
5554 (SilcServerRekeyInternalContext *)protocol->context;
5555 SilcServer server = (SilcServer)ctx->server;
5556 SilcSocketConnection sock = ctx->sock;
5557 SilcIDListData idata = (SilcIDListData)sock->user_data;
5559 if (ctx->timeout_task)
5560 silc_schedule_task_del(server->schedule, ctx->timeout_task);
5562 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
5563 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
5564 /* Error occured during protocol */
5565 SILC_LOG_ERROR(("Error occurred during rekey protocol with "
5566 "%s (%s)", sock->hostname, sock->ip));
5567 silc_protocol_cancel(protocol, server->schedule);
5568 silc_protocol_free(protocol);
5569 sock->protocol = NULL;
5571 silc_packet_context_free(ctx->packet);
5573 silc_ske_free(ctx->ske);
5574 silc_socket_free(sock);
5576 silc_server_disconnect_remote(server, sock,
5577 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
5578 if (sock->user_data)
5579 silc_server_free_sock_user_data(server, sock, NULL);
5582 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
5583 silc_server_create_connections(server);
5587 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
5588 sock->hostname, sock->port,
5589 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5590 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5591 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5594 /* Purge the outgoing data queue to assure that all rekey packets really
5595 go to the network before we quit the protocol. */
5596 silc_server_packet_queue_purge(server, sock);
5598 /* Re-register re-key timeout */
5599 if (ctx->responder == FALSE)
5600 silc_schedule_task_add(server->schedule, sock->sock,
5601 silc_server_rekey_callback,
5602 sock, idata->rekey->timeout, 0,
5603 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
5606 silc_protocol_free(protocol);
5607 sock->protocol = NULL;
5609 silc_packet_context_free(ctx->packet);
5611 silc_ske_free(ctx->ske);
5612 silc_socket_free(sock);
5616 /* Task callback used to retrieve network statistical information from
5617 router server once in a while. */
5619 SILC_TASK_CALLBACK(silc_server_get_stats)
5621 SilcServer server = (SilcServer)context;
5622 SilcBuffer idp, packet;
5624 if (!server->standalone) {
5625 SILC_LOG_DEBUG(("Retrieving stats from router"));
5626 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5627 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5628 ++server->cmd_ident, 1,
5629 1, idp->data, idp->len);
5630 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5631 SILC_PACKET_COMMAND, 0, packet->data,
5632 packet->len, FALSE);
5633 silc_buffer_free(packet);
5634 silc_buffer_free(idp);
5637 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
5638 server, 120, 0, SILC_TASK_TIMEOUT,