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);
46 /* Allocates a new SILC server object. This has to be done before the server
47 can be used. After allocation one must call silc_server_init to initialize
48 the server. The new allocated server object is returned to the new_server
51 int silc_server_alloc(SilcServer *new_server)
55 SILC_LOG_DEBUG(("Allocating new server object"));
57 server = silc_calloc(1, sizeof(*server));
58 server->server_type = SILC_SERVER;
59 server->standalone = TRUE;
60 server->local_list = silc_calloc(1, sizeof(*server->local_list));
61 server->global_list = silc_calloc(1, sizeof(*server->global_list));
62 server->pending_commands = silc_dlist_init();
64 server->sim = silc_dlist_init();
72 /* Free's the SILC server object. This is called at the very end before
75 void silc_server_free(SilcServer server)
78 SilcIDCacheEntry cache;
86 silc_dlist_start(server->sim);
87 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
88 silc_dlist_del(server->sim, sim);
92 silc_dlist_uninit(server->sim);
96 silc_server_backup_free(server);
97 silc_server_config_unref(&server->config_ref);
99 silc_rng_free(server->rng);
101 silc_pkcs_free(server->pkcs);
102 if (server->public_key)
103 silc_pkcs_public_key_free(server->public_key);
104 if (server->private_key)
105 silc_pkcs_private_key_free(server->private_key);
106 if (server->pending_commands)
107 silc_dlist_uninit(server->pending_commands);
108 if (server->id_entry)
109 silc_idlist_del_server(server->local_list, server->id_entry);
111 /* Delete all channels */
113 if (silc_idcache_get_all(server->local_list->channels, &list) &&
114 silc_idcache_list_first(list, &cache)) {
115 silc_idlist_del_channel(server->local_list, cache->context);
116 while (silc_idcache_list_next(list, &cache))
117 silc_idlist_del_channel(server->local_list, cache->context);
120 silc_idcache_list_free(list);
122 if (silc_idcache_get_all(server->global_list->channels, &list) &&
123 silc_idcache_list_first(list, &cache)) {
124 silc_idlist_del_channel(server->global_list, cache->context);
125 while (silc_idcache_list_next(list, &cache))
126 silc_idlist_del_channel(server->global_list, cache->context);
129 silc_idcache_list_free(list);
132 silc_hash_table_free(server->pk_hash);
134 /* Delete all clients */
136 if (silc_idcache_get_all(server->local_list->clients, &list) &&
137 silc_idcache_list_first(list, &cache)) {
138 silc_idlist_del_client(server->local_list, cache->context);
139 while (silc_idcache_list_next(list, &cache))
140 silc_idlist_del_client(server->local_list, cache->context);
143 silc_idcache_list_free(list);
145 if (silc_idcache_get_all(server->global_list->clients, &list) &&
146 silc_idcache_list_first(list, &cache)) {
147 silc_idlist_del_client(server->global_list, cache->context);
148 while (silc_idcache_list_next(list, &cache))
149 silc_idlist_del_client(server->global_list, cache->context);
152 silc_idcache_list_free(list);
155 /* Delete all servers */
157 if (silc_idcache_get_all(server->local_list->servers, &list) &&
158 silc_idcache_list_first(list, &cache)) {
159 silc_idlist_del_server(server->local_list, cache->context);
160 while (silc_idcache_list_next(list, &cache))
161 silc_idlist_del_server(server->local_list, cache->context);
164 silc_idcache_list_free(list);
166 if (silc_idcache_get_all(server->global_list->servers, &list) &&
167 silc_idcache_list_first(list, &cache)) {
168 silc_idlist_del_server(server->global_list, cache->context);
169 while (silc_idcache_list_next(list, &cache))
170 silc_idlist_del_server(server->global_list, cache->context);
173 silc_idcache_list_free(list);
175 silc_idcache_free(server->local_list->clients);
176 silc_idcache_free(server->local_list->servers);
177 silc_idcache_free(server->local_list->channels);
178 silc_idcache_free(server->global_list->clients);
179 silc_idcache_free(server->global_list->servers);
180 silc_idcache_free(server->global_list->channels);
181 silc_hash_table_free(server->watcher_list);
183 silc_hash_free(server->md5hash);
184 silc_hash_free(server->sha1hash);
185 silc_hmac_unregister_all();
186 silc_hash_unregister_all();
187 silc_cipher_unregister_all();
188 silc_pkcs_unregister_all();
190 silc_free(server->local_list);
191 silc_free(server->global_list);
192 silc_free(server->server_name);
193 silc_free(server->id_string);
194 silc_free(server->purge_i);
195 silc_free(server->purge_g);
199 /* Creates a new server listener. */
201 static bool silc_server_listen(SilcServer server, const char *server_ip,
202 SilcUInt16 port, int *sock)
204 *sock = silc_net_create_server(port, server_ip);
206 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
213 /* Adds a secondary listener. */
215 bool silc_server_init_secondary(SilcServer server)
217 int sock = 0, sock_list[server->config->param.connections_max];
218 SilcSocketConnection newsocket = NULL;
219 SilcServerConfigServerInfoInterface *interface;
221 for (interface = server->config->server_info->secondary; interface;
222 interface = interface->next, sock++) {
224 if (!silc_server_listen(server,
225 interface->server_ip, interface->port, &sock_list[sock]))
228 /* Set socket to non-blocking mode */
229 silc_net_set_socket_nonblock(sock_list[sock]);
231 /* Add ourselves also to the socket table. The entry allocated above
232 is sent as argument for fast referencing in the future. */
233 silc_socket_alloc(sock_list[sock],
234 SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
235 server->sockets[sock_list[sock]] = newsocket;
236 SILC_SET_LISTENER(newsocket);
238 /* Perform name and address lookups to resolve the listenning address
240 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
242 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
244 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
245 newsocket->hostname ? newsocket->hostname :
246 newsocket->ip ? newsocket->ip : ""));
247 server->stat.conn_failures++;
250 if (!newsocket->hostname)
251 newsocket->hostname = strdup(newsocket->ip);
253 newsocket->port = silc_net_get_local_port(sock);
255 newsocket->user_data = (void *)server->id_entry;
256 silc_schedule_task_add(server->schedule, sock_list[sock],
257 silc_server_accept_new_connection,
258 (void *)server, 0, 0,
260 SILC_TASK_PRI_NORMAL);
266 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
270 /* Initializes the entire SILC server. This is called always before running
271 the server. This is called only once at the initialization of the program.
272 This binds the server to its listenning port. After this function returns
273 one should call silc_server_run to start the server. This returns TRUE
274 when everything is ok to run the server. Configuration file must be
275 read and parsed before calling this. */
277 bool silc_server_init(SilcServer server)
281 SilcServerEntry id_entry;
282 SilcIDListPurge purge;
283 SilcSocketConnection newsocket = NULL;
285 SILC_LOG_DEBUG(("Initializing server"));
287 server->starttime = time(NULL);
289 /* Take config object for us */
290 silc_server_config_ref(&server->config_ref, server->config,
294 /* Set debugging on if configured */
295 if (server->config->debug_string) {
297 silc_log_set_debug_string(server->config->debug_string);
299 #endif /* SILC_DEBUG */
301 /* Steal public and private key from the config object */
302 server->public_key = server->config->server_info->public_key;
303 server->private_key = server->config->server_info->private_key;
304 server->config->server_info->public_key = NULL;
305 server->config->server_info->private_key = NULL;
307 /* Register all configured ciphers, PKCS and hash functions. */
308 if (!silc_server_config_register_ciphers(server))
309 silc_cipher_register_default();
310 if (!silc_server_config_register_pkcs(server))
311 silc_pkcs_register_default();
312 if (!silc_server_config_register_hashfuncs(server))
313 silc_hash_register_default();
314 if (!silc_server_config_register_hmacs(server))
315 silc_hmac_register_default();
317 /* Initialize random number generator for the server. */
318 server->rng = silc_rng_alloc();
319 silc_rng_init(server->rng);
320 silc_rng_global_init(server->rng);
322 /* Initialize hash functions for server to use */
323 silc_hash_alloc("md5", &server->md5hash);
324 silc_hash_alloc("sha1", &server->sha1hash);
326 /* Allocate PKCS context for local public and private keys */
327 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
329 silc_pkcs_public_key_set(server->pkcs, server->public_key);
330 silc_pkcs_private_key_set(server->pkcs, server->private_key);
332 /* Initialize the scheduler */
333 server->schedule = silc_schedule_init(server->config->param.connections_max,
335 if (!server->schedule)
338 /* First, register log files configuration for error output */
339 silc_server_config_setlogfiles(server);
341 /* Initialize ID caches */
342 server->local_list->clients =
343 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
344 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
345 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
347 /* These are allocated for normal server as well as these hold some
348 global information that the server has fetched from its router. For
349 router these are used as they are supposed to be used on router. */
350 server->global_list->clients =
351 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
352 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
353 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
355 /* Init watcher list */
356 server->watcher_list =
357 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
358 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
360 if (!server->watcher_list)
363 /* Init public key list */
365 silc_hash_table_alloc(0, silc_hash_public_key, NULL,
366 silc_hash_public_key_compare, NULL,
369 if (!server->pk_hash)
372 /* Create a listening server */
373 if (!silc_server_listen(server,
374 server->config->server_info->primary == NULL ? NULL :
375 server->config->server_info->primary->server_ip,
376 server->config->server_info->primary == NULL ? 0 :
377 server->config->server_info->primary->port,
381 /* Set socket to non-blocking mode */
382 silc_net_set_socket_nonblock(sock);
385 /* Allocate the entire socket list that is used in server. Eventually
386 all connections will have entry in this table (it is a table of
387 pointers to the actual object that is allocated individually
389 server->sockets = silc_calloc(server->config->param.connections_max,
390 sizeof(*server->sockets));
391 if (!server->sockets)
394 /* Add ourselves also to the socket table. The entry allocated above
395 is sent as argument for fast referencing in the future. */
396 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
397 server->sockets[sock] = newsocket;
398 SILC_SET_LISTENER(newsocket);
400 /* Perform name and address lookups to resolve the listenning address
402 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
404 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
406 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
407 newsocket->hostname ? newsocket->hostname :
408 newsocket->ip ? newsocket->ip : ""));
409 server->stat.conn_failures++;
412 if (!newsocket->hostname)
413 newsocket->hostname = strdup(newsocket->ip);
415 newsocket->port = silc_net_get_local_port(sock);
417 /* Create a Server ID for the server. */
418 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
423 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
424 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
425 server->server_name = server->config->server_info->server_name;
426 server->config->server_info->server_name = NULL;
428 /* Add ourselves to the server list. We don't have a router yet
429 beacuse we haven't established a route yet. It will be done later.
430 For now, NULL is sent as router. This allocates new entry to
433 silc_idlist_add_server(server->local_list, strdup(server->server_name),
434 server->server_type, server->id, NULL, NULL);
436 SILC_LOG_ERROR(("Could not add ourselves to cache"));
439 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
441 /* Put the allocated socket pointer also to the entry allocated above
442 for fast back-referencing to the socket list. */
443 newsocket->user_data = (void *)id_entry;
444 id_entry->connection = (void *)newsocket;
445 server->id_entry = id_entry;
447 /* Register protocols */
448 silc_server_protocols_register();
450 /* Create connections to configured routers. */
451 silc_server_create_connections(server);
453 /* Add listener task to the scheduler. This task receives new connections
454 to the server. This task remains on the queue until the end of the
456 silc_schedule_task_add(server->schedule, sock,
457 silc_server_accept_new_connection,
458 (void *)server, 0, 0,
460 SILC_TASK_PRI_NORMAL);
462 if (silc_server_init_secondary(server) == FALSE)
465 server->listenning = TRUE;
467 /* If server connections has been configured then we must be router as
468 normal server cannot have server connections, only router connections. */
469 if (server->config->servers) {
470 SilcServerConfigServer *ptr = server->config->servers;
472 server->server_type = SILC_ROUTER;
474 if (ptr->backup_router) {
475 server->server_type = SILC_BACKUP_ROUTER;
476 server->backup_router = TRUE;
477 server->id_entry->server_type = SILC_BACKUP_ROUTER;
484 /* Register the ID Cache purge task. This periodically purges the ID cache
485 and removes the expired cache entries. */
487 /* Clients local list */
488 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
489 purge->cache = server->local_list->clients;
490 purge->timeout = 600;
491 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
492 (void *)purge, purge->timeout, 0,
493 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
495 /* Clients global list */
496 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
497 purge->cache = server->global_list->clients;
498 purge->timeout = 300;
499 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
500 (void *)purge, purge->timeout, 0,
501 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
503 /* If we are normal server we'll retrieve network statisticial information
504 once in a while from the router. */
505 if (server->server_type != SILC_ROUTER)
506 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
507 server, 10, 0, SILC_TASK_TIMEOUT,
510 if (server->server_type == SILC_ROUTER)
511 server->stat.routers++;
513 SILC_LOG_DEBUG(("Server initialized"));
515 /* We are done here, return succesfully */
519 silc_server_config_unref(&server->config_ref);
520 silc_net_close_server(sock);
524 /* Task callback to close a socket connection after rehash */
526 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
528 SilcServer server = context;
529 SilcSocketConnection sock = server->sockets[fd];
534 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
535 sock->hostname, sock->port,
536 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
537 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
538 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
540 silc_schedule_task_del_by_context(server->schedule, sock);
541 silc_server_disconnect_remote(server, sock,
542 SILC_STATUS_ERR_BANNED_FROM_SERVER,
543 "This connection is removed from "
546 silc_server_free_sock_user_data(server, sock, NULL);
549 /* This function basically reads the config file again and switches the config
550 object pointed by the server object. After that, we have to fix various
551 things such as the server_name and the listening ports.
552 Keep in mind that we no longer have the root privileges at this point. */
554 bool silc_server_rehash(SilcServer server)
556 SilcServerConfig newconfig;
558 SILC_LOG_INFO(("Rehashing server"));
560 /* Reset the logging system */
561 silc_log_quick = TRUE;
562 silc_log_flush_all();
564 /* Start the main rehash phase (read again the config file) */
565 newconfig = silc_server_config_alloc(server->config_file);
567 SILC_LOG_ERROR(("Rehash FAILED."));
571 /* Reinit scheduler if necessary */
572 if (newconfig->param.connections_max > server->config->param.connections_max)
573 if (!silc_schedule_reinit(server->schedule,
574 newconfig->param.connections_max))
577 /* Fix the server_name field */
578 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
579 silc_free(server->server_name);
580 server->server_name = newconfig->server_info->server_name;
581 newconfig->server_info->server_name = NULL;
583 /* Update the idcache list with a fresh pointer */
584 silc_free(server->id_entry->server_name);
585 server->id_entry->server_name = strdup(server->server_name);
586 if (!silc_idcache_del_by_context(server->local_list->servers,
589 if (!silc_idcache_add(server->local_list->servers,
590 server->id_entry->server_name,
591 server->id_entry->id, server->id_entry, 0, NULL))
596 silc_server_config_setlogfiles(server);
598 /* Change new key pair if necessary */
599 if (newconfig->server_info->public_key &&
600 !silc_pkcs_public_key_compare(server->public_key,
601 newconfig->server_info->public_key)) {
602 silc_pkcs_public_key_free(server->public_key);
603 silc_pkcs_private_key_free(server->private_key);
604 server->public_key = newconfig->server_info->public_key;
605 server->private_key = newconfig->server_info->private_key;
606 newconfig->server_info->public_key = NULL;
607 newconfig->server_info->private_key = NULL;
609 /* Allocate PKCS context for local public and private keys */
610 silc_pkcs_free(server->pkcs);
611 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
613 silc_pkcs_public_key_set(server->pkcs, server->public_key);
614 silc_pkcs_private_key_set(server->pkcs, server->private_key);
617 /* Check for unconfigured server and router connections and close
618 connections that were unconfigured. */
620 if (server->config->routers) {
621 SilcServerConfigRouter *ptr;
622 SilcServerConfigRouter *newptr;
625 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
628 /* Check whether new config has this one too */
629 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
630 if (silc_string_compare(newptr->host, ptr->host) &&
631 newptr->port == ptr->port &&
632 newptr->initiator == ptr->initiator) {
638 if (!found && ptr->host) {
639 /* Remove this connection */
640 SilcSocketConnection sock;
641 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_ROUTER,
642 ptr->host, ptr->port);
643 if (sock && !SILC_IS_LISTENER(sock))
644 silc_schedule_task_add(server->schedule, sock->sock,
645 silc_server_rehash_close_connection,
646 server, 0, 1, SILC_TASK_TIMEOUT,
647 SILC_TASK_PRI_NORMAL);
652 if (server->config->servers) {
653 SilcServerConfigServer *ptr;
654 SilcServerConfigServer *newptr;
657 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
660 /* Check whether new config has this one too */
661 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
662 if (silc_string_compare(newptr->host, ptr->host)) {
668 if (!found && ptr->host) {
669 /* Remove this connection */
670 SilcSocketConnection sock;
671 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_SERVER,
673 if (sock && !SILC_IS_LISTENER(sock))
674 silc_schedule_task_add(server->schedule, sock->sock,
675 silc_server_rehash_close_connection,
676 server, 0, 1, SILC_TASK_TIMEOUT,
677 SILC_TASK_PRI_NORMAL);
682 if (server->config->clients) {
683 SilcServerConfigClient *ptr;
684 SilcServerConfigClient *newptr;
687 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
690 /* Check whether new config has this one too */
691 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
692 if (silc_string_compare(newptr->host, ptr->host)) {
698 if (!found && ptr->host) {
699 /* Remove this connection */
700 SilcSocketConnection sock;
701 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_CLIENT,
704 silc_schedule_task_add(server->schedule, sock->sock,
705 silc_server_rehash_close_connection,
706 server, 0, 1, SILC_TASK_TIMEOUT,
707 SILC_TASK_PRI_NORMAL);
712 /* Create connections after rehash */
713 silc_server_create_connections(server);
715 /* Check whether our router status has changed */
716 if (newconfig->servers) {
717 SilcServerConfigServer *ptr = newconfig->servers;
719 server->server_type = SILC_ROUTER;
721 if (ptr->backup_router) {
722 server->server_type = SILC_BACKUP_ROUTER;
723 server->backup_router = TRUE;
724 server->id_entry->server_type = SILC_BACKUP_ROUTER;
731 /* Our old config is gone now. We'll unreference our reference made in
732 silc_server_init and then destroy it since we are destroying it
733 underneath the application (layer which called silc_server_init). */
734 silc_server_config_unref(&server->config_ref);
735 silc_server_config_destroy(server->config);
737 /* Take new config context */
738 server->config = newconfig;
739 silc_server_config_ref(&server->config_ref, server->config, server->config);
742 /* Set debugging on if configured */
743 if (server->config->debug_string) {
745 silc_log_set_debug_string(server->config->debug_string);
749 #endif /* SILC_DEBUG */
751 SILC_LOG_DEBUG(("Server rehashed"));
756 /* The heart of the server. This runs the scheduler thus runs the server.
757 When this returns the server has been stopped and the program will
760 void silc_server_run(SilcServer server)
762 SILC_LOG_INFO(("SILC Server started"));
764 /* Start the scheduler, the heart of the SILC server. When this returns
765 the program will be terminated. */
766 silc_schedule(server->schedule);
769 /* Stops the SILC server. This function is used to shutdown the server.
770 This is usually called after the scheduler has returned. After stopping
771 the server one should call silc_server_free. */
773 void silc_server_stop(SilcServer server)
775 SILC_LOG_INFO(("SILC Server shutting down"));
777 if (server->schedule) {
780 server->server_shutdown = TRUE;
782 /* Close all connections */
783 for (i = 0; i < server->config->param.connections_max; i++) {
784 if (!server->sockets[i])
786 if (!SILC_IS_LISTENER(server->sockets[i])) {
787 SilcSocketConnection sock = server->sockets[i];
788 SilcIDListData idata = sock->user_data;
791 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
793 silc_schedule_task_del_by_context(server->schedule,
795 silc_schedule_task_del_by_fd(server->schedule,
796 server->sockets[i]->sock);
797 silc_server_disconnect_remote(server, server->sockets[i],
799 "Server is shutting down");
800 if (server->sockets[i]) {
802 silc_server_free_sock_user_data(server, sock,
803 "Server is shutting down");
804 silc_socket_free(sock);
807 silc_socket_free(server->sockets[i]);
808 server->sockets[i] = NULL;
812 /* We are not connected to network anymore */
813 server->standalone = TRUE;
815 silc_schedule_stop(server->schedule);
816 silc_schedule_uninit(server->schedule);
817 server->schedule = NULL;
819 silc_free(server->sockets);
820 server->sockets = NULL;
823 silc_server_protocols_unregister();
825 SILC_LOG_DEBUG(("Server stopped"));
828 /* Function that is called when the network connection to a router has
829 been established. This will continue with the key exchange protocol
830 with the remote router. */
832 void silc_server_start_key_exchange(SilcServer server,
833 SilcServerConnection sconn,
836 SilcSocketConnection newsocket;
837 SilcProtocol protocol;
838 SilcServerKEInternalContext *proto_ctx;
839 SilcServerConfigRouter *conn =
840 (SilcServerConfigRouter *) sconn->conn.ref_ptr;
843 /* Cancel any possible retry timeouts */
844 silc_schedule_task_del_by_callback(server->schedule,
845 silc_server_connect_to_router_retry);
847 /* Set socket options */
848 silc_net_set_socket_nonblock(sock);
849 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
851 /* Create socket connection for the connection. Even though we
852 know that we are connecting to a router we will mark the socket
853 to be unknown connection until we have executed authentication
855 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
856 server->sockets[sock] = newsocket;
857 newsocket->hostname = strdup(sconn->remote_host);
858 newsocket->ip = strdup(sconn->remote_host);
859 newsocket->port = sconn->remote_port;
860 sconn->sock = newsocket;
862 /* Allocate internal protocol context. This is sent as context
864 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
865 proto_ctx->server = (void *)server;
866 proto_ctx->context = (void *)sconn;
867 proto_ctx->sock = newsocket;
868 proto_ctx->rng = server->rng;
869 proto_ctx->responder = FALSE;
871 /* Set Key Exchange flags from configuration, but fall back to global
873 SILC_GET_SKE_FLAGS(conn, proto_ctx);
874 if (server->config->param.key_exchange_pfs)
875 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
877 /* Perform key exchange protocol. silc_server_connect_to_router_second
878 will be called after the protocol is finished. */
879 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
880 &protocol, proto_ctx,
881 silc_server_connect_to_router_second);
882 newsocket->protocol = protocol;
884 /* Register a timeout task that will be executed if the protocol
885 is not executed within set limit. */
886 proto_ctx->timeout_task =
887 silc_schedule_task_add(server->schedule, sock,
888 silc_server_timeout_remote,
889 server, server->config->key_exchange_timeout, 0,
893 /* Register the connection for network input and output. This sets
894 that scheduler will listen for incoming packets for this connection
895 and sets that outgoing packets may be sent to this connection as
896 well. However, this doesn't set the scheduler for outgoing traffic,
897 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
898 later when outgoing data is available. */
899 context = (void *)server;
900 SILC_REGISTER_CONNECTION_FOR_IO(sock);
902 /* Run the protocol */
903 silc_protocol_execute(protocol, server->schedule, 0, 0);
906 /* Timeout callback that will be called to retry connecting to remote
907 router. This is used by both normal and router server. This will wait
908 before retrying the connecting. The timeout is generated by exponential
909 backoff algorithm. */
911 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
913 SilcServer server = app_context;
914 SilcServerConnection sconn = (SilcServerConnection)context;
915 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
916 SilcServerConfigConnParams *param =
917 (conn->param ? conn->param : &server->config->param);
919 /* Don't retry if we are shutting down. */
920 if (server->server_shutdown) {
921 silc_server_config_unref(&sconn->conn);
922 silc_free(sconn->remote_host);
923 silc_free(sconn->backup_replace_ip);
928 SILC_LOG_INFO(("Retrying connecting to a router"));
930 /* Calculate next timeout */
931 if (sconn->retry_count >= 1) {
932 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
933 if (sconn->retry_timeout > param->reconnect_interval_max)
934 sconn->retry_timeout = param->reconnect_interval_max;
936 sconn->retry_timeout = param->reconnect_interval;
938 sconn->retry_count++;
939 sconn->retry_timeout = sconn->retry_timeout +
940 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
942 /* If we've reached max retry count, give up. */
943 if ((sconn->retry_count > param->reconnect_count) &&
944 !param->reconnect_keep_trying) {
945 SILC_LOG_ERROR(("Could not connect to router, giving up"));
946 silc_server_config_unref(&sconn->conn);
947 silc_free(sconn->remote_host);
948 silc_free(sconn->backup_replace_ip);
953 SILC_LOG_DEBUG(("Retrying connecting to a router in %d seconds",
954 sconn->retry_timeout));
956 /* We will lookup a fresh pointer later */
957 silc_server_config_unref(&sconn->conn);
959 /* Wait one before retrying */
960 silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
961 context, sconn->retry_timeout, 0,
962 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
965 /* Generic routine to use connect to a router. */
967 SILC_TASK_CALLBACK(silc_server_connect_router)
969 SilcServer server = app_context;
970 SilcServerConnection sconn = (SilcServerConnection)context;
971 SilcServerConfigRouter *rconn;
974 /* Don't connect if we are shutting down. */
975 if (server->server_shutdown) {
976 silc_free(sconn->remote_host);
977 silc_free(sconn->backup_replace_ip);
982 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
983 (sconn->backup ? "backup router" : "router"),
984 sconn->remote_host, sconn->remote_port));
986 server->router_connect = time(NULL);
987 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
990 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
991 (sconn->backup ? "backup router" : "router"),
992 sconn->remote_host, sconn->remote_port));
993 silc_free(sconn->remote_host);
994 silc_free(sconn->backup_replace_ip);
998 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1000 /* Connect to remote host */
1001 sock = silc_net_create_connection(
1002 (!server->config->server_info->primary ? NULL :
1003 server->config->server_info->primary->server_ip),
1004 sconn->remote_port, sconn->remote_host);
1006 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1007 sconn->remote_host, sconn->remote_port));
1008 if (!sconn->no_reconnect)
1009 silc_schedule_task_add(server->schedule, 0,
1010 silc_server_connect_to_router_retry,
1011 context, 0, 1, SILC_TASK_TIMEOUT,
1012 SILC_TASK_PRI_NORMAL);
1014 silc_server_config_unref(&sconn->conn);
1015 silc_free(sconn->remote_host);
1016 silc_free(sconn->backup_replace_ip);
1022 /* Continue with key exchange protocol */
1023 silc_server_start_key_exchange(server, sconn, sock);
1026 /* This function connects to our primary router or if we are a router this
1027 establishes all our primary routes. This is called at the start of the
1028 server to do authentication and key exchange with our router - called
1031 SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router)
1033 SilcServer server = (SilcServer)context;
1034 SilcServerConnection sconn;
1035 SilcServerConfigRouter *ptr;
1037 /* Don't connect if we are shutting down. */
1038 if (server->server_shutdown)
1041 SILC_LOG_DEBUG(("We are %s",
1042 (server->server_type == SILC_SERVER ?
1043 "normal server" : server->server_type == SILC_ROUTER ?
1044 "router" : "backup router/normal server")));
1046 if (!server->config->routers) {
1047 /* There wasn't a configured router, we will continue but we don't
1048 have a connection to outside world. We will be standalone server. */
1049 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1050 server->standalone = TRUE;
1054 /* Cancel any possible retry timeouts */
1055 silc_schedule_task_del_by_callback(server->schedule,
1056 silc_server_connect_router);
1057 silc_schedule_task_del_by_callback(server->schedule,
1058 silc_server_connect_to_router_retry);
1060 /* Create the connections to all our routes */
1061 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1063 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1064 ptr->backup_router ? "Backup router" : "Router",
1065 ptr->initiator ? "Initiator" : "Responder",
1066 ptr->host, ptr->port));
1068 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1069 ptr->initiator == FALSE && !server->backup_router &&
1070 !silc_server_config_get_backup_router(server))
1071 server->wait_backup = TRUE;
1073 if (ptr->initiator) {
1074 /* Check whether we are connecting or connected to this host already */
1075 if (silc_server_num_sockets_by_remote(server,
1076 silc_net_is_ip(ptr->host) ?
1078 silc_net_is_ip(ptr->host) ?
1079 NULL : ptr->host, ptr->port,
1080 SILC_SOCKET_TYPE_ROUTER)) {
1081 SILC_LOG_DEBUG(("We are already connected to this router"));
1083 /* If we don't have primary router and this connection is our
1084 primary router we are in desync. Reconnect to the primary. */
1085 if (server->standalone && !server->router) {
1086 SilcServerConfigRouter *primary =
1087 silc_server_config_get_primary_router(server);
1088 if (primary == ptr) {
1089 SilcSocketConnection sock =
1090 silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_ROUTER,
1091 ptr->host, ptr->port);
1093 server->backup_noswitch = TRUE;
1094 if (sock->user_data)
1095 silc_server_free_sock_user_data(server, sock, NULL);
1096 silc_server_disconnect_remote(server, sock, 0, NULL);
1097 server->backup_noswitch = FALSE;
1098 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1109 if (silc_server_num_sockets_by_remote(server,
1110 silc_net_is_ip(ptr->host) ?
1112 silc_net_is_ip(ptr->host) ?
1113 NULL : ptr->host, ptr->port,
1114 SILC_SOCKET_TYPE_UNKNOWN)) {
1115 SILC_LOG_DEBUG(("We are already connecting to this router"));
1119 /* Allocate connection object for hold connection specific stuff. */
1120 sconn = silc_calloc(1, sizeof(*sconn));
1121 sconn->remote_host = strdup(ptr->host);
1122 sconn->remote_port = ptr->port;
1123 sconn->backup = ptr->backup_router;
1124 if (sconn->backup) {
1125 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1126 sconn->backup_replace_port = ptr->backup_replace_port;
1129 if (!server->router_conn && !sconn->backup)
1130 server->router_conn = sconn;
1132 silc_schedule_task_add(server->schedule, 0,
1133 silc_server_connect_router,
1134 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
1135 SILC_TASK_PRI_NORMAL);
1140 /* Second part of connecting to router(s). Key exchange protocol has been
1141 executed and now we will execute authentication protocol. */
1143 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
1145 SilcProtocol protocol = (SilcProtocol)context;
1146 SilcServerKEInternalContext *ctx =
1147 (SilcServerKEInternalContext *)protocol->context;
1148 SilcServer server = (SilcServer)ctx->server;
1149 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1150 SilcSocketConnection sock = ctx->sock;
1151 SilcServerConnAuthInternalContext *proto_ctx;
1152 SilcServerConfigRouter *conn = NULL;
1154 SILC_LOG_DEBUG(("Start"));
1156 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1157 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1158 /* Error occured during protocol */
1159 silc_protocol_free(protocol);
1160 sock->protocol = NULL;
1161 silc_ske_free_key_material(ctx->keymat);
1163 silc_packet_context_free(ctx->packet);
1165 silc_ske_free(ctx->ske);
1166 silc_free(ctx->dest_id);
1168 silc_server_disconnect_remote(server, sock,
1169 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1171 /* Try reconnecting if configuration wants it */
1172 if (!sconn->no_reconnect) {
1173 silc_schedule_task_add(server->schedule, 0,
1174 silc_server_connect_to_router_retry,
1175 sconn, 0, 1, SILC_TASK_TIMEOUT,
1176 SILC_TASK_PRI_NORMAL);
1180 /* Call completion to indicate error */
1181 if (sconn->callback)
1182 (*sconn->callback)(server, NULL, sconn->callback_context);
1184 silc_server_config_unref(&sconn->conn);
1185 silc_free(sconn->remote_host);
1186 silc_free(sconn->backup_replace_ip);
1191 /* We now have the key material as the result of the key exchange
1192 protocol. Take the key material into use. Free the raw key material
1193 as soon as we've set them into use. */
1194 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1195 ctx->sock, ctx->keymat,
1196 ctx->ske->prop->cipher,
1197 ctx->ske->prop->pkcs,
1198 ctx->ske->prop->hash,
1199 ctx->ske->prop->hmac,
1200 ctx->ske->prop->group,
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);
1233 silc_ske_free_key_material(ctx->keymat);
1235 /* Allocate internal context for the authentication protocol. This
1236 is sent as context for the protocol. */
1237 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1238 proto_ctx->server = (void *)server;
1239 proto_ctx->context = (void *)sconn;
1240 proto_ctx->sock = sock;
1241 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1242 proto_ctx->dest_id_type = ctx->dest_id_type;
1243 proto_ctx->dest_id = ctx->dest_id;
1245 /* Resolve the authentication method used in this connection. Check if
1246 we find a match from user configured connections */
1247 if (!sconn->conn.ref_ptr)
1248 conn = silc_server_config_find_router_conn(server, sock->hostname,
1251 conn = sconn->conn.ref_ptr;
1254 /* Match found. Use the configured authentication method. Take only
1255 the passphrase, since for public key auth we automatically use
1256 our local key pair. */
1257 if (conn->passphrase) {
1258 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1259 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
1261 proto_ctx->auth_data = strdup(conn->passphrase);
1262 proto_ctx->auth_data_len = strlen(conn->passphrase);
1263 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
1265 } else if (conn->publickeys) {
1266 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
1268 proto_ctx->auth_meth = SILC_AUTH_NONE;
1271 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
1272 sock->hostname, sock->ip, sock->port));
1273 silc_protocol_free(protocol);
1274 sock->protocol = NULL;
1276 silc_packet_context_free(ctx->packet);
1278 silc_ske_free(ctx->ske);
1279 silc_free(ctx->dest_id);
1281 silc_server_config_unref(&sconn->conn);
1282 silc_free(sconn->remote_host);
1283 silc_free(sconn->backup_replace_ip);
1285 silc_server_disconnect_remote(server, sock,
1286 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1290 /* Free old protocol as it is finished now */
1291 silc_protocol_free(protocol);
1293 silc_packet_context_free(ctx->packet);
1295 sock->protocol = NULL;
1297 /* Allocate the authentication protocol. This is allocated here
1298 but we won't start it yet. We will be receiving party of this
1299 protocol thus we will wait that connecting party will make
1300 their first move. */
1301 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1302 &sock->protocol, proto_ctx,
1303 silc_server_connect_to_router_final);
1305 /* Register timeout task. If the protocol is not executed inside
1306 this timelimit the connection will be terminated. */
1307 proto_ctx->timeout_task =
1308 silc_schedule_task_add(server->schedule, sock->sock,
1309 silc_server_timeout_remote,
1311 server->config->conn_auth_timeout, 0,
1315 /* Run the protocol */
1316 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1319 /* Finalizes the connection to router. Registers a server task to the
1320 queue so that we can accept new connections. */
1322 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
1324 SilcProtocol protocol = (SilcProtocol)context;
1325 SilcServerConnAuthInternalContext *ctx =
1326 (SilcServerConnAuthInternalContext *)protocol->context;
1327 SilcServer server = (SilcServer)ctx->server;
1328 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
1329 SilcSocketConnection sock = ctx->sock;
1330 SilcServerEntry id_entry = NULL;
1332 unsigned char *id_string;
1334 SilcIDListData idata;
1335 SilcServerConfigRouter *conn = NULL;
1336 SilcServerConfigConnParams *param = NULL;
1338 SILC_LOG_DEBUG(("Start"));
1340 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1341 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1342 /* Error occured during protocol */
1343 silc_free(ctx->dest_id);
1344 sock->protocol = NULL;
1345 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1347 sock->protocol = protocol;
1349 /* Try reconnecting if configuration wants it */
1350 if (!sconn->no_reconnect) {
1351 silc_schedule_task_add(server->schedule, 0,
1352 silc_server_connect_to_router_retry,
1353 sconn, 0, 1, SILC_TASK_TIMEOUT,
1354 SILC_TASK_PRI_NORMAL);
1361 /* Add a task to the queue. This task receives new connections to the
1362 server. This task remains on the queue until the end of the program. */
1363 if (!server->listenning && !sconn->backup) {
1364 silc_schedule_task_add(server->schedule, server->sock,
1365 silc_server_accept_new_connection,
1366 (void *)server, 0, 0,
1368 SILC_TASK_PRI_NORMAL);
1369 server->listenning = TRUE;
1372 /* Send NEW_SERVER packet to the router. We will become registered
1373 to the SILC network after sending this packet. */
1374 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
1375 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
1376 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
1377 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1378 silc_buffer_format(packet,
1379 SILC_STR_UI_SHORT(id_len),
1380 SILC_STR_UI_XNSTRING(id_string, id_len),
1381 SILC_STR_UI_SHORT(strlen(server->server_name)),
1382 SILC_STR_UI_XNSTRING(server->server_name,
1383 strlen(server->server_name)),
1386 /* Send the packet */
1387 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
1388 packet->data, packet->len, TRUE);
1389 silc_buffer_free(packet);
1390 silc_free(id_string);
1392 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
1394 /* Check that we do not have this ID already */
1395 id_entry = silc_idlist_find_server_by_id(server->local_list,
1396 ctx->dest_id, TRUE, NULL);
1398 silc_idcache_del_by_context(server->local_list->servers, id_entry);
1400 id_entry = silc_idlist_find_server_by_id(server->global_list,
1401 ctx->dest_id, TRUE, NULL);
1403 silc_idcache_del_by_context(server->global_list->servers, id_entry);
1406 SILC_LOG_DEBUG(("New server id(%s)",
1407 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
1409 /* Add the connected router to global server list. Router is sent
1410 as NULL since it's local to us. */
1411 id_entry = silc_idlist_add_server(server->global_list,
1412 strdup(sock->hostname),
1413 SILC_ROUTER, ctx->dest_id, NULL, sock);
1415 silc_free(ctx->dest_id);
1416 SILC_LOG_ERROR(("Cannot add new server entry to cache"));
1417 sock->protocol = NULL;
1418 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1420 sock->protocol = protocol;
1424 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1425 silc_free(sock->user_data);
1426 sock->user_data = (void *)id_entry;
1427 sock->type = SILC_SOCKET_TYPE_ROUTER;
1428 idata = (SilcIDListData)sock->user_data;
1429 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1430 SILC_IDLIST_STATUS_LOCAL);
1432 conn = sconn->conn.ref_ptr;
1433 param = &server->config->param;
1434 if (conn && conn->param)
1435 param = conn->param;
1437 /* Perform keepalive. */
1438 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
1439 silc_server_perform_heartbeat,
1442 /* Register re-key timeout */
1443 idata->rekey->timeout = param->key_exchange_rekey;
1444 silc_schedule_task_add(server->schedule, sock->sock,
1445 silc_server_rekey_callback,
1446 (void *)sock, idata->rekey->timeout, 0,
1447 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1449 if (!sconn->backup) {
1450 /* Mark this router our primary router if we're still standalone */
1451 if (server->standalone) {
1452 SILC_LOG_DEBUG(("This connection is our primary router"));
1453 server->id_entry->router = id_entry;
1454 server->router = id_entry;
1455 server->router->server_type = SILC_ROUTER;
1456 server->standalone = FALSE;
1457 server->backup_primary = FALSE;
1459 /* Announce data if we are not backup router (unless not as primary
1460 currently). Backup router announces later at the end of
1461 resuming protocol. */
1462 if (server->backup_router && server->server_type == SILC_ROUTER) {
1463 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1465 /* If we are router then announce our possible servers. Backup
1466 router announces also global servers. */
1467 if (server->server_type == SILC_ROUTER)
1468 silc_server_announce_servers(server,
1469 server->backup_router ? TRUE : FALSE,
1470 0, SILC_PRIMARY_ROUTE(server));
1472 /* Announce our clients and channels to the router */
1473 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1474 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1477 /* If we are backup router then this primary router is whom we are
1479 if (server->server_type == SILC_BACKUP_ROUTER)
1480 silc_server_backup_add(server, server->id_entry, sock->ip,
1481 sconn->remote_port, TRUE);
1484 /* Add this server to be our backup router */
1485 id_entry->server_type = SILC_BACKUP_ROUTER;
1486 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1487 sconn->backup_replace_port, FALSE);
1490 sock->protocol = NULL;
1493 /* Call the completion callback to indicate that we've connected to
1495 if (sconn && sconn->callback)
1496 (*sconn->callback)(server, id_entry, sconn->callback_context);
1498 /* Free the temporary connection data context */
1500 silc_server_config_unref(&sconn->conn);
1501 silc_free(sconn->remote_host);
1502 silc_free(sconn->backup_replace_ip);
1505 if (sconn == server->router_conn)
1506 server->router_conn = NULL;
1509 /* Free the protocol object */
1510 if (sock->protocol == protocol)
1511 sock->protocol = NULL;
1512 silc_protocol_free(protocol);
1514 silc_packet_context_free(ctx->packet);
1516 silc_ske_free(ctx->ske);
1517 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1518 silc_free(ctx->auth_data);
1522 /* Host lookup callback that is called after the incoming connection's
1523 IP and FQDN lookup is performed. This will actually check the acceptance
1524 of the incoming connection and will register the key exchange protocol
1525 for this connection. */
1528 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1531 SilcServerKEInternalContext *proto_ctx =
1532 (SilcServerKEInternalContext *)context;
1533 SilcServer server = (SilcServer)proto_ctx->server;
1534 SilcServerConfigClient *cconfig = NULL;
1535 SilcServerConfigServer *sconfig = NULL;
1536 SilcServerConfigRouter *rconfig = NULL;
1537 SilcServerConfigDeny *deny;
1540 /* Check whether we could resolve both IP and FQDN. */
1541 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1542 server->config->require_reverse_lookup)) {
1543 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1544 sock->hostname ? sock->hostname :
1545 sock->ip ? sock->ip : ""));
1546 server->stat.conn_failures++;
1547 silc_server_disconnect_remote(server, sock,
1548 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1549 "Unknown host or IP");
1550 silc_free(proto_ctx);
1554 /* Register the connection for network input and output. This sets
1555 that scheduler will listen for incoming packets for this connection
1556 and sets that outgoing packets may be sent to this connection as well.
1557 However, this doesn't set the scheduler for outgoing traffic, it
1558 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1559 later when outgoing data is available. */
1560 context = (void *)server;
1561 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1563 SILC_LOG_INFO(("Incoming connection %s (%s)", sock->hostname,
1566 /* Listenning port */
1567 if (!server->sockets[(SilcUInt32)proto_ctx->context]) {
1568 silc_server_disconnect_remote(server, sock,
1569 SILC_STATUS_ERR_RESOURCE_LIMIT,
1570 "Connection refused");
1571 server->stat.conn_failures++;
1572 silc_free(proto_ctx);
1575 port = server->sockets[(SilcUInt32)proto_ctx->context]->port;
1577 /* Check whether this connection is denied to connect to us. */
1578 deny = silc_server_config_find_denied(server, sock->ip);
1580 deny = silc_server_config_find_denied(server, sock->hostname);
1582 /* The connection is denied */
1583 SILC_LOG_INFO(("Connection %s (%s) is denied",
1584 sock->hostname, sock->ip));
1585 silc_server_disconnect_remote(server, sock,
1586 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1588 server->stat.conn_failures++;
1589 silc_free(proto_ctx);
1593 /* Check whether we have configured this sort of connection at all. We
1594 have to check all configurations since we don't know what type of
1595 connection this is. */
1596 if (!(cconfig = silc_server_config_find_client(server, sock->ip)))
1597 cconfig = silc_server_config_find_client(server, sock->hostname);
1598 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1599 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1600 if (server->server_type == SILC_ROUTER) {
1601 if (!(rconfig = silc_server_config_find_router_conn(server,
1602 sock->ip, sock->port)))
1603 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1606 if (!cconfig && !sconfig && !rconfig) {
1607 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1609 silc_server_disconnect_remote(server, sock,
1610 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
1611 server->stat.conn_failures++;
1612 silc_free(proto_ctx);
1616 /* The connection is allowed */
1618 /* Set internal context for key exchange protocol. This is
1619 sent as context for the protocol. */
1620 proto_ctx->sock = sock;
1621 proto_ctx->rng = server->rng;
1622 proto_ctx->responder = TRUE;
1623 silc_server_config_ref(&proto_ctx->cconfig, server->config, cconfig);
1624 silc_server_config_ref(&proto_ctx->sconfig, server->config, sconfig);
1625 silc_server_config_ref(&proto_ctx->rconfig, server->config, rconfig);
1627 /* Take flags for key exchange. Since we do not know what type of connection
1628 this is, we go through all found configurations and use the global ones
1629 as well. This will result always into strictest key exchange flags. */
1630 SILC_GET_SKE_FLAGS(cconfig, proto_ctx);
1631 SILC_GET_SKE_FLAGS(sconfig, proto_ctx);
1632 SILC_GET_SKE_FLAGS(rconfig, proto_ctx);
1633 if (server->config->param.key_exchange_pfs)
1634 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
1636 /* Prepare the connection for key exchange protocol. We allocate the
1637 protocol but will not start it yet. The connector will be the
1638 initiator of the protocol thus we will wait for initiation from
1639 there before we start the protocol. */
1640 server->stat.auth_attempts++;
1641 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1642 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1643 &sock->protocol, proto_ctx,
1644 silc_server_accept_new_connection_second);
1646 /* Register a timeout task that will be executed if the connector
1647 will not start the key exchange protocol within specified timeout
1648 and the connection will be closed. */
1649 proto_ctx->timeout_task =
1650 silc_schedule_task_add(server->schedule, sock->sock,
1651 silc_server_timeout_remote,
1653 server->config->key_exchange_timeout, 0,
1658 /* Accepts new connections to the server. Accepting new connections are
1659 done in three parts to make it async. */
1661 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1663 SilcServer server = (SilcServer)context;
1664 SilcSocketConnection newsocket;
1665 SilcServerKEInternalContext *proto_ctx;
1668 SILC_LOG_DEBUG(("Accepting new connection"));
1670 server->stat.conn_attempts++;
1672 sock = silc_net_accept_connection(fd);
1674 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1675 server->stat.conn_failures++;
1679 /* Check for maximum allowed connections */
1680 if (sock > server->config->param.connections_max) {
1681 SILC_LOG_ERROR(("Refusing connection, server is full"));
1682 server->stat.conn_failures++;
1683 silc_net_close_connection(sock);
1687 /* Set socket options */
1688 silc_net_set_socket_nonblock(sock);
1689 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1691 /* We don't create a ID yet, since we don't know what type of connection
1692 this is yet. But, we do add the connection to the socket table. */
1693 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1694 server->sockets[sock] = newsocket;
1696 /* Perform asynchronous host lookup. This will lookup the IP and the
1697 FQDN of the remote connection. After the lookup is done the connection
1698 is accepted further. */
1699 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1700 proto_ctx->server = server;
1701 proto_ctx->context = (void *)fd;
1702 silc_socket_host_lookup(newsocket, TRUE,
1703 silc_server_accept_new_connection_lookup,
1704 (void *)proto_ctx, server->schedule);
1707 /* Second part of accepting new connection. Key exchange protocol has been
1708 performed and now it is time to do little connection authentication
1709 protocol to figure out whether this connection is client or server
1710 and whether it has right to access this server (especially server
1711 connections needs to be authenticated). */
1713 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1715 SilcProtocol protocol = (SilcProtocol)context;
1716 SilcServerKEInternalContext *ctx =
1717 (SilcServerKEInternalContext *)protocol->context;
1718 SilcServer server = (SilcServer)ctx->server;
1719 SilcSocketConnection sock = ctx->sock;
1720 SilcServerConnAuthInternalContext *proto_ctx;
1722 SILC_LOG_DEBUG(("Start"));
1724 if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
1725 (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
1726 /* Error occured during protocol */
1727 SILC_LOG_DEBUG(("Error in key exchange protocol"));
1728 silc_protocol_free(protocol);
1729 sock->protocol = NULL;
1730 silc_ske_free_key_material(ctx->keymat);
1732 silc_packet_context_free(ctx->packet);
1734 silc_ske_free(ctx->ske);
1735 silc_free(ctx->dest_id);
1736 silc_server_config_unref(&ctx->cconfig);
1737 silc_server_config_unref(&ctx->sconfig);
1738 silc_server_config_unref(&ctx->rconfig);
1741 if (!SILC_IS_DISCONNECTING(sock)) {
1742 SILC_LOG_INFO(("Key exchange failed for %s:%d [%s]", sock->hostname,
1744 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1745 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1746 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1748 silc_server_disconnect_remote(server, sock,
1749 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
1753 server->stat.auth_failures++;
1757 /* We now have the key material as the result of the key exchange
1758 protocol. Take the key material into use. Free the raw key material
1759 as soon as we've set them into use. */
1760 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1761 ctx->sock, ctx->keymat,
1762 ctx->ske->prop->cipher,
1763 ctx->ske->prop->pkcs,
1764 ctx->ske->prop->hash,
1765 ctx->ske->prop->hmac,
1766 ctx->ske->prop->group,
1768 SILC_LOG_ERROR(("Error setting key material in use"));
1769 silc_protocol_free(protocol);
1770 sock->protocol = NULL;
1771 silc_ske_free_key_material(ctx->keymat);
1773 silc_packet_context_free(ctx->packet);
1775 silc_ske_free(ctx->ske);
1776 silc_free(ctx->dest_id);
1777 silc_server_config_unref(&ctx->cconfig);
1778 silc_server_config_unref(&ctx->sconfig);
1779 silc_server_config_unref(&ctx->rconfig);
1781 silc_server_disconnect_remote(server, sock,
1782 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1783 server->stat.auth_failures++;
1786 silc_ske_free_key_material(ctx->keymat);
1788 /* Allocate internal context for the authentication protocol. This
1789 is sent as context for the protocol. */
1790 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1791 proto_ctx->server = (void *)server;
1792 proto_ctx->sock = sock;
1793 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1794 proto_ctx->responder = TRUE;
1795 proto_ctx->dest_id_type = ctx->dest_id_type;
1796 proto_ctx->dest_id = ctx->dest_id;
1797 proto_ctx->cconfig = ctx->cconfig;
1798 proto_ctx->sconfig = ctx->sconfig;
1799 proto_ctx->rconfig = ctx->rconfig;
1801 /* Free old protocol as it is finished now */
1802 silc_protocol_free(protocol);
1804 silc_packet_context_free(ctx->packet);
1806 sock->protocol = NULL;
1808 /* Allocate the authentication protocol. This is allocated here
1809 but we won't start it yet. We will be receiving party of this
1810 protocol thus we will wait that connecting party will make
1811 their first move. */
1812 SILC_LOG_DEBUG(("Starting connection authentication protocol"));
1813 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1814 &sock->protocol, proto_ctx,
1815 silc_server_accept_new_connection_final);
1817 /* Register timeout task. If the protocol is not executed inside
1818 this timelimit the connection will be terminated. */
1819 proto_ctx->timeout_task =
1820 silc_schedule_task_add(server->schedule, sock->sock,
1821 silc_server_timeout_remote,
1823 server->config->conn_auth_timeout, 0,
1828 /* After this is called, server don't wait for backup router anymore.
1829 This gets called automatically even after we have backup router
1830 connection established. */
1832 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
1834 SilcServer server = context;
1835 server->wait_backup = FALSE;
1838 /* Final part of accepting new connection. The connection has now
1839 been authenticated and keys has been exchanged. We also know whether
1840 this is client or server connection. */
1842 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1844 SilcProtocol protocol = (SilcProtocol)context;
1845 SilcServerConnAuthInternalContext *ctx =
1846 (SilcServerConnAuthInternalContext *)protocol->context;
1847 SilcServer server = (SilcServer)ctx->server;
1848 SilcSocketConnection sock = ctx->sock;
1849 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1851 SilcServerConfigConnParams *param = &server->config->param;
1853 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1854 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1855 /* Error occured during protocol */
1856 SILC_LOG_DEBUG(("Error during authentication protocol"));
1857 silc_protocol_free(protocol);
1858 sock->protocol = NULL;
1860 silc_packet_context_free(ctx->packet);
1862 silc_ske_free(ctx->ske);
1863 silc_free(ctx->dest_id);
1864 silc_server_config_unref(&ctx->cconfig);
1865 silc_server_config_unref(&ctx->sconfig);
1866 silc_server_config_unref(&ctx->rconfig);
1869 if (!SILC_IS_DISCONNECTING(sock)) {
1870 SILC_LOG_INFO(("Authentication failed for %s:%d [%s]", sock->hostname,
1872 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1873 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1874 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1876 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1879 server->stat.auth_failures++;
1883 entry->data.last_receive = time(NULL);
1885 switch (ctx->conn_type) {
1886 case SILC_SOCKET_TYPE_CLIENT:
1888 SilcClientEntry client;
1889 SilcServerConfigClient *conn = ctx->cconfig.ref_ptr;
1891 /* Verify whether this connection is after all allowed to connect */
1892 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1893 &server->config->param,
1894 conn->param, ctx->ske)) {
1895 server->stat.auth_failures++;
1899 /* If we are primary router and we have backup router configured
1900 but it has not connected to use yet, do not accept any other
1902 if (server->wait_backup && server->server_type == SILC_ROUTER &&
1903 !server->backup_router) {
1904 SilcServerConfigRouter *router;
1905 router = silc_server_config_get_backup_router(server);
1906 if (router && strcmp(server->config->server_info->primary->server_ip,
1908 silc_server_find_socket_by_host(server,
1909 SILC_SOCKET_TYPE_SERVER,
1910 router->backup_replace_ip, 0)) {
1911 SILC_LOG_INFO(("Will not accept connections because we do "
1912 "not have backup router connection established"));
1913 sock->protocol = NULL;
1914 silc_server_disconnect_remote(server, sock,
1915 SILC_STATUS_ERR_PERM_DENIED,
1916 "We do not have connection to backup "
1917 "router established, try later");
1918 silc_free(sock->user_data);
1919 server->stat.auth_failures++;
1921 /* From here on, wait 20 seconds for the backup router to appear. */
1922 silc_schedule_task_add(server->schedule, 0,
1923 silc_server_backup_router_wait,
1924 (void *)server, 20, 0,
1925 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1930 SILC_LOG_DEBUG(("Remote host is client"));
1931 SILC_LOG_INFO(("Connection %s (%s) is client", sock->hostname,
1934 /* Add the client to the client ID cache. The nickname and Client ID
1935 and other information is created after we have received NEW_CLIENT
1936 packet from client. */
1937 client = silc_idlist_add_client(server->local_list,
1938 NULL, NULL, NULL, NULL, NULL, sock, 0);
1940 SILC_LOG_ERROR(("Could not add new client to cache"));
1941 silc_free(sock->user_data);
1942 sock->protocol = NULL;
1943 silc_server_disconnect_remote(server, sock,
1944 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1945 server->stat.auth_failures++;
1948 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1951 server->stat.my_clients++;
1952 server->stat.clients++;
1953 server->stat.cell_clients++;
1955 /* Get connection parameters */
1957 param = conn->param;
1959 if (!param->keepalive_secs)
1960 param->keepalive_secs = server->config->param.keepalive_secs;
1962 if (!param->qos && server->config->param.qos) {
1963 param->qos = server->config->param.qos;
1964 param->qos_rate_limit = server->config->param.qos_rate_limit;
1965 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
1966 param->qos_limit_sec = server->config->param.qos_limit_sec;
1967 param->qos_limit_usec = server->config->param.qos_limit_usec;
1970 /* Check if to be anonymous connection */
1971 if (param->anonymous)
1972 client->mode |= SILC_UMODE_ANONYMOUS;
1975 /* Add public key to hash list (for whois using attributes) */
1976 silc_hash_table_add(server->pk_hash,
1977 entry->data.public_key, client);
1979 id_entry = (void *)client;
1982 case SILC_SOCKET_TYPE_SERVER:
1983 case SILC_SOCKET_TYPE_ROUTER:
1985 SilcServerEntry new_server;
1986 bool initiator = FALSE;
1987 bool backup_local = FALSE;
1988 bool backup_router = FALSE;
1989 char *backup_replace_ip = NULL;
1990 SilcUInt16 backup_replace_port = 0;
1991 SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
1992 SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
1994 /* If we are backup router and this is incoming server connection
1995 and we do not have connection to primary router, do not allow
1997 if (server->server_type == SILC_BACKUP_ROUTER &&
1998 ctx->conn_type == SILC_SOCKET_TYPE_SERVER &&
1999 !SILC_PRIMARY_ROUTE(server)) {
2000 SILC_LOG_INFO(("Will not accept server connection because we do "
2001 "not have primary router connection established"));
2002 sock->protocol = NULL;
2003 silc_server_disconnect_remote(server, sock,
2004 SILC_STATUS_ERR_PERM_DENIED,
2005 "We do not have connection to primary "
2006 "router established, try later");
2007 silc_free(sock->user_data);
2008 server->stat.auth_failures++;
2012 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
2013 /* Verify whether this connection is after all allowed to connect */
2014 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
2015 &server->config->param,
2016 rconn ? rconn->param : NULL,
2018 silc_free(sock->user_data);
2019 server->stat.auth_failures++;
2025 param = rconn->param;
2027 if (!param->keepalive_secs)
2028 param->keepalive_secs = server->config->param.keepalive_secs;
2030 if (!param->qos && server->config->param.qos) {
2031 param->qos = server->config->param.qos;
2032 param->qos_rate_limit = server->config->param.qos_rate_limit;
2033 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2034 param->qos_limit_sec = server->config->param.qos_limit_sec;
2035 param->qos_limit_usec = server->config->param.qos_limit_usec;
2039 initiator = rconn->initiator;
2040 backup_local = rconn->backup_local;
2041 backup_router = rconn->backup_router;
2042 backup_replace_ip = rconn->backup_replace_ip;
2043 backup_replace_port = rconn->backup_replace_port;
2047 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
2048 /* Verify whether this connection is after all allowed to connect */
2049 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
2050 &server->config->param,
2051 sconn ? sconn->param : NULL,
2053 silc_free(sock->user_data);
2054 server->stat.auth_failures++;
2059 param = sconn->param;
2061 if (!param->keepalive_secs)
2062 param->keepalive_secs = server->config->param.keepalive_secs;
2064 if (!param->qos && server->config->param.qos) {
2065 param->qos = server->config->param.qos;
2066 param->qos_rate_limit = server->config->param.qos_rate_limit;
2067 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2068 param->qos_limit_sec = server->config->param.qos_limit_sec;
2069 param->qos_limit_usec = server->config->param.qos_limit_usec;
2073 backup_router = sconn->backup_router;
2077 /* If we are primary router and we have backup router configured
2078 but it has not connected to use yet, do not accept any other
2080 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2081 !server->backup_router && !backup_router) {
2082 SilcServerConfigRouter *router;
2083 router = silc_server_config_get_backup_router(server);
2084 if (router && strcmp(server->config->server_info->primary->server_ip,
2086 silc_server_find_socket_by_host(server,
2087 SILC_SOCKET_TYPE_SERVER,
2088 router->backup_replace_ip, 0)) {
2089 SILC_LOG_INFO(("Will not accept connections because we do "
2090 "not have backup router connection established"));
2091 sock->protocol = NULL;
2092 silc_server_disconnect_remote(server, sock,
2093 SILC_STATUS_ERR_PERM_DENIED,
2094 "We do not have connection to backup "
2095 "router established, try later");
2096 silc_free(sock->user_data);
2097 server->stat.auth_failures++;
2099 /* From here on, wait 20 seconds for the backup router to appear. */
2100 silc_schedule_task_add(server->schedule, 0,
2101 silc_server_backup_router_wait,
2102 (void *)server, 20, 0,
2103 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2108 SILC_LOG_DEBUG(("Remote host is %s",
2109 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2110 "server" : (backup_router ?
2111 "backup router" : "router")));
2112 SILC_LOG_INFO(("Connection %s (%s) is %s", sock->hostname,
2113 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2114 "server" : (backup_router ?
2115 "backup router" : "router")));
2117 /* Add the server into server cache. The server name and Server ID
2118 is updated after we have received NEW_SERVER packet from the
2119 server. We mark ourselves as router for this server if we really
2122 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2123 server->local_list : (backup_router ?
2124 server->local_list :
2125 server->global_list)),
2127 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2128 SILC_SERVER : SILC_ROUTER),
2130 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
2131 server->id_entry : (backup_router ?
2132 server->id_entry : NULL)),
2135 SILC_LOG_ERROR(("Could not add new server to cache"));
2136 silc_free(sock->user_data);
2137 sock->protocol = NULL;
2138 silc_server_disconnect_remote(server, sock,
2139 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2140 server->stat.auth_failures++;
2143 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2145 id_entry = (void *)new_server;
2147 /* If the incoming connection is router and marked as backup router
2148 then add it to be one of our backups */
2149 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
2150 /* Change it back to SERVER type since that's what it really is. */
2152 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
2153 new_server->server_type = SILC_BACKUP_ROUTER;
2155 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2156 ("Backup router %s is now online",
2159 /* Remove the backup waiting with timeout */
2160 silc_schedule_task_add(server->schedule, 0,
2161 silc_server_backup_router_wait,
2162 (void *)server, 10, 0,
2163 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2167 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
2168 server->stat.my_servers++;
2170 server->stat.my_routers++;
2171 server->stat.routers++;
2173 server->stat.servers++;
2175 /* Check whether this connection is to be our primary router connection
2176 if we do not already have the primary route. */
2177 if (!backup_router &&
2178 server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
2179 if (silc_server_config_is_primary_route(server) && !initiator)
2182 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2183 server->standalone = FALSE;
2184 if (!server->id_entry->router) {
2185 server->id_entry->router = id_entry;
2186 server->router = id_entry;
2197 sock->type = ctx->conn_type;
2199 /* Add the common data structure to the ID entry. */
2200 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
2202 /* Add to sockets internal pointer for fast referencing */
2203 silc_free(sock->user_data);
2204 sock->user_data = id_entry;
2206 /* Connection has been fully established now. Everything is ok. */
2207 SILC_LOG_DEBUG(("New connection authenticated"));
2209 /* Perform keepalive. */
2210 if (param->keepalive_secs)
2211 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
2212 silc_server_perform_heartbeat,
2215 /* Perform Quality of Service */
2217 silc_socket_set_qos(sock, param->qos_rate_limit, param->qos_bytes_limit,
2218 param->qos_limit_sec, param->qos_limit_usec,
2222 if (sock->protocol == protocol)
2223 silc_protocol_free(protocol);
2225 silc_packet_context_free(ctx->packet);
2227 silc_ske_free(ctx->ske);
2228 silc_free(ctx->dest_id);
2229 silc_server_config_unref(&ctx->cconfig);
2230 silc_server_config_unref(&ctx->sconfig);
2231 silc_server_config_unref(&ctx->rconfig);
2233 sock->protocol = NULL;
2236 /* This function is used to read packets from network and send packets to
2237 network. This is usually a generic task. */
2239 SILC_TASK_CALLBACK(silc_server_packet_process)
2241 SilcServer server = (SilcServer)context;
2242 SilcSocketConnection sock = server->sockets[fd];
2243 SilcIDListData idata;
2244 SilcCipher cipher = NULL;
2245 SilcHmac hmac = NULL;
2246 SilcUInt32 sequence = 0;
2247 bool local_is_router;
2251 SILC_LOG_DEBUG(("Unknown socket connection"));
2255 /* Packet sending */
2257 if (type == SILC_TASK_WRITE) {
2258 /* Do not send data to disconnected connection */
2259 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2260 SILC_LOG_DEBUG(("Disconnected socket connection, cannot send"));
2261 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
2262 SILC_UNSET_OUTBUF_PENDING(sock);
2263 silc_buffer_clear(sock->outbuf);
2267 server->stat.packets_sent++;
2269 /* Send the packet */
2270 ret = silc_packet_send(sock, TRUE);
2272 /* If returned -2 could not write to connection now, will do
2277 /* The packet has been sent and now it is time to set the connection
2278 back to only for input. When there is again some outgoing data
2279 available for this connection it will be set for output as well.
2280 This call clears the output setting and sets it only for input. */
2281 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
2282 SILC_UNSET_OUTBUF_PENDING(sock);
2283 silc_buffer_clear(sock->outbuf);
2286 SILC_LOG_ERROR(("Error sending packet to connection "
2287 "%s:%d [%s]", sock->hostname, sock->port,
2288 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2289 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2290 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2293 if (sock->user_data) {
2294 /* If backup then mark that resuming will not be allowed */
2295 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2296 sock->type == SILC_SOCKET_TYPE_SERVER) {
2297 SilcServerEntry server_entry = sock->user_data;
2298 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2299 server->backup_closed = TRUE;
2302 silc_server_free_sock_user_data(server, sock, NULL);
2304 SILC_SET_DISCONNECTING(sock);
2305 silc_server_close_connection(server, sock);
2310 /* Packet receiving */
2312 /* Read some data from connection */
2313 ret = silc_packet_receive(sock);
2317 SILC_LOG_ERROR(("Error receiving packet from connection "
2318 "%s:%d [%s] %s", sock->hostname, sock->port,
2319 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2320 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2321 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2322 "Router"), strerror(errno)));
2324 if (sock->user_data) {
2325 /* If backup then mark that resuming will not be allowed */
2326 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2327 sock->type == SILC_SOCKET_TYPE_SERVER) {
2328 SilcServerEntry server_entry = sock->user_data;
2329 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2330 server->backup_closed = TRUE;
2333 silc_server_free_sock_user_data(server, sock, NULL);
2335 SILC_SET_DISCONNECTING(sock);
2336 silc_server_close_connection(server, sock);
2343 SILC_LOG_DEBUG(("Read EOF"));
2345 /* If connection is disconnecting already we will finally
2346 close the connection */
2347 if (SILC_IS_DISCONNECTING(sock)) {
2348 if (sock->user_data)
2349 silc_server_free_sock_user_data(server, sock, NULL);
2350 silc_server_close_connection(server, sock);
2354 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
2356 if (sock->user_data) {
2359 /* If backup disconnected then mark that resuming will not be allowed */
2360 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2361 sock->type == SILC_SOCKET_TYPE_SERVER && sock->user_data) {
2362 SilcServerEntry server_entry = sock->user_data;
2363 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2364 server->backup_closed = TRUE;
2367 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
2368 silc_server_free_sock_user_data(server, sock, tmp);
2370 silc_server_free_sock_user_data(server, sock, NULL);
2371 } else if (server->router_conn && server->router_conn->sock == sock &&
2372 !server->router && server->standalone) {
2373 silc_server_create_connections(server);
2376 SILC_SET_DISCONNECTING(sock);
2377 silc_server_close_connection(server, sock);
2381 /* If connection is disconnecting or disconnected we will ignore
2383 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2384 SILC_LOG_DEBUG(("Ignoring read data from disconnected connection"));
2388 /* Get keys and stuff from ID entry */
2389 idata = (SilcIDListData)sock->user_data;
2391 cipher = idata->receive_key;
2392 hmac = idata->hmac_receive;
2393 sequence = idata->psn_receive;
2396 /* Then, process the packet. This will call the parser that will then
2397 decrypt and parse the packet. */
2399 local_is_router = (server->server_type == SILC_ROUTER);
2401 /* If socket connection is our primary, we are backup and we are doing
2402 backup resuming, we won't process the packet as being a router
2403 (affects channel message decryption). */
2404 if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
2405 SILC_PRIMARY_ROUTE(server) == sock)
2406 local_is_router = FALSE;
2408 ret = silc_packet_receive_process(sock, local_is_router,
2409 cipher, hmac, sequence,
2410 silc_server_packet_parse, server);
2412 /* If processing failed the connection is closed. */
2414 /* On packet processing errors we may close our primary router
2415 connection but won't become primary router if we are the backup
2416 since this is local error condition. */
2417 if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
2418 server->backup_noswitch = TRUE;
2420 if (sock->user_data) {
2421 /* If we are router and backup errorred then mark that resuming
2422 will not be allowed */
2423 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2424 sock->type == SILC_SOCKET_TYPE_SERVER) {
2425 SilcServerEntry server_entry = sock->user_data;
2426 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2427 server->backup_closed = TRUE;
2430 silc_server_free_sock_user_data(server, sock, NULL);
2432 SILC_SET_DISCONNECTING(sock);
2433 silc_server_close_connection(server, sock);
2437 /* Parses whole packet, received earlier. */
2439 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
2441 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
2442 SilcServer server = (SilcServer)parse_ctx->context;
2443 SilcSocketConnection sock = parse_ctx->sock;
2444 SilcPacketContext *packet = parse_ctx->packet;
2445 SilcIDListData idata = (SilcIDListData)sock->user_data;
2448 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2449 SILC_LOG_DEBUG(("Connection is disconnected"));
2453 server->stat.packets_received++;
2455 /* Parse the packet */
2456 if (parse_ctx->normal)
2457 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
2459 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
2461 /* If entry is disabled ignore what we got. */
2462 if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
2463 ret != SILC_PACKET_HEARTBEAT && ret != SILC_PACKET_RESUME_ROUTER &&
2464 ret != SILC_PACKET_REKEY && ret != SILC_PACKET_REKEY_DONE) {
2465 SILC_LOG_DEBUG(("Connection is disabled"));
2469 if (ret == SILC_PACKET_NONE) {
2470 SILC_LOG_DEBUG(("Error parsing packet"));
2474 /* Check that the the current client ID is same as in the client's packet. */
2475 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2476 SilcClientEntry client = (SilcClientEntry)sock->user_data;
2477 if (client && client->id && packet->src_id) {
2478 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
2479 packet->src_id_type);
2480 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
2482 SILC_LOG_DEBUG(("Packet source is not same as sender"));
2489 if (server->server_type == SILC_ROUTER) {
2490 /* Route the packet if it is not destined to us. Other ID types but
2491 server are handled separately after processing them. */
2492 if (packet->dst_id && !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
2493 packet->dst_id_type == SILC_ID_SERVER &&
2494 sock->type != SILC_SOCKET_TYPE_CLIENT &&
2495 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
2497 /* Route the packet to fastest route for the destination ID */
2498 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
2499 packet->dst_id_type);
2502 silc_server_packet_route(server,
2503 silc_server_route_get(server, id,
2504 packet->dst_id_type),
2511 /* Parse the incoming packet type */
2512 silc_server_packet_parse_type(server, sock, packet);
2514 /* Broadcast packet if it is marked as broadcast packet and it is
2515 originated from router and we are router. */
2516 if (server->server_type == SILC_ROUTER &&
2517 sock->type == SILC_SOCKET_TYPE_ROUTER &&
2518 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
2519 /* Broadcast to our primary route */
2520 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
2522 /* If we have backup routers then we need to feed all broadcast
2523 data to those servers. */
2524 silc_server_backup_broadcast(server, sock, packet);
2528 silc_packet_context_free(packet);
2529 silc_free(parse_ctx);
2532 /* Parser callback called by silc_packet_receive_process. This merely
2533 registers timeout that will handle the actual parsing when appropriate. */
2535 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
2538 SilcServer server = (SilcServer)context;
2539 SilcSocketConnection sock = parser_context->sock;
2540 SilcIDListData idata = (SilcIDListData)sock->user_data;
2544 idata->psn_receive = parser_context->packet->sequence + 1;
2546 /* If protocol for this connection is key exchange or rekey then we'll
2547 process all packets synchronously, since there might be packets in
2548 queue that we are not able to decrypt without first processing the
2549 packets before them. */
2550 if (sock->protocol && sock->protocol->protocol &&
2551 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2552 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2553 silc_server_packet_parse_real(server->schedule, server, 0, sock->sock,
2556 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
2557 SILC_LOG_DEBUG(("Connection is disconnected"));
2561 /* Reprocess data since we'll return FALSE here. This is because
2562 the idata->receive_key might have become valid in the last packet
2563 and we want to call this processor with valid cipher. */
2565 ret = silc_packet_receive_process(
2566 sock, server->server_type == SILC_ROUTER,
2568 idata->hmac_receive, idata->psn_receive,
2569 silc_server_packet_parse, server);
2571 ret = silc_packet_receive_process(
2572 sock, server->server_type == SILC_ROUTER,
2574 silc_server_packet_parse, server);
2577 /* On packet processing errors we may close our primary router
2578 connection but won't become primary router if we are the backup
2579 since this is local error condition. */
2580 if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
2581 server->backup_noswitch = TRUE;
2583 if (sock->user_data)
2584 silc_server_free_sock_user_data(server, sock, NULL);
2585 SILC_SET_DISCONNECTING(sock);
2586 silc_server_close_connection(server, sock);
2592 switch (sock->type) {
2593 case SILC_SOCKET_TYPE_UNKNOWN:
2594 case SILC_SOCKET_TYPE_CLIENT:
2595 /* Parse the packet with timeout */
2596 silc_schedule_task_add(server->schedule, sock->sock,
2597 silc_server_packet_parse_real,
2598 (void *)parser_context, 0, 100000,
2600 SILC_TASK_PRI_NORMAL);
2602 case SILC_SOCKET_TYPE_SERVER:
2603 case SILC_SOCKET_TYPE_ROUTER:
2604 /* Packets from servers are parsed immediately */
2605 silc_server_packet_parse_real(server->schedule, server, 0, sock->sock,
2613 /* Parses the packet type and calls what ever routines the packet type
2614 requires. This is done for all incoming packets. */
2616 void silc_server_packet_parse_type(SilcServer server,
2617 SilcSocketConnection sock,
2618 SilcPacketContext *packet)
2620 SilcPacketType type = packet->type;
2621 SilcIDListData idata = (SilcIDListData)sock->user_data;
2623 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
2624 silc_get_packet_name(type), packet->flags));
2626 /* Parse the packet type */
2628 case SILC_PACKET_DISCONNECT:
2631 char *message = NULL;
2633 if (packet->flags & SILC_PACKET_FLAG_LIST)
2635 if (packet->buffer->len < 1)
2638 status = (SilcStatus)packet->buffer->data[0];
2639 if (packet->buffer->len > 1 &&
2640 silc_utf8_valid(packet->buffer->data + 1, packet->buffer->len - 1))
2641 message = silc_memdup(packet->buffer->data + 1,
2642 packet->buffer->len - 1);
2644 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s",
2645 sock->ip, sock->hostname,
2646 silc_get_status_message(status), status,
2647 message ? message : ""));
2650 /* Do not switch to backup in case of error */
2651 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
2653 /* If backup disconnected then mark that resuming will not be allowed */
2654 if (server->server_type == SILC_ROUTER && !server->backup_router &&
2655 sock->type == SILC_SOCKET_TYPE_SERVER && sock->user_data) {
2656 SilcServerEntry server_entry = sock->user_data;
2657 if (server_entry->server_type == SILC_BACKUP_ROUTER)
2658 server->backup_closed = TRUE;
2661 /* Handle the disconnection from our end too */
2662 if (sock->user_data && SILC_IS_LOCAL(sock->user_data))
2663 silc_server_free_sock_user_data(server, sock, NULL);
2664 SILC_SET_DISCONNECTING(sock);
2665 silc_server_close_connection(server, sock);
2666 server->backup_noswitch = FALSE;
2670 case SILC_PACKET_SUCCESS:
2672 * Success received for something. For now we can have only
2673 * one protocol for connection executing at once hence this
2674 * success message is for whatever protocol is executing currently.
2676 if (packet->flags & SILC_PACKET_FLAG_LIST)
2679 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2682 case SILC_PACKET_FAILURE:
2684 * Failure received for something. For now we can have only
2685 * one protocol for connection executing at once hence this
2686 * failure message is for whatever protocol is executing currently.
2688 if (packet->flags & SILC_PACKET_FLAG_LIST)
2691 /* Check for failure START_USE from backup router */
2692 if (server->server_type == SILC_SERVER &&
2693 server->backup_primary && packet->buffer->len == 4) {
2695 SILC_GET32_MSB(type, packet->buffer->data);
2696 if (type == SILC_SERVER_BACKUP_START_USE) {
2697 /* Attempt to reconnect to primary */
2698 SILC_LOG_DEBUG(("Received failed START_USE from backup %s", sock->ip));
2700 /* Default action is to disconnect from backup and reconnect to
2701 primary. Since this failure can happen during switching to
2702 backup (backup might have not noticed the primary going down yet),
2703 we will wait a while and keep sending START_USE to backup.
2704 Only after that we'll give up. */
2705 if (server->router == sock->user_data &&
2706 (time(0) - server->router_connect) < 30) {
2707 SILC_LOG_DEBUG(("Resending START_USE to backup router"));
2708 silc_server_backup_send_start_use(server, sock, FALSE);
2712 /* If backup is our primary, disconnect now. */
2713 if (server->router == sock->user_data) {
2714 if (sock->user_data)
2715 silc_server_free_sock_user_data(server, sock, NULL);
2716 SILC_SET_DISCONNECTING(sock);
2717 silc_server_close_connection(server, sock);
2721 silc_server_create_connections(server);
2725 /* Execute protocol */
2726 if (sock->protocol) {
2727 sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
2728 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2733 case SILC_PACKET_REJECT:
2734 if (packet->flags & SILC_PACKET_FLAG_LIST)
2739 case SILC_PACKET_NOTIFY:
2741 * Received notify packet. Server can receive notify packets from
2742 * router. Server then relays the notify messages to clients if needed.
2744 if (packet->flags & SILC_PACKET_FLAG_LIST)
2745 silc_server_notify_list(server, sock, packet);
2747 silc_server_notify(server, sock, packet);
2753 case SILC_PACKET_CHANNEL_MESSAGE:
2755 * Received channel message. Channel messages are special packets
2756 * (although probably most common ones) thus they are handled
2759 if (packet->flags & SILC_PACKET_FLAG_LIST)
2761 idata->last_receive = time(NULL);
2762 silc_server_channel_message(server, sock, packet);
2765 case SILC_PACKET_CHANNEL_KEY:
2767 * Received key for channel. As channels are created by the router
2768 * the keys are as well. We will distribute the key to all of our
2769 * locally connected clients on the particular channel. Router
2770 * never receives this channel and thus is ignored.
2772 if (packet->flags & SILC_PACKET_FLAG_LIST)
2774 silc_server_channel_key(server, sock, packet);
2780 case SILC_PACKET_COMMAND:
2782 * Recived command. Processes the command request and allocates the
2783 * command context and calls the command.
2785 if (packet->flags & SILC_PACKET_FLAG_LIST)
2787 silc_server_command_process(server, sock, packet);
2790 case SILC_PACKET_COMMAND_REPLY:
2792 * Received command reply packet. Received command reply to command. It
2793 * may be reply to command sent by us or reply to command sent by client
2794 * that we've routed further.
2796 if (packet->flags & SILC_PACKET_FLAG_LIST)
2798 silc_server_command_reply(server, sock, packet);
2802 * Private Message packets
2804 case SILC_PACKET_PRIVATE_MESSAGE:
2806 * Received private message packet. The packet is coming from either
2809 if (packet->flags & SILC_PACKET_FLAG_LIST)
2811 idata->last_receive = time(NULL);
2812 silc_server_private_message(server, sock, packet);
2815 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
2817 * Private message key packet.
2819 if (packet->flags & SILC_PACKET_FLAG_LIST)
2821 silc_server_private_message_key(server, sock, packet);
2825 * Key Exchange protocol packets
2827 case SILC_PACKET_KEY_EXCHANGE:
2828 if (packet->flags & SILC_PACKET_FLAG_LIST)
2831 if (sock->protocol && sock->protocol->protocol &&
2832 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
2833 SilcServerKEInternalContext *proto_ctx =
2834 (SilcServerKEInternalContext *)sock->protocol->context;
2836 proto_ctx->packet = silc_packet_context_dup(packet);
2838 /* Let the protocol handle the packet */
2839 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
2841 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
2842 "protocol active (%s:%d [%s]).", sock->hostname,
2844 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2845 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2846 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2851 case SILC_PACKET_KEY_EXCHANGE_1:
2852 if (packet->flags & SILC_PACKET_FLAG_LIST)
2855 if (sock->protocol && sock->protocol->protocol &&
2856 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2857 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2859 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2860 SilcServerRekeyInternalContext *proto_ctx =
2861 (SilcServerRekeyInternalContext *)sock->protocol->context;
2863 if (proto_ctx->packet)
2864 silc_packet_context_free(proto_ctx->packet);
2866 proto_ctx->packet = silc_packet_context_dup(packet);
2868 /* Let the protocol handle the packet */
2869 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2871 SilcServerKEInternalContext *proto_ctx =
2872 (SilcServerKEInternalContext *)sock->protocol->context;
2874 if (proto_ctx->packet)
2875 silc_packet_context_free(proto_ctx->packet);
2877 proto_ctx->packet = silc_packet_context_dup(packet);
2878 proto_ctx->dest_id_type = packet->src_id_type;
2879 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2880 packet->src_id_type);
2881 if (!proto_ctx->dest_id)
2884 /* Let the protocol handle the packet */
2885 silc_protocol_execute(sock->protocol, server->schedule,
2889 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
2890 "protocol active (%s:%d [%s]).", sock->hostname,
2892 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2893 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2894 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2899 case SILC_PACKET_KEY_EXCHANGE_2:
2900 if (packet->flags & SILC_PACKET_FLAG_LIST)
2903 if (sock->protocol && sock->protocol->protocol &&
2904 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2905 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2907 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2908 SilcServerRekeyInternalContext *proto_ctx =
2909 (SilcServerRekeyInternalContext *)sock->protocol->context;
2911 if (proto_ctx->packet)
2912 silc_packet_context_free(proto_ctx->packet);
2914 proto_ctx->packet = silc_packet_context_dup(packet);
2916 /* Let the protocol handle the packet */
2917 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2919 SilcServerKEInternalContext *proto_ctx =
2920 (SilcServerKEInternalContext *)sock->protocol->context;
2922 if (proto_ctx->packet)
2923 silc_packet_context_free(proto_ctx->packet);
2925 proto_ctx->packet = silc_packet_context_dup(packet);
2926 proto_ctx->dest_id_type = packet->src_id_type;
2927 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2928 packet->src_id_type);
2929 if (!proto_ctx->dest_id)
2932 /* Let the protocol handle the packet */
2933 silc_protocol_execute(sock->protocol, server->schedule,
2937 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2938 "protocol active (%s:%d [%s]).", sock->hostname,
2940 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2941 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2942 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2947 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2949 * Connection authentication request packet. When we receive this packet
2950 * we will send to the other end information about our mandatory
2951 * authentication method for the connection. This packet maybe received
2954 if (packet->flags & SILC_PACKET_FLAG_LIST)
2956 silc_server_connection_auth_request(server, sock, packet);
2960 * Connection Authentication protocol packets
2962 case SILC_PACKET_CONNECTION_AUTH:
2963 /* Start of the authentication protocol. We receive here the
2964 authentication data and will verify it. */
2965 if (packet->flags & SILC_PACKET_FLAG_LIST)
2968 if (sock->protocol && sock->protocol->protocol->type
2969 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2971 SilcServerConnAuthInternalContext *proto_ctx =
2972 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2974 proto_ctx->packet = silc_packet_context_dup(packet);
2976 /* Let the protocol handle the packet */
2977 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2979 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2980 "protocol active (%s:%d [%s]).", sock->hostname,
2982 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2983 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2984 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2989 case SILC_PACKET_NEW_ID:
2991 * Received New ID packet. This includes some new ID that has been
2992 * created. It may be for client, server or channel. This is the way
2993 * to distribute information about new registered entities in the
2996 if (packet->flags & SILC_PACKET_FLAG_LIST)
2997 silc_server_new_id_list(server, sock, packet);
2999 silc_server_new_id(server, sock, packet);
3002 case SILC_PACKET_NEW_CLIENT:
3004 * Received new client packet. This includes client information that
3005 * we will use to create initial client ID. After creating new
3006 * ID we will send it to the client.
3008 if (packet->flags & SILC_PACKET_FLAG_LIST)
3010 silc_server_new_client(server, sock, packet);
3013 case SILC_PACKET_NEW_SERVER:
3015 * Received new server packet. This includes Server ID and some other
3016 * information that we may save. This is received after server has
3019 if (packet->flags & SILC_PACKET_FLAG_LIST)
3021 silc_server_new_server(server, sock, packet);
3024 case SILC_PACKET_NEW_CHANNEL:
3026 * Received new channel packet. Information about new channel in the
3027 * network are distributed using this packet.
3029 if (packet->flags & SILC_PACKET_FLAG_LIST)
3030 silc_server_new_channel_list(server, sock, packet);
3032 silc_server_new_channel(server, sock, packet);
3035 case SILC_PACKET_HEARTBEAT:
3037 * Received heartbeat.
3039 if (packet->flags & SILC_PACKET_FLAG_LIST)
3043 case SILC_PACKET_KEY_AGREEMENT:
3045 * Received heartbeat.
3047 if (packet->flags & SILC_PACKET_FLAG_LIST)
3049 silc_server_key_agreement(server, sock, packet);
3052 case SILC_PACKET_REKEY:
3054 * Received re-key packet. The sender wants to regenerate the session
3057 if (packet->flags & SILC_PACKET_FLAG_LIST)
3059 silc_server_rekey(server, sock, packet);
3062 case SILC_PACKET_REKEY_DONE:
3064 * The re-key is done.
3066 if (packet->flags & SILC_PACKET_FLAG_LIST)
3069 if (sock->protocol && sock->protocol->protocol &&
3070 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
3072 SilcServerRekeyInternalContext *proto_ctx =
3073 (SilcServerRekeyInternalContext *)sock->protocol->context;
3075 if (proto_ctx->packet)
3076 silc_packet_context_free(proto_ctx->packet);
3078 proto_ctx->packet = silc_packet_context_dup(packet);
3080 /* Let the protocol handle the packet */
3081 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
3083 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
3084 "protocol active (%s:%d [%s]).", sock->hostname,
3086 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3087 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3088 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3093 case SILC_PACKET_FTP:
3095 if (packet->flags & SILC_PACKET_FLAG_LIST)
3097 silc_server_ftp(server, sock, packet);
3100 case SILC_PACKET_RESUME_CLIENT:
3102 if (packet->flags & SILC_PACKET_FLAG_LIST)
3104 silc_server_resume_client(server, sock, packet);
3107 case SILC_PACKET_RESUME_ROUTER:
3108 /* Resume router packet received. This packet is received for backup
3109 router resuming protocol. */
3110 if (packet->flags & SILC_PACKET_FLAG_LIST)
3112 silc_server_backup_resume_router(server, sock, packet);
3116 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
3121 /* Creates connection to a remote router. */
3123 void silc_server_create_connection(SilcServer server,
3124 const char *remote_host, SilcUInt32 port)
3126 SilcServerConnection sconn;
3128 /* Allocate connection object for hold connection specific stuff. */
3129 sconn = silc_calloc(1, sizeof(*sconn));
3130 sconn->remote_host = strdup(remote_host);
3131 sconn->remote_port = port;
3132 sconn->no_reconnect = TRUE;
3134 silc_schedule_task_add(server->schedule, 0,
3135 silc_server_connect_router,
3136 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
3137 SILC_TASK_PRI_NORMAL);
3140 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3142 SilcServer server = app_context;
3143 SilcSocketConnection sock = context;
3145 SILC_LOG_DEBUG(("Deleting socket %p", sock));
3147 /* Close the actual connection */
3148 silc_net_close_connection(sock->sock);
3149 server->sockets[sock->sock] = NULL;
3151 /* We won't listen for this connection anymore */
3152 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
3153 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
3155 silc_socket_free(sock);
3158 /* Closes connection to socket connection */
3160 void silc_server_close_connection(SilcServer server,
3161 SilcSocketConnection sock)
3165 if (SILC_IS_DISCONNECTED(sock)) {
3166 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
3167 silc_schedule_task_add(server->schedule, sock->sock,
3168 silc_server_close_connection_final,
3169 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
3170 SILC_TASK_PRI_NORMAL);
3171 server->sockets[sock->sock] = NULL;
3175 /* If any protocol is active cancel its execution. It will call
3176 the final callback which will finalize the disconnection. */
3177 if (sock->protocol && sock->protocol->protocol &&
3178 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3179 SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
3180 silc_protocol_cancel(sock->protocol, server->schedule);
3181 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3182 silc_protocol_execute_final(sock->protocol, server->schedule);
3183 sock->protocol = NULL;
3187 memset(tmp, 0, sizeof(tmp));
3188 silc_socket_get_error(sock, tmp, sizeof(tmp));
3189 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", sock->hostname,
3191 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
3192 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
3193 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
3194 "Router"), tmp[0] ? tmp : ""));
3196 SILC_SET_DISCONNECTED(sock);
3197 silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3198 silc_schedule_task_add(server->schedule, sock->sock,
3199 silc_server_close_connection_final,
3200 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
3201 SILC_TASK_PRI_NORMAL);
3202 server->sockets[sock->sock] = NULL;
3205 /* Sends disconnect message to remote connection and disconnects the
3206 connection. NOTE: If this is called from protocol callback
3207 then sock->protocol must be set NULL before calling this, since
3208 this routine dispatches protocol callbacks too. */
3210 void silc_server_disconnect_remote(SilcServer server,
3211 SilcSocketConnection sock,
3212 SilcStatus status, ...)
3215 unsigned char buf[512];
3223 if (SILC_IS_DISCONNECTING(sock)) {
3224 SILC_SET_DISCONNECTED(sock);
3225 silc_server_close_connection(server, sock);
3229 memset(buf, 0, sizeof(buf));
3230 va_start(ap, status);
3231 cp = va_arg(ap, char *);
3233 vsnprintf(buf, sizeof(buf) - 1, cp, ap);
3238 SILC_LOG_DEBUG(("Disconnecting remote host"));
3240 /* Notify remote end that the conversation is over. The notify message
3241 is tried to be sent immediately. */
3245 len += silc_utf8_encoded_len(buf, strlen(buf), SILC_STRING_ASCII);
3247 buffer = silc_buffer_alloc_size(len);
3251 buffer->data[0] = status;
3253 silc_utf8_encode(buf, strlen(buf), SILC_STRING_ASCII, buffer->data + 1,
3255 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
3256 buffer->data, buffer->len, TRUE);
3257 silc_buffer_free(buffer);
3260 silc_server_packet_queue_purge(server, sock);
3262 /* Mark the connection to be disconnected */
3263 SILC_SET_DISCONNECTING(sock);
3264 silc_server_close_connection(server, sock);
3267 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
3269 SilcServer server = app_context;
3270 SilcClientEntry client = context;
3272 assert(!silc_hash_table_count(client->channels));
3274 silc_idlist_del_data(client);
3275 silc_idcache_purge_by_context(server->local_list->clients, client);
3278 /* Frees client data and notifies about client's signoff. */
3280 void silc_server_free_client_data(SilcServer server,
3281 SilcSocketConnection sock,
3282 SilcClientEntry client,
3284 const char *signoff)
3286 SILC_LOG_DEBUG(("Freeing client data"));
3288 /* If there is pending outgoing data for the client then purge it
3289 to the network before removing the client entry. */
3290 silc_server_packet_queue_purge(server, sock);
3293 /* Check if anyone is watching this nickname */
3294 if (server->server_type == SILC_ROUTER)
3295 silc_server_check_watcher_list(server, client, NULL,
3296 SILC_NOTIFY_TYPE_SIGNOFF);
3298 /* Send SIGNOFF notify to routers. */
3300 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3301 SILC_BROADCAST(server), client->id,
3305 /* Remove client from all channels */
3307 silc_server_remove_from_channels(server, NULL, client,
3308 TRUE, (char *)signoff, TRUE, FALSE);
3310 silc_server_remove_from_channels(server, NULL, client,
3311 FALSE, NULL, FALSE, FALSE);
3313 /* Remove this client from watcher list if it is */
3314 silc_server_del_from_watcher_list(server, client);
3316 /* Remove this client from the public key hash list */
3317 if (client->data.public_key)
3318 silc_hash_table_del_by_context(server->pk_hash,
3319 client->data.public_key, client);
3321 /* Update statistics */
3322 server->stat.my_clients--;
3323 server->stat.clients--;
3324 if (server->stat.cell_clients)
3325 server->stat.cell_clients--;
3326 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3327 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3328 silc_schedule_task_del_by_context(server->schedule, client);
3330 /* We will not delete the client entry right away. We will take it
3331 into history (for WHOWAS command) for 5 minutes, unless we're
3332 shutting down server. */
3333 if (!server->server_shutdown) {
3334 silc_schedule_task_add(server->schedule, 0,
3335 silc_server_free_client_data_timeout,
3337 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
3338 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3339 client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3341 client->router = NULL;
3342 client->connection = NULL;
3344 /* Delete directly since we're shutting down server */
3345 silc_idlist_del_data(client);
3346 silc_idlist_del_client(server->local_list, client);
3350 /* Frees user_data pointer from socket connection object. This also sends
3351 appropriate notify packets to the network to inform about leaving
3354 void silc_server_free_sock_user_data(SilcServer server,
3355 SilcSocketConnection sock,
3356 const char *signoff_message)
3359 /* If any protocol is active cancel its execution */
3360 if (sock->protocol && sock->protocol->protocol &&
3361 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3362 SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
3363 silc_protocol_cancel(sock->protocol, server->schedule);
3364 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3365 silc_protocol_execute_final(sock->protocol, server->schedule);
3366 sock->protocol = NULL;
3369 switch (sock->type) {
3370 case SILC_SOCKET_TYPE_CLIENT:
3372 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
3373 silc_server_free_client_data(server, sock, user_data, TRUE,
3377 case SILC_SOCKET_TYPE_SERVER:
3378 case SILC_SOCKET_TYPE_ROUTER:
3380 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
3381 SilcServerEntry backup_router = NULL;
3383 SILC_LOG_DEBUG(("Freeing server data"));
3386 backup_router = silc_server_backup_get(server, user_data->id);
3388 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3389 backup_router == server->id_entry &&
3390 sock->type != SILC_SOCKET_TYPE_ROUTER)
3391 backup_router = NULL;
3393 if (server->server_shutdown || server->backup_noswitch)
3394 backup_router = NULL;
3396 /* If this was our primary router connection then we're lost to
3397 the outside world. */
3398 if (server->router == user_data) {
3399 /* Check whether we have a backup router connection */
3400 if (!backup_router || backup_router == user_data) {
3401 if (!server->no_reconnect)
3402 silc_server_create_connections(server);
3403 server->id_entry->router = NULL;
3404 server->router = NULL;
3405 server->standalone = TRUE;
3406 server->backup_primary = FALSE;
3407 backup_router = NULL;
3409 if (server->id_entry != backup_router) {
3410 SILC_LOG_INFO(("New primary router is backup router %s",
3411 backup_router->server_name));
3412 server->id_entry->router = backup_router;
3413 server->router = backup_router;
3414 server->router_connect = time(0);
3415 server->backup_primary = TRUE;
3416 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3418 /* Send START_USE to backup router to indicate we have switched */
3419 silc_server_backup_send_start_use(server,
3420 backup_router->connection,
3423 SILC_LOG_INFO(("We are now new primary router in this cell"));
3424 server->id_entry->router = NULL;
3425 server->router = NULL;
3426 server->standalone = TRUE;
3429 /* We stop here to take a breath */
3432 if (server->backup_router) {
3433 server->server_type = SILC_ROUTER;
3435 /* We'll need to constantly try to reconnect to the primary
3436 router so that we'll see when it comes back online. */
3437 silc_server_backup_reconnect(server, sock->ip, sock->port,
3438 silc_server_backup_connected,
3442 /* Mark this connection as replaced */
3443 silc_server_backup_replaced_add(server, user_data->id,
3446 } else if (backup_router) {
3447 SILC_LOG_INFO(("Enabling the use of backup router %s",
3448 backup_router->server_name));
3450 /* Mark this connection as replaced */
3451 silc_server_backup_replaced_add(server, user_data->id,
3453 } else if (server->server_type == SILC_SERVER &&
3454 sock->type == SILC_SOCKET_TYPE_ROUTER) {
3455 /* Reconnect to the router (backup) */
3456 if (!server->no_reconnect)
3457 silc_server_create_connections(server);
3460 if (user_data->server_name)
3461 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3462 ("Server %s signoff", user_data->server_name));
3464 if (!backup_router) {
3465 /* Remove all servers that are originated from this server, and
3466 remove the clients of those servers too. */
3467 silc_server_remove_servers_by_server(server, user_data, TRUE);
3470 /* Remove the clients that this server owns as they will become
3471 invalid now too. For backup router the server is actually
3472 coming from the primary router, so mark that as the owner
3474 if (server->server_type == SILC_BACKUP_ROUTER &&
3475 sock->type == SILC_SOCKET_TYPE_SERVER)
3476 silc_server_remove_clients_by_server(server, server->router,
3480 silc_server_remove_clients_by_server(server, user_data,
3483 /* Remove channels owned by this server */
3484 if (server->server_type == SILC_SERVER)
3485 silc_server_remove_channels_by_server(server, user_data);
3487 /* Enable local server connections that may be disabled */
3488 silc_server_local_servers_toggle_enabled(server, TRUE);
3490 /* Update the client entries of this server to the new backup
3491 router. If we are the backup router we also resolve the real
3492 servers for the clients. After updating is over this also
3493 removes the clients that this server explicitly owns. */
3494 silc_server_update_clients_by_server(server, user_data,
3495 backup_router, TRUE);
3497 /* If we are router and just lost our primary router (now standlaone)
3498 we remove everything that was behind it, since we don't know
3500 if (server->server_type == SILC_ROUTER && server->standalone)
3501 /* Remove all servers that are originated from this server, and
3502 remove the clients of those servers too. */
3503 silc_server_remove_servers_by_server(server, user_data, TRUE);
3505 /* Finally remove the clients that are explicitly owned by this
3506 server. They go down with the server. */
3507 silc_server_remove_clients_by_server(server, user_data,
3510 /* Update our server cache to use the new backup router too. */
3511 silc_server_update_servers_by_server(server, user_data, backup_router);
3512 if (server->server_type == SILC_SERVER)
3513 silc_server_update_channels_by_server(server, user_data,
3516 /* Send notify about primary router going down to local operators */
3517 if (server->backup_router)
3518 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3519 SILC_NOTIFY_TYPE_NONE,
3520 ("%s switched to backup router %s "
3521 "(we are primary router now)",
3522 server->server_name, server->server_name));
3523 else if (server->router)
3524 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3525 SILC_NOTIFY_TYPE_NONE,
3526 ("%s switched to backup router %s",
3527 server->server_name,
3528 server->router->server_name));
3530 server->backup_noswitch = FALSE;
3532 /* Free the server entry */
3533 silc_server_backup_del(server, user_data);
3534 silc_server_backup_replaced_del(server, user_data);
3535 silc_idlist_del_data(user_data);
3536 if (!silc_idlist_del_server(server->local_list, user_data))
3537 silc_idlist_del_server(server->global_list, user_data);
3538 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
3539 server->stat.my_servers--;
3541 server->stat.my_routers--;
3542 server->stat.routers--;
3544 server->stat.servers--;
3545 if (server->server_type == SILC_ROUTER)
3546 server->stat.cell_servers--;
3548 if (backup_router && backup_router != server->id_entry) {
3549 /* Announce all of our stuff that was created about 5 minutes ago.
3550 The backup router knows all the other stuff already. */
3551 if (server->server_type == SILC_ROUTER)
3552 silc_server_announce_servers(server, FALSE, time(0) - 300,
3553 backup_router->connection);
3555 /* Announce our clients and channels to the router */
3556 silc_server_announce_clients(server, time(0) - 300,
3557 backup_router->connection);
3558 silc_server_announce_channels(server, time(0) - 300,
3559 backup_router->connection);
3565 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
3567 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3569 silc_idlist_del_data(user_data);
3570 silc_free(user_data);
3575 sock->user_data = NULL;
3578 /* Removes client from all channels it has joined. This is used when client
3579 connection is disconnected. If the client on a channel is last, the
3580 channel is removed as well. This sends the SIGNOFF notify types. */
3582 void silc_server_remove_from_channels(SilcServer server,
3583 SilcSocketConnection sock,
3584 SilcClientEntry client,
3586 const char *signoff_message,
3590 SilcChannelEntry channel;
3591 SilcChannelClientEntry chl;
3592 SilcHashTableList htl;
3593 SilcBuffer clidp = NULL;
3598 if (notify && !client->id)
3601 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3602 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3605 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3610 /* Remove the client from all channels. The client is removed from
3611 the channels' user list. */
3612 silc_hash_table_list(client->channels, &htl);
3613 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3614 channel = chl->channel;
3616 /* Remove channel if this is last client leaving the channel, unless
3617 the channel is permanent. */
3618 if (server->server_type != SILC_SERVER &&
3619 silc_hash_table_count(channel->user_list) < 2) {
3620 silc_server_channel_delete(server, channel);
3624 silc_hash_table_del(client->channels, channel);
3625 silc_hash_table_del(channel->user_list, client);
3626 channel->user_count--;
3628 /* If there is no global users on the channel anymore mark the channel
3629 as local channel. Do not check if the removed client is local client. */
3630 if (server->server_type == SILC_SERVER && channel->global_users &&
3631 chl->client->router && !silc_server_channel_has_global(channel))
3632 channel->global_users = FALSE;
3634 memset(chl, 'A', sizeof(*chl));
3637 /* Update statistics */
3638 if (SILC_IS_LOCAL(client))
3639 server->stat.my_chanclients--;
3640 if (server->server_type == SILC_ROUTER) {
3641 server->stat.cell_chanclients--;
3642 server->stat.chanclients--;
3645 /* If there is not at least one local user on the channel then we don't
3646 need the channel entry anymore, we can remove it safely, unless the
3647 channel is permanent channel */
3648 if (server->server_type == SILC_SERVER &&
3649 !silc_server_channel_has_local(channel)) {
3650 /* Notify about leaving client if this channel has global users. */
3651 if (notify && channel->global_users)
3652 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3653 SILC_NOTIFY_TYPE_SIGNOFF,
3654 signoff_message ? 2 : 1,
3655 clidp->data, clidp->len,
3656 signoff_message, signoff_message ?
3657 strlen(signoff_message) : 0);
3659 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3660 silc_server_channel_delete(server, channel);
3664 /* Send notify to channel about client leaving SILC and channel too */
3666 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3667 SILC_NOTIFY_TYPE_SIGNOFF,
3668 signoff_message ? 2 : 1,
3669 clidp->data, clidp->len,
3670 signoff_message, signoff_message ?
3671 strlen(signoff_message) : 0);
3673 if (killed && clidp) {
3674 /* Remove the client from channel's invite list */
3675 if (channel->invite_list &&
3676 silc_hash_table_count(channel->invite_list)) {
3678 SilcArgumentPayload iargs;
3679 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3681 iargs = silc_argument_payload_parse(ab->data, ab->len, 1);
3682 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3683 silc_buffer_free(ab);
3684 silc_argument_payload_free(iargs);
3688 /* Don't create keys if we are shutting down */
3689 if (server->server_shutdown)
3692 /* Re-generate channel key if needed */
3693 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3694 if (!silc_server_create_channel_key(server, channel, 0))
3697 /* Send the channel key to the channel. The key of course is not sent
3698 to the client who was removed from the channel. */
3699 silc_server_send_channel_key(server, client->connection, channel,
3700 server->server_type == SILC_ROUTER ?
3701 FALSE : !server->standalone);
3705 silc_hash_table_list_reset(&htl);
3707 silc_buffer_free(clidp);
3710 /* Removes client from one channel. This is used for example when client
3711 calls LEAVE command to remove itself from the channel. Returns TRUE
3712 if channel still exists and FALSE if the channel is removed when
3713 last client leaves the channel. If `notify' is FALSE notify messages
3716 bool silc_server_remove_from_one_channel(SilcServer server,
3717 SilcSocketConnection sock,
3718 SilcChannelEntry channel,
3719 SilcClientEntry client,
3722 SilcChannelClientEntry chl;
3725 SILC_LOG_DEBUG(("Removing %s from channel %s",
3726 silc_id_render(client->id, SILC_ID_CLIENT),
3727 channel->channel_name));
3729 /* Get the entry to the channel, if this client is not on the channel
3731 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3734 /* Remove channel if this is last client leaving the channel, unless
3735 the channel is permanent. */
3736 if (server->server_type != SILC_SERVER &&
3737 silc_hash_table_count(channel->user_list) < 2) {
3738 silc_server_channel_delete(server, channel);
3742 silc_hash_table_del(client->channels, channel);
3743 silc_hash_table_del(channel->user_list, client);
3744 channel->user_count--;
3746 /* If there is no global users on the channel anymore mark the channel
3747 as local channel. Do not check if the client is local client. */
3748 if (server->server_type == SILC_SERVER && channel->global_users &&
3749 chl->client->router && !silc_server_channel_has_global(channel))
3750 channel->global_users = FALSE;
3752 memset(chl, 'O', sizeof(*chl));
3755 /* Update statistics */
3756 if (SILC_IS_LOCAL(client))
3757 server->stat.my_chanclients--;
3758 if (server->server_type == SILC_ROUTER) {
3759 server->stat.cell_chanclients--;
3760 server->stat.chanclients--;
3763 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3767 /* If there is not at least one local user on the channel then we don't
3768 need the channel entry anymore, we can remove it safely, unless the
3769 channel is permanent channel */
3770 if (server->server_type == SILC_SERVER &&
3771 !silc_server_channel_has_local(channel)) {
3772 /* Notify about leaving client if this channel has global users. */
3773 if (notify && channel->global_users)
3774 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3775 SILC_NOTIFY_TYPE_LEAVE, 1,
3776 clidp->data, clidp->len);
3778 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3779 silc_server_channel_delete(server, channel);
3780 silc_buffer_free(clidp);
3784 /* Send notify to channel about client leaving the channel */
3786 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3787 SILC_NOTIFY_TYPE_LEAVE, 1,
3788 clidp->data, clidp->len);
3790 silc_buffer_free(clidp);
3794 /* Timeout callback. This is called if connection is idle or for some
3795 other reason is not responding within some period of time. This
3796 disconnects the remote end. */
3798 SILC_TASK_CALLBACK(silc_server_timeout_remote)
3800 SilcServer server = (SilcServer)context;
3801 SilcSocketConnection sock = server->sockets[fd];
3802 SilcProtocolType protocol = 0;
3804 SILC_LOG_DEBUG(("Start"));
3809 SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
3810 sock->hostname, sock->ip));
3812 /* If we have protocol active we must assure that we call the protocol's
3813 final callback so that all the memory is freed. */
3814 if (sock->protocol && sock->protocol->protocol &&
3815 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3816 protocol = sock->protocol->protocol->type;
3817 silc_protocol_cancel(sock->protocol, server->schedule);
3818 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3819 silc_protocol_execute_final(sock->protocol, server->schedule);
3820 sock->protocol = NULL;
3824 silc_server_disconnect_remote(server, sock,
3826 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3827 SILC_STATUS_ERR_AUTH_FAILED :
3828 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3829 "Connection timeout");
3831 if (sock->user_data)
3832 silc_server_free_sock_user_data(server, sock, NULL);
3835 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3836 function may be used only by router. In real SILC network all channels
3837 are created by routers thus this function is never used by normal
3840 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3841 SilcServerID *router_id,
3847 SilcChannelID *channel_id;
3848 SilcChannelEntry entry;
3852 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3855 cipher = SILC_DEFAULT_CIPHER;
3857 hmac = SILC_DEFAULT_HMAC;
3859 /* Allocate cipher */
3860 if (!silc_cipher_alloc(cipher, &key))
3864 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3865 silc_cipher_free(key);
3869 channel_name = strdup(channel_name);
3871 /* Create the channel ID */
3872 if (!silc_id_create_channel_id(server, router_id, server->rng,
3874 silc_free(channel_name);
3875 silc_cipher_free(key);
3876 silc_hmac_free(newhmac);
3880 /* Create the channel */
3881 entry = silc_idlist_add_channel(server->local_list, channel_name,
3882 SILC_CHANNEL_MODE_NONE, channel_id,
3883 NULL, key, newhmac, 0);
3885 silc_free(channel_name);
3886 silc_cipher_free(key);
3887 silc_hmac_free(newhmac);
3888 silc_free(channel_id);
3892 entry->cipher = strdup(cipher);
3893 entry->hmac_name = strdup(hmac);
3895 /* Now create the actual key material */
3896 if (!silc_server_create_channel_key(server, entry,
3897 silc_cipher_get_key_len(key) / 8)) {
3898 silc_idlist_del_channel(server->local_list, entry);
3902 /* Notify other routers about the new channel. We send the packet
3903 to our primary route. */
3905 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3906 channel_name, entry->id,
3907 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3910 /* Distribute to backup routers */
3911 if (broadcast && server->server_type == SILC_ROUTER) {
3914 SilcUInt32 name_len = strlen(channel_name);
3915 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
3916 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
3918 packet = silc_channel_payload_encode(channel_name, name_len,
3919 cid, channel_id_len, entry->mode);
3920 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3921 packet->data, packet->len, FALSE, TRUE);
3923 silc_buffer_free(packet);
3926 server->stat.my_channels++;
3927 if (server->server_type == SILC_ROUTER) {
3928 server->stat.channels++;
3929 server->stat.cell_channels++;
3930 entry->users_resolved = TRUE;
3936 /* Same as above but creates the channel with Channel ID `channel_id. */
3939 silc_server_create_new_channel_with_id(SilcServer server,
3943 SilcChannelID *channel_id,
3946 SilcChannelEntry entry;
3950 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3953 cipher = SILC_DEFAULT_CIPHER;
3955 hmac = SILC_DEFAULT_HMAC;
3957 /* Allocate cipher */
3958 if (!silc_cipher_alloc(cipher, &key))
3962 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3963 silc_cipher_free(key);
3967 channel_name = strdup(channel_name);
3969 /* Create the channel */
3970 entry = silc_idlist_add_channel(server->local_list, channel_name,
3971 SILC_CHANNEL_MODE_NONE, channel_id,
3972 NULL, key, newhmac, 0);
3974 silc_cipher_free(key);
3975 silc_hmac_free(newhmac);
3976 silc_free(channel_name);
3980 /* Now create the actual key material */
3981 if (!silc_server_create_channel_key(server, entry,
3982 silc_cipher_get_key_len(key) / 8)) {
3983 silc_idlist_del_channel(server->local_list, entry);
3987 /* Notify other routers about the new channel. We send the packet
3988 to our primary route. */
3990 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3991 channel_name, entry->id,
3992 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3995 /* Distribute to backup routers */
3996 if (broadcast && server->server_type == SILC_ROUTER) {
3999 SilcUInt32 name_len = strlen(channel_name);
4000 SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
4001 cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
4003 packet = silc_channel_payload_encode(channel_name, name_len,
4004 cid, channel_id_len, entry->mode);
4005 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
4006 packet->data, packet->len, FALSE, TRUE);
4008 silc_buffer_free(packet);
4011 server->stat.my_channels++;
4012 if (server->server_type == SILC_ROUTER) {
4013 server->stat.channels++;
4014 server->stat.cell_channels++;
4015 entry->users_resolved = TRUE;
4021 /* Channel's key re-key timeout callback. */
4023 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
4025 SilcServer server = app_context;
4026 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
4030 /* Return now if we are shutting down */
4031 if (server->server_shutdown)
4034 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
4037 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
4040 /* Generates new channel key. This is used to create the initial channel key
4041 but also to re-generate new key for channel. If `key_len' is provided
4042 it is the bytes of the key length. */
4044 bool silc_server_create_channel_key(SilcServer server,
4045 SilcChannelEntry channel,
4049 unsigned char channel_key[32], hash[32];
4052 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
4053 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
4057 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
4059 if (!channel->channel_key)
4060 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
4061 channel->channel_key = NULL;
4067 else if (channel->key_len)
4068 len = channel->key_len / 8;
4070 len = silc_cipher_get_key_len(channel->channel_key) / 8;
4072 /* Create channel key */
4073 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
4076 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
4078 /* Remove old key if exists */
4080 memset(channel->key, 0, channel->key_len / 8);
4081 silc_free(channel->key);
4085 channel->key_len = len * 8;
4086 channel->key = silc_memdup(channel_key, len);
4087 memset(channel_key, 0, sizeof(channel_key));
4089 /* Generate HMAC key from the channel key data and set it */
4091 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4092 memset(channel->key, 0, channel->key_len / 8);
4093 silc_free(channel->key);
4094 channel->channel_key = NULL;
4097 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
4098 silc_hmac_set_key(channel->hmac, hash,
4099 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4100 memset(hash, 0, sizeof(hash));
4102 if (server->server_type == SILC_ROUTER) {
4103 if (!channel->rekey)
4104 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4105 channel->rekey->channel = channel;
4106 channel->rekey->key_len = key_len;
4107 if (channel->rekey->task)
4108 silc_schedule_task_del(server->schedule, channel->rekey->task);
4110 channel->rekey->task =
4111 silc_schedule_task_add(server->schedule, 0,
4112 silc_server_channel_key_rekey,
4113 (void *)channel->rekey,
4114 server->config->channel_rekey_secs, 0,
4116 SILC_TASK_PRI_NORMAL);
4122 /* Saves the channel key found in the encoded `key_payload' buffer. This
4123 function is used when we receive Channel Key Payload and also when we're
4124 processing JOIN command reply. Returns entry to the channel. */
4126 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4127 SilcBuffer key_payload,
4128 SilcChannelEntry channel)
4130 SilcChannelKeyPayload payload = NULL;
4131 SilcChannelID *id = NULL;
4132 unsigned char *tmp, hash[32];
4136 /* Decode channel key payload */
4137 payload = silc_channel_key_payload_parse(key_payload->data,
4140 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4145 /* Get the channel entry */
4148 /* Get channel ID */
4149 tmp = silc_channel_key_get_id(payload, &tmp_len);
4150 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
4156 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4158 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4160 if (server->server_type == SILC_ROUTER)
4161 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4162 silc_id_render(id, SILC_ID_CHANNEL)));
4168 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4170 tmp = silc_channel_key_get_key(payload, &tmp_len);
4176 cipher = silc_channel_key_get_cipher(payload, NULL);
4182 /* Remove old key if exists */
4184 memset(channel->key, 0, channel->key_len / 8);
4185 silc_free(channel->key);
4186 silc_cipher_free(channel->channel_key);
4189 /* Create new cipher */
4190 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
4191 channel->channel_key = NULL;
4196 if (channel->cipher)
4197 silc_free(channel->cipher);
4198 channel->cipher = strdup(cipher);
4201 channel->key_len = tmp_len * 8;
4202 channel->key = silc_memdup(tmp, tmp_len);
4203 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
4205 /* Generate HMAC key from the channel key data and set it */
4207 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4208 memset(channel->key, 0, channel->key_len / 8);
4209 silc_free(channel->key);
4210 channel->channel_key = NULL;
4213 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4214 silc_hmac_set_key(channel->hmac, hash,
4215 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4217 memset(hash, 0, sizeof(hash));
4218 memset(tmp, 0, tmp_len);
4220 if (server->server_type == SILC_ROUTER) {
4221 if (!channel->rekey)
4222 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4223 channel->rekey->channel = channel;
4224 if (channel->rekey->task)
4225 silc_schedule_task_del(server->schedule, channel->rekey->task);
4227 channel->rekey->task =
4228 silc_schedule_task_add(server->schedule, 0,
4229 silc_server_channel_key_rekey,
4230 (void *)channel->rekey,
4231 server->config->channel_rekey_secs, 0,
4233 SILC_TASK_PRI_NORMAL);
4239 silc_channel_key_payload_free(payload);
4244 /* Heartbeat callback. This function is set as argument for the
4245 silc_socket_set_heartbeat function. The library will call this function
4246 at the set time interval. */
4248 void silc_server_perform_heartbeat(SilcSocketConnection sock,
4251 SilcServer server = hb_context;
4253 SILC_LOG_DEBUG(("Sending heartbeat to %s:%d (%s)", sock->hostname,
4254 sock->port, sock->ip));
4256 /* Send the heartbeat */
4257 silc_server_send_heartbeat(server, sock);
4260 /* Returns assembled of all servers in the given ID list. The packet's
4261 form is dictated by the New ID payload. */
4263 static void silc_server_announce_get_servers(SilcServer server,
4264 SilcServerEntry remote,
4266 SilcBuffer *servers,
4267 unsigned long creation_time)
4269 SilcIDCacheList list;
4270 SilcIDCacheEntry id_cache;
4271 SilcServerEntry entry;
4274 /* Go through all clients in the list */
4275 if (silc_idcache_get_all(id_list->servers, &list)) {
4276 if (silc_idcache_list_first(list, &id_cache)) {
4278 entry = (SilcServerEntry)id_cache->context;
4280 /* Do not announce the one we've sending our announcements and
4281 do not announce ourself. Also check the creation time if it's
4283 if ((entry == remote) || (entry == server->id_entry) ||
4284 (creation_time && entry->data.created < creation_time)) {
4285 if (!silc_idcache_list_next(list, &id_cache))
4290 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4292 *servers = silc_buffer_realloc(*servers,
4294 (*servers)->truelen + idp->len :
4296 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4297 silc_buffer_put(*servers, idp->data, idp->len);
4298 silc_buffer_pull(*servers, idp->len);
4299 silc_buffer_free(idp);
4301 if (!silc_idcache_list_next(list, &id_cache))
4306 silc_idcache_list_free(list);
4311 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4317 p = silc_notify_payload_encode(notify, argc, ap);
4323 /* This function is used by router to announce existing servers to our
4324 primary router when we've connected to it. If `creation_time' is non-zero
4325 then only the servers that has been created after the `creation_time'
4326 will be announced. */
4328 void silc_server_announce_servers(SilcServer server, bool global,
4329 unsigned long creation_time,
4330 SilcSocketConnection remote)
4332 SilcBuffer servers = NULL;
4334 SILC_LOG_DEBUG(("Announcing servers"));
4336 /* Get servers in local list */
4337 silc_server_announce_get_servers(server, remote->user_data,
4338 server->local_list, &servers,
4342 /* Get servers in global list */
4343 silc_server_announce_get_servers(server, remote->user_data,
4344 server->global_list, &servers,
4348 silc_buffer_push(servers, servers->data - servers->head);
4349 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
4351 /* Send the packet */
4352 silc_server_packet_send(server, remote,
4353 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4354 servers->data, servers->len, TRUE);
4356 silc_buffer_free(servers);
4360 /* Returns assembled packet of all clients in the given ID list. The
4361 packet's form is dictated by the New ID Payload. */
4363 static void silc_server_announce_get_clients(SilcServer server,
4365 SilcBuffer *clients,
4367 unsigned long creation_time)
4369 SilcIDCacheList list;
4370 SilcIDCacheEntry id_cache;
4371 SilcClientEntry client;
4374 unsigned char mode[4];
4376 /* Go through all clients in the list */
4377 if (silc_idcache_get_all(id_list->clients, &list)) {
4378 if (silc_idcache_list_first(list, &id_cache)) {
4380 client = (SilcClientEntry)id_cache->context;
4382 if (creation_time && client->data.created < creation_time) {
4383 if (!silc_idcache_list_next(list, &id_cache))
4387 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) &&
4388 !client->connection && !client->router && !SILC_IS_LOCAL(client)) {
4389 if (!silc_idcache_list_next(list, &id_cache))
4394 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4396 *clients = silc_buffer_realloc(*clients,
4398 (*clients)->truelen + idp->len :
4400 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4401 silc_buffer_put(*clients, idp->data, idp->len);
4402 silc_buffer_pull(*clients, idp->len);
4404 SILC_PUT32_MSB(client->mode, mode);
4406 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4407 2, idp->data, idp->len,
4409 *umodes = silc_buffer_realloc(*umodes,
4411 (*umodes)->truelen + tmp->len :
4413 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4414 silc_buffer_put(*umodes, tmp->data, tmp->len);
4415 silc_buffer_pull(*umodes, tmp->len);
4416 silc_buffer_free(tmp);
4418 silc_buffer_free(idp);
4420 if (!silc_idcache_list_next(list, &id_cache))
4425 silc_idcache_list_free(list);
4429 /* This function is used to announce our existing clients to our router
4430 when we've connected to it. If `creation_time' is non-zero then only
4431 the clients that has been created after the `creation_time' will be
4434 void silc_server_announce_clients(SilcServer server,
4435 unsigned long creation_time,
4436 SilcSocketConnection remote)
4438 SilcBuffer clients = NULL;
4439 SilcBuffer umodes = NULL;
4441 SILC_LOG_DEBUG(("Announcing clients"));
4443 /* Get clients in local list */
4444 silc_server_announce_get_clients(server, server->local_list,
4445 &clients, &umodes, creation_time);
4447 /* As router we announce our global list as well */
4448 if (server->server_type == SILC_ROUTER)
4449 silc_server_announce_get_clients(server, server->global_list,
4450 &clients, &umodes, creation_time);
4453 silc_buffer_push(clients, clients->data - clients->head);
4454 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
4456 /* Send the packet */
4457 silc_server_packet_send(server, remote,
4458 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4459 clients->data, clients->len, TRUE);
4461 silc_buffer_free(clients);
4465 silc_buffer_push(umodes, umodes->data - umodes->head);
4466 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
4468 /* Send the packet */
4469 silc_server_packet_send(server, remote,
4470 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4471 umodes->data, umodes->len, TRUE);
4473 silc_buffer_free(umodes);
4477 /* Returns channel's topic for announcing it */
4479 void silc_server_announce_get_channel_topic(SilcServer server,
4480 SilcChannelEntry channel,
4485 if (channel->topic) {
4486 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4487 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4488 chidp->data, chidp->len,
4490 strlen(channel->topic));
4491 silc_buffer_free(chidp);
4495 /* Returns channel's invite and ban lists */
4497 void silc_server_announce_get_inviteban(SilcServer server,
4498 SilcChannelEntry channel,
4502 SilcBuffer list, idp, idp2, tmp2;
4504 SilcHashTableList htl;
4505 const unsigned char a[1] = { 0x03 };
4507 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4509 /* Encode invite list */
4510 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4511 list = silc_buffer_alloc_size(2);
4512 type = silc_hash_table_count(channel->invite_list);
4513 SILC_PUT16_MSB(type, list->data);
4514 silc_hash_table_list(channel->invite_list, &htl);
4515 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4516 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4518 silc_hash_table_list_reset(&htl);
4520 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4522 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4523 idp->data, idp->len,
4524 channel->channel_name,
4525 strlen(channel->channel_name),
4526 idp2->data, idp2->len,
4528 list->data, list->len);
4529 silc_buffer_free(idp2);
4530 silc_buffer_free(list);
4533 /* Encode ban list */
4534 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4535 list = silc_buffer_alloc_size(2);
4536 type = silc_hash_table_count(channel->ban_list);
4537 SILC_PUT16_MSB(type, list->data);
4538 silc_hash_table_list(channel->ban_list, &htl);
4539 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4540 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4542 silc_hash_table_list_reset(&htl);
4545 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4546 idp->data, idp->len,
4548 list->data, list->len);
4549 silc_buffer_free(list);
4552 silc_buffer_free(idp);
4555 /* Returns assembled packets for channel users of the `channel'. */
4557 void silc_server_announce_get_channel_users(SilcServer server,
4558 SilcChannelEntry channel,
4559 SilcBuffer *channel_modes,
4560 SilcBuffer *channel_users,
4561 SilcBuffer *channel_users_modes)
4563 SilcChannelClientEntry chl;
4564 SilcHashTableList htl;
4565 SilcBuffer chidp, clidp, csidp;
4566 SilcBuffer tmp, fkey = NULL, chpklist;
4568 unsigned char mode[4];
4571 SILC_LOG_DEBUG(("Start"));
4573 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4574 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4575 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4578 SILC_PUT32_MSB(channel->mode, mode);
4579 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4580 if (channel->founder_key)
4581 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
4583 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4584 7, csidp->data, csidp->len,
4587 hmac, hmac ? strlen(hmac) : 0,
4588 channel->passphrase,
4589 channel->passphrase ?
4590 strlen(channel->passphrase) : 0,
4591 fkey ? fkey->data : NULL,
4592 fkey ? fkey->len : 0,
4593 chpklist ? chpklist->data : NULL,
4594 chpklist ? chpklist->len : 0);
4597 silc_buffer_realloc(*channel_modes,
4599 (*channel_modes)->truelen + len : len));
4600 silc_buffer_pull_tail(*channel_modes,
4601 ((*channel_modes)->end -
4602 (*channel_modes)->data));
4603 silc_buffer_put(*channel_modes, tmp->data, tmp->len);
4604 silc_buffer_pull(*channel_modes, len);
4605 silc_buffer_free(tmp);
4606 silc_buffer_free(fkey);
4609 /* Now find all users on the channel */
4610 silc_hash_table_list(channel->user_list, &htl);
4611 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4612 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4615 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4616 clidp->data, clidp->len,
4617 chidp->data, chidp->len);
4620 silc_buffer_realloc(*channel_users,
4622 (*channel_users)->truelen + len : len));
4623 silc_buffer_pull_tail(*channel_users,
4624 ((*channel_users)->end -
4625 (*channel_users)->data));
4627 silc_buffer_put(*channel_users, tmp->data, tmp->len);
4628 silc_buffer_pull(*channel_users, len);
4629 silc_buffer_free(tmp);
4631 /* CUMODE notify for mode change on the channel */
4632 SILC_PUT32_MSB(chl->mode, mode);
4633 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4634 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
4635 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4636 4, csidp->data, csidp->len,
4638 clidp->data, clidp->len,
4639 fkey ? fkey->data : NULL,
4640 fkey ? fkey->len : 0);
4642 *channel_users_modes =
4643 silc_buffer_realloc(*channel_users_modes,
4644 (*channel_users_modes ?
4645 (*channel_users_modes)->truelen + len : len));
4646 silc_buffer_pull_tail(*channel_users_modes,
4647 ((*channel_users_modes)->end -
4648 (*channel_users_modes)->data));
4650 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
4651 silc_buffer_pull(*channel_users_modes, len);
4652 silc_buffer_free(tmp);
4653 silc_buffer_free(fkey);
4655 silc_buffer_free(clidp);
4657 silc_hash_table_list_reset(&htl);
4658 silc_buffer_free(chidp);
4659 silc_buffer_free(csidp);
4662 /* Returns assembled packets for all channels and users on those channels
4663 from the given ID List. The packets are in the form dictated by the
4664 New Channel and New Channel User payloads. */
4666 void silc_server_announce_get_channels(SilcServer server,
4668 SilcBuffer *channels,
4669 SilcBuffer **channel_modes,
4670 SilcBuffer *channel_users,
4671 SilcBuffer **channel_users_modes,
4672 SilcUInt32 *channel_users_modes_c,
4673 SilcBuffer **channel_topics,
4674 SilcBuffer **channel_invites,
4675 SilcBuffer **channel_bans,
4676 SilcChannelID ***channel_ids,
4677 unsigned long creation_time)
4679 SilcIDCacheList list;
4680 SilcIDCacheEntry id_cache;
4681 SilcChannelEntry channel;
4684 SilcUInt16 name_len;
4686 int i = *channel_users_modes_c;
4689 SILC_LOG_DEBUG(("Start"));
4691 /* Go through all channels in the list */
4692 if (silc_idcache_get_all(id_list->channels, &list)) {
4693 if (silc_idcache_list_first(list, &id_cache)) {
4695 channel = (SilcChannelEntry)id_cache->context;
4697 if (creation_time && channel->created < creation_time)
4702 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
4703 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
4704 name_len = strlen(channel->channel_name);
4707 len = 4 + name_len + id_len + 4;
4709 silc_buffer_realloc(*channels,
4710 (*channels ? (*channels)->truelen +
4712 silc_buffer_pull_tail(*channels,
4713 ((*channels)->end - (*channels)->data));
4714 silc_buffer_format(*channels,
4715 SILC_STR_UI_SHORT(name_len),
4716 SILC_STR_UI_XNSTRING(channel->channel_name,
4718 SILC_STR_UI_SHORT(id_len),
4719 SILC_STR_UI_XNSTRING(cid, id_len),
4720 SILC_STR_UI_INT(channel->mode),
4722 silc_buffer_pull(*channels, len);
4725 if (creation_time && channel->updated < creation_time)
4731 /* Channel user modes */
4732 *channel_users_modes = silc_realloc(*channel_users_modes,
4733 sizeof(**channel_users_modes) *
4735 (*channel_users_modes)[i] = NULL;
4736 *channel_modes = silc_realloc(*channel_modes,
4737 sizeof(**channel_modes) * (i + 1));
4738 (*channel_modes)[i] = NULL;
4739 *channel_ids = silc_realloc(*channel_ids,
4740 sizeof(**channel_ids) * (i + 1));
4741 (*channel_ids)[i] = NULL;
4742 silc_server_announce_get_channel_users(server, channel,
4743 &(*channel_modes)[i],
4745 &(*channel_users_modes)[i]);
4746 (*channel_ids)[i] = channel->id;
4748 /* Channel's topic */
4749 *channel_topics = silc_realloc(*channel_topics,
4750 sizeof(**channel_topics) * (i + 1));
4751 (*channel_topics)[i] = NULL;
4752 silc_server_announce_get_channel_topic(server, channel,
4753 &(*channel_topics)[i]);
4755 /* Channel's invite and ban list */
4756 *channel_invites = silc_realloc(*channel_invites,
4757 sizeof(**channel_invites) * (i + 1));
4758 (*channel_invites)[i] = NULL;
4759 *channel_bans = silc_realloc(*channel_bans,
4760 sizeof(**channel_bans) * (i + 1));
4761 (*channel_bans)[i] = NULL;
4762 silc_server_announce_get_inviteban(server, channel,
4763 &(*channel_invites)[i],
4764 &(*channel_bans)[i]);
4766 (*channel_users_modes_c)++;
4772 if (!silc_idcache_list_next(list, &id_cache))
4777 silc_idcache_list_free(list);
4781 /* This function is used to announce our existing channels to our router
4782 when we've connected to it. This also announces the users on the
4783 channels to the router. If the `creation_time' is non-zero only the
4784 channels that was created after the `creation_time' are announced.
4785 Note that the channel users are still announced even if the `creation_time'
4788 void silc_server_announce_channels(SilcServer server,
4789 unsigned long creation_time,
4790 SilcSocketConnection remote)
4792 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4793 SilcBuffer *channel_users_modes = NULL;
4794 SilcBuffer *channel_topics = NULL;
4795 SilcBuffer *channel_invites = NULL;
4796 SilcBuffer *channel_bans = NULL;
4797 SilcUInt32 channel_users_modes_c = 0;
4798 SilcChannelID **channel_ids = NULL;
4800 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4802 /* Get channels and channel users in local list */
4803 silc_server_announce_get_channels(server, server->local_list,
4804 &channels, &channel_modes,
4806 &channel_users_modes,
4807 &channel_users_modes_c,
4811 &channel_ids, creation_time);
4813 /* Get channels and channel users in global list */
4814 if (server->server_type != SILC_SERVER)
4815 silc_server_announce_get_channels(server, server->global_list,
4816 &channels, &channel_modes,
4818 &channel_users_modes,
4819 &channel_users_modes_c,
4823 &channel_ids, creation_time);
4826 silc_buffer_push(channels, channels->data - channels->head);
4827 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
4829 /* Send the packet */
4830 silc_server_packet_send(server, remote,
4831 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4832 channels->data, channels->len,
4835 silc_buffer_free(channels);
4838 if (channel_users) {
4839 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4840 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4841 channel_users->len);
4843 /* Send the packet */
4844 silc_server_packet_send(server, remote,
4845 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4846 channel_users->data, channel_users->len,
4849 silc_buffer_free(channel_users);
4852 if (channel_modes) {
4855 for (i = 0; i < channel_users_modes_c; i++) {
4856 if (!channel_modes[i])
4858 silc_buffer_push(channel_modes[i],
4859 channel_modes[i]->data -
4860 channel_modes[i]->head);
4861 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4862 channel_modes[i]->len);
4863 silc_server_packet_send_dest(server, remote,
4864 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4865 channel_ids[i], SILC_ID_CHANNEL,
4866 channel_modes[i]->data,
4867 channel_modes[i]->len,
4869 silc_buffer_free(channel_modes[i]);
4871 silc_free(channel_modes);
4874 if (channel_users_modes) {
4877 for (i = 0; i < channel_users_modes_c; i++) {
4878 if (!channel_users_modes[i])
4880 silc_buffer_push(channel_users_modes[i],
4881 channel_users_modes[i]->data -
4882 channel_users_modes[i]->head);
4883 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4884 channel_users_modes[i]->len);
4885 silc_server_packet_send_dest(server, remote,
4886 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4887 channel_ids[i], SILC_ID_CHANNEL,
4888 channel_users_modes[i]->data,
4889 channel_users_modes[i]->len,
4891 silc_buffer_free(channel_users_modes[i]);
4893 silc_free(channel_users_modes);
4896 if (channel_topics) {
4899 for (i = 0; i < channel_users_modes_c; i++) {
4900 if (!channel_topics[i])
4903 silc_buffer_push(channel_topics[i],
4904 channel_topics[i]->data -
4905 channel_topics[i]->head);
4906 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4907 channel_topics[i]->len);
4908 silc_server_packet_send_dest(server, remote,
4909 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4910 channel_ids[i], SILC_ID_CHANNEL,
4911 channel_topics[i]->data,
4912 channel_topics[i]->len,
4914 silc_buffer_free(channel_topics[i]);
4916 silc_free(channel_topics);
4919 if (channel_invites) {
4922 for (i = 0; i < channel_users_modes_c; i++) {
4923 if (!channel_invites[i])
4926 silc_buffer_push(channel_invites[i],
4927 channel_invites[i]->data -
4928 channel_invites[i]->head);
4929 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4930 channel_invites[i]->len);
4931 silc_server_packet_send_dest(server, remote,
4932 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4933 channel_ids[i], SILC_ID_CHANNEL,
4934 channel_invites[i]->data,
4935 channel_invites[i]->len,
4937 silc_buffer_free(channel_invites[i]);
4939 silc_free(channel_invites);
4945 for (i = 0; i < channel_users_modes_c; i++) {
4946 if (!channel_bans[i])
4949 silc_buffer_push(channel_bans[i],
4950 channel_bans[i]->data -
4951 channel_bans[i]->head);
4952 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4953 channel_bans[i]->len);
4954 silc_server_packet_send_dest(server, remote,
4955 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4956 channel_ids[i], SILC_ID_CHANNEL,
4957 channel_bans[i]->data,
4958 channel_bans[i]->len,
4960 silc_buffer_free(channel_bans[i]);
4962 silc_free(channel_bans);
4965 silc_free(channel_ids);
4968 /* Assembles user list and users mode list from the `channel'. */
4970 bool silc_server_get_users_on_channel(SilcServer server,
4971 SilcChannelEntry channel,
4972 SilcBuffer *user_list,
4973 SilcBuffer *mode_list,
4974 SilcUInt32 *user_count)
4976 SilcChannelClientEntry chl;
4977 SilcHashTableList htl;
4978 SilcBuffer client_id_list;
4979 SilcBuffer client_mode_list;
4981 SilcUInt32 list_count = 0, len = 0;
4983 if (!silc_hash_table_count(channel->user_list))
4986 silc_hash_table_list(channel->user_list, &htl);
4987 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4988 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4989 silc_hash_table_list_reset(&htl);
4991 client_id_list = silc_buffer_alloc(len);
4993 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4994 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
4995 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
4997 silc_hash_table_list(channel->user_list, &htl);
4998 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5000 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
5001 silc_buffer_put(client_id_list, idp->data, idp->len);
5002 silc_buffer_pull(client_id_list, idp->len);
5003 silc_buffer_free(idp);
5005 /* Client's mode on channel */
5006 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
5007 silc_buffer_pull(client_mode_list, 4);
5011 silc_hash_table_list_reset(&htl);
5012 silc_buffer_push(client_id_list,
5013 client_id_list->data - client_id_list->head);
5014 silc_buffer_push(client_mode_list,
5015 client_mode_list->data - client_mode_list->head);
5017 *user_list = client_id_list;
5018 *mode_list = client_mode_list;
5019 *user_count = list_count;
5023 /* Saves users and their modes to the `channel'. */
5025 void silc_server_save_users_on_channel(SilcServer server,
5026 SilcSocketConnection sock,
5027 SilcChannelEntry channel,
5028 SilcClientID *noadd,
5029 SilcBuffer user_list,
5030 SilcBuffer mode_list,
5031 SilcUInt32 user_count)
5036 SilcClientID *client_id;
5037 SilcClientEntry client;
5038 SilcIDCacheEntry cache;
5039 SilcChannelClientEntry chl;
5041 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5042 channel->channel_name));
5044 for (i = 0; i < user_count; i++) {
5046 SILC_GET16_MSB(idp_len, user_list->data + 2);
5048 client_id = silc_id_payload_parse_id(user_list->data, idp_len, NULL);
5049 silc_buffer_pull(user_list, idp_len);
5054 SILC_GET32_MSB(mode, mode_list->data);
5055 silc_buffer_pull(mode_list, 4);
5057 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
5058 silc_free(client_id);
5064 /* Check if we have this client cached already. */
5065 client = silc_idlist_find_client_by_id(server->local_list, client_id,
5066 server->server_type, &cache);
5068 client = silc_idlist_find_client_by_id(server->global_list,
5069 client_id, server->server_type,
5072 /* If router did not find such Client ID in its lists then this must
5073 be bogus client or some router in the net is buggy. */
5074 if (server->server_type != SILC_SERVER) {
5075 silc_free(client_id);
5079 /* We don't have that client anywhere, add it. The client is added
5080 to global list since server didn't have it in the lists so it must be
5082 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5083 silc_id_dup(client_id, SILC_ID_CLIENT),
5084 sock->user_data, NULL, 0);
5086 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5087 silc_free(client_id);
5091 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5096 silc_free(client_id);
5098 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5099 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5100 "%s", channel->channel_name));
5104 if (!silc_server_client_on_channel(client, channel, &chl)) {
5105 /* Client was not on the channel, add it. */
5106 chl = silc_calloc(1, sizeof(*chl));
5107 chl->client = client;
5109 chl->channel = channel;
5110 silc_hash_table_add(channel->user_list, chl->client, chl);
5111 silc_hash_table_add(client->channels, chl->channel, chl);
5112 channel->user_count++;
5120 /* Saves channels and channels user modes to the `client'. Removes
5121 the client from those channels that are not sent in the list but
5124 void silc_server_save_user_channels(SilcServer server,
5125 SilcSocketConnection sock,
5126 SilcClientEntry client,
5127 SilcBuffer channels,
5128 SilcBuffer channels_user_modes)
5131 SilcUInt32 *chumodes;
5132 SilcChannelPayload entry;
5133 SilcChannelEntry channel;
5134 SilcChannelID *channel_id;
5135 SilcChannelClientEntry chl;
5136 SilcHashTable ht = NULL;
5137 SilcHashTableList htl;
5141 if (!channels || !channels_user_modes ||
5142 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5145 ch = silc_channel_payload_parse_list(channels->data, channels->len);
5146 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5148 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5149 NULL, NULL, NULL, TRUE);
5150 silc_dlist_start(ch);
5151 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5152 /* Check if we have this channel, and add it if we don't have it.
5153 Also add the client on the channel unless it is there already. */
5154 channel_id = silc_channel_get_id_parse(entry);
5155 channel = silc_idlist_find_channel_by_id(server->local_list,
5158 channel = silc_idlist_find_channel_by_id(server->global_list,
5161 if (server->server_type != SILC_SERVER) {
5162 silc_free(channel_id);
5167 /* We don't have that channel anywhere, add it. */
5168 name = silc_channel_get_name(entry, NULL);
5169 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5170 channel_id, server->router,
5173 silc_free(channel_id);
5180 channel->mode = silc_channel_get_mode(entry);
5182 /* Add the client on the channel */
5183 if (!silc_server_client_on_channel(client, channel, &chl)) {
5184 chl = silc_calloc(1, sizeof(*chl));
5185 chl->client = client;
5186 chl->mode = chumodes[i++];
5187 chl->channel = channel;
5188 silc_hash_table_add(channel->user_list, chl->client, chl);
5189 silc_hash_table_add(client->channels, chl->channel, chl);
5190 channel->user_count++;
5193 chl->mode = chumodes[i++];
5196 silc_hash_table_add(ht, channel, channel);
5197 silc_free(channel_id);
5199 silc_channel_payload_list_free(ch);
5200 silc_free(chumodes);
5204 /* Go through the list again and remove client from channels that
5205 are no part of the list. */
5207 silc_hash_table_list(client->channels, &htl);
5208 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5209 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5210 silc_hash_table_del(chl->channel->user_list, chl->client);
5211 silc_hash_table_del(chl->client->channels, chl->channel);
5215 silc_hash_table_list_reset(&htl);
5216 silc_hash_table_free(ht);
5218 silc_hash_table_list(client->channels, &htl);
5219 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5220 silc_hash_table_del(chl->channel->user_list, chl->client);
5221 silc_hash_table_del(chl->client->channels, chl->channel);
5224 silc_hash_table_list_reset(&htl);
5228 /* Lookups route to the client indicated by the `id_data'. The connection
5229 object and internal data object is returned. Returns NULL if route
5230 could not be found to the client. If the `client_id' is specified then
5231 it is used and the `id_data' is ignored. */
5233 SilcSocketConnection
5234 silc_server_get_client_route(SilcServer server,
5235 unsigned char *id_data,
5237 SilcClientID *client_id,
5238 SilcIDListData *idata,
5239 SilcClientEntry *client_entry)
5242 SilcClientEntry client;
5244 SILC_LOG_DEBUG(("Start"));
5247 *client_entry = NULL;
5249 /* Decode destination Client ID */
5251 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
5253 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
5257 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5260 /* If the destination belongs to our server we don't have to route
5261 the packet anywhere but to send it to the local destination. */
5262 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5266 /* If we are router and the client has router then the client is in
5267 our cell but not directly connected to us. */
5268 if (server->server_type == SILC_ROUTER && client->router) {
5269 /* We are of course in this case the client's router thus the route
5270 to the client is the server who owns the client. So, we will send
5271 the packet to that server. */
5273 *idata = (SilcIDListData)client->router;
5274 return client->router->connection;
5277 /* Seems that client really is directly connected to us */
5279 *idata = (SilcIDListData)client;
5281 *client_entry = client;
5282 return client->connection;
5285 /* Destination belongs to someone not in this server. If we are normal
5286 server our action is to send the packet to our router. */
5287 if (server->server_type != SILC_ROUTER && !server->standalone) {
5290 *idata = (SilcIDListData)server->router;
5291 return SILC_PRIMARY_ROUTE(server);
5294 /* We are router and we will perform route lookup for the destination
5295 and send the packet to fastest route. */
5296 if (server->server_type == SILC_ROUTER && !server->standalone) {
5297 /* Check first that the ID is valid */
5298 client = silc_idlist_find_client_by_id(server->global_list, id,
5301 SilcSocketConnection dst_sock;
5303 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5307 *idata = (SilcIDListData)dst_sock->user_data;
5316 /* Encodes and returns channel list of channels the `client' has joined.
5317 Secret channels are not put to the list. */
5319 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5320 SilcClientEntry client,
5323 SilcBuffer *user_mode_list)
5325 SilcBuffer buffer = NULL;
5326 SilcChannelEntry channel;
5327 SilcChannelClientEntry chl;
5328 SilcHashTableList htl;
5331 SilcUInt16 name_len;
5335 *user_mode_list = NULL;
5337 silc_hash_table_list(client->channels, &htl);
5338 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5339 channel = chl->channel;
5341 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5343 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5346 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
5347 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
5348 name_len = strlen(channel->channel_name);
5350 len = 4 + name_len + id_len + 4;
5351 buffer = silc_buffer_realloc(buffer,
5352 (buffer ? buffer->truelen + len : len));
5353 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5354 silc_buffer_format(buffer,
5355 SILC_STR_UI_SHORT(name_len),
5356 SILC_STR_UI_XNSTRING(channel->channel_name,
5358 SILC_STR_UI_SHORT(id_len),
5359 SILC_STR_UI_XNSTRING(cid, id_len),
5360 SILC_STR_UI_INT(chl->channel->mode),
5362 silc_buffer_pull(buffer, len);
5365 if (user_mode_list) {
5366 *user_mode_list = silc_buffer_realloc(*user_mode_list,
5368 (*user_mode_list)->truelen + 4 :
5370 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5371 (*user_mode_list)->data));
5372 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5373 silc_buffer_pull(*user_mode_list, 4);
5376 silc_hash_table_list_reset(&htl);
5379 silc_buffer_push(buffer, buffer->data - buffer->head);
5380 if (user_mode_list && *user_mode_list)
5381 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5382 (*user_mode_list)->head));
5387 /* Timeout callback for unsuccessful rekey. The rekey did not go through
5390 SILC_TASK_CALLBACK(silc_server_rekey_timeout)
5392 SilcServerRekeyInternalContext *ctx = context;
5393 SilcServer server = app_context;
5394 SilcSocketConnection sock = ctx->sock;
5396 SILC_LOG_DEBUG(("Timeout occurred in rekey protocol with %s:%d [%s]",
5397 sock->hostname, sock->port,
5398 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5399 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5400 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5403 SILC_LOG_WARNING(("Timeout occurred in rekey protocol with %s:%d [%s]",
5404 sock->hostname, sock->port,
5405 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5406 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5407 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5410 if (sock->protocol) {
5411 silc_protocol_cancel(sock->protocol, server->schedule);
5412 silc_protocol_free(sock->protocol);
5413 sock->protocol = NULL;
5416 silc_packet_context_free(ctx->packet);
5418 silc_ske_free(ctx->ske);
5419 silc_socket_free(sock);
5422 /* Disconnect since we failed to rekey, the keys are probably wrong. */
5423 silc_server_disconnect_remote(server, sock,
5424 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
5425 if (sock->user_data)
5426 silc_server_free_sock_user_data(server, sock, NULL);
5429 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
5430 silc_server_create_connections(server);
5433 /* A timeout callback for the re-key. We will be the initiator of the
5436 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_callback)
5438 SilcServer server = app_context;
5439 SilcSocketConnection sock = (SilcSocketConnection)context;
5440 SilcIDListData idata = (SilcIDListData)sock->user_data;
5441 SilcProtocol protocol;
5442 SilcServerRekeyInternalContext *proto_ctx;
5447 /* Do not execute rekey with disabled connections, as it would not
5448 go through anyway. */
5449 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
5452 /* If rekey protocol is active already wait for it to finish */
5453 if (sock->protocol && sock->protocol->protocol &&
5454 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)
5457 /* If any other protocol is active do not start this protocol yet. */
5458 if (sock->protocol) {
5459 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
5460 silc_schedule_task_add(server->schedule, sock->sock,
5461 silc_server_rekey_callback,
5462 sock, 60, 0, SILC_TASK_TIMEOUT,
5463 SILC_TASK_PRI_NORMAL);
5467 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
5468 sock->hostname, sock->port,
5469 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5470 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5471 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5474 /* Allocate internal protocol context. This is sent as context
5476 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
5477 proto_ctx->server = (void *)server;
5478 proto_ctx->sock = silc_socket_dup(sock);
5479 proto_ctx->responder = FALSE;
5480 proto_ctx->pfs = idata->rekey->pfs;
5482 /* Perform rekey protocol. Will call the final callback after the
5483 protocol is over. */
5484 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
5485 &protocol, proto_ctx, silc_server_rekey_final);
5486 sock->protocol = protocol;
5488 /* Register timeout callback in case the rekey does not go through. */
5489 proto_ctx->timeout_task =
5490 silc_schedule_task_add(server->schedule, sock->sock,
5491 silc_server_rekey_timeout,
5493 (idata->rekey->timeout >
5494 server->config->key_exchange_timeout ?
5495 idata->rekey->timeout :
5496 server->config->key_exchange_timeout * 4), 0,
5500 /* Run the protocol */
5501 silc_protocol_execute(protocol, server->schedule, 0, 0);
5504 /* The final callback for the REKEY protocol. This will actually take the
5505 new key material into use. */
5507 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
5509 SilcProtocol protocol = (SilcProtocol)context;
5510 SilcServerRekeyInternalContext *ctx =
5511 (SilcServerRekeyInternalContext *)protocol->context;
5512 SilcServer server = (SilcServer)ctx->server;
5513 SilcSocketConnection sock = ctx->sock;
5514 SilcIDListData idata = (SilcIDListData)sock->user_data;
5516 if (ctx->timeout_task)
5517 silc_schedule_task_del(server->schedule, ctx->timeout_task);
5519 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
5520 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
5521 /* Error occured during protocol */
5522 SILC_LOG_ERROR(("Error occurred during rekey protocol with "
5523 "%s (%s)", sock->hostname, sock->ip));
5524 silc_protocol_cancel(protocol, server->schedule);
5525 silc_protocol_free(protocol);
5526 sock->protocol = NULL;
5528 silc_packet_context_free(ctx->packet);
5530 silc_ske_free(ctx->ske);
5531 silc_socket_free(sock);
5533 silc_server_disconnect_remote(server, sock,
5534 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
5535 if (sock->user_data)
5536 silc_server_free_sock_user_data(server, sock, NULL);
5539 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
5540 silc_server_create_connections(server);
5544 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
5545 sock->hostname, sock->port,
5546 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
5547 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
5548 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
5551 /* Purge the outgoing data queue to assure that all rekey packets really
5552 go to the network before we quit the protocol. */
5553 silc_server_packet_queue_purge(server, sock);
5555 /* Re-register re-key timeout */
5556 if (ctx->responder == FALSE)
5557 silc_schedule_task_add(server->schedule, sock->sock,
5558 silc_server_rekey_callback,
5559 sock, idata->rekey->timeout, 0,
5560 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
5563 silc_protocol_free(protocol);
5564 sock->protocol = NULL;
5566 silc_packet_context_free(ctx->packet);
5568 silc_ske_free(ctx->ske);
5569 silc_socket_free(sock);
5573 /* Task callback used to retrieve network statistical information from
5574 router server once in a while. */
5576 SILC_TASK_CALLBACK(silc_server_get_stats)
5578 SilcServer server = (SilcServer)context;
5579 SilcBuffer idp, packet;
5581 if (!server->standalone) {
5582 SILC_LOG_DEBUG(("Retrieving stats from router"));
5583 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5584 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5585 ++server->cmd_ident, 1,
5586 1, idp->data, idp->len);
5587 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5588 SILC_PACKET_COMMAND, 0, packet->data,
5589 packet->len, FALSE);
5590 silc_buffer_free(packet);
5591 silc_buffer_free(idp);
5594 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
5595 server, 120, 0, SILC_TASK_TIMEOUT,