5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * This is the actual SILC server than handles everything relating to
22 * servicing the SILC connections. This is also a SILC router as a router
23 * is also normal server.
27 #include "serverincludes.h"
28 #include "server_internal.h"
30 /* Static prototypes */
31 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
32 SILC_TASK_CALLBACK(silc_server_connect_router);
33 SILC_TASK_CALLBACK(silc_server_connect_to_router);
34 SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
35 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
36 SILC_TASK_CALLBACK(silc_server_accept_new_connection);
37 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second);
38 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final);
39 SILC_TASK_CALLBACK(silc_server_packet_process);
40 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
41 SILC_TASK_CALLBACK(silc_server_close_connection_final);
42 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout);
43 SILC_TASK_CALLBACK(silc_server_timeout_remote);
44 SILC_TASK_CALLBACK(silc_server_channel_key_rekey);
45 SILC_TASK_CALLBACK(silc_server_failure_callback);
46 SILC_TASK_CALLBACK(silc_server_rekey_callback);
47 SILC_TASK_CALLBACK(silc_server_get_stats);
49 /* Allocates a new SILC server object. This has to be done before the server
50 can be used. After allocation one must call silc_server_init to initialize
51 the server. The new allocated server object is returned to the new_server
54 int silc_server_alloc(SilcServer *new_server)
58 SILC_LOG_DEBUG(("Allocating new server object"));
60 server = silc_calloc(1, sizeof(*server));
61 server->server_type = SILC_SERVER;
62 server->standalone = TRUE;
63 server->local_list = silc_calloc(1, sizeof(*server->local_list));
64 server->global_list = silc_calloc(1, sizeof(*server->global_list));
65 server->pending_commands = silc_dlist_init();
67 server->sim = silc_dlist_init();
75 /* Free's the SILC server object. This is called at the very end before
78 void silc_server_free(SilcServer server)
84 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
85 silc_dlist_del(server->sim, sim);
88 silc_dlist_uninit(server->sim);
91 silc_server_config_unref(&server->config_ref);
93 silc_rng_free(server->rng);
95 silc_pkcs_free(server->pkcs);
96 if (server->public_key)
97 silc_pkcs_public_key_free(server->public_key);
98 if (server->private_key)
99 silc_pkcs_private_key_free(server->private_key);
100 if (server->pending_commands)
101 silc_dlist_uninit(server->pending_commands);
102 if (server->id_entry)
103 silc_idlist_del_server(server->local_list, server->id_entry);
105 silc_idcache_free(server->local_list->clients);
106 silc_idcache_free(server->local_list->servers);
107 silc_idcache_free(server->local_list->channels);
108 silc_idcache_free(server->global_list->clients);
109 silc_idcache_free(server->global_list->servers);
110 silc_idcache_free(server->global_list->channels);
111 silc_hash_table_free(server->watcher_list);
113 silc_free(server->sockets);
118 /* Opens a listening port.
119 XXX This function will become more general and will support multiple
122 static bool silc_server_listen(SilcServer server, const char *server_ip,
123 SilcUInt16 port, int *sock)
125 *sock = silc_net_create_server(port, server_ip);
127 SILC_LOG_ERROR(("Could not create server listener: %s on %hu",
134 /* Adds a secondary listener. */
135 bool silc_server_init_secondary(SilcServer server)
137 int sock=0, sock_list[server->config->param.connections_max];
138 SilcSocketConnection newsocket = NULL;
139 SilcServerConfigServerInfoInterface *interface;
141 for (interface = server->config->server_info->secondary; interface;
142 interface = interface->next, sock++) {
144 if (!silc_server_listen(server,
145 interface->server_ip, interface->port, &sock_list[sock]))
148 /* Set socket to non-blocking mode */
149 silc_net_set_socket_nonblock(sock_list[sock]);
151 /* Add ourselves also to the socket table. The entry allocated above
152 is sent as argument for fast referencing in the future. */
153 silc_socket_alloc(sock_list[sock],
154 SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
155 server->sockets[sock_list[sock]] = newsocket;
157 /* Perform name and address lookups to resolve the listenning address
159 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
161 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
163 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
164 newsocket->hostname ? newsocket->hostname :
165 newsocket->ip ? newsocket->ip : ""));
166 server->stat.conn_failures++;
169 if (!newsocket->hostname)
170 newsocket->hostname = strdup(newsocket->ip);
172 newsocket->port = silc_net_get_local_port(sock);
174 newsocket->user_data = (void *)server->id_entry;
175 silc_schedule_task_add(server->schedule, sock_list[sock],
176 silc_server_accept_new_connection,
177 (void *)server, 0, 0,
179 SILC_TASK_PRI_NORMAL);
187 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
192 /* Initializes the entire SILC server. This is called always before running
193 the server. This is called only once at the initialization of the program.
194 This binds the server to its listenning port. After this function returns
195 one should call silc_server_run to start the server. This returns TRUE
196 when everything is ok to run the server. Configuration file must be
197 read and parsed before calling this. */
199 bool silc_server_init(SilcServer server)
203 SilcServerEntry id_entry;
204 SilcIDListPurge purge;
205 SilcSocketConnection newsocket = NULL;
207 SILC_LOG_DEBUG(("Initializing server"));
209 server->starttime = time(NULL);
211 /* Take config object for us */
212 silc_server_config_ref(&server->config_ref, server->config,
215 /* Steal public and private key from the config object */
216 server->public_key = server->config->server_info->public_key;
217 server->private_key = server->config->server_info->private_key;
218 server->config->server_info->public_key = NULL;
219 server->config->server_info->private_key = NULL;
221 /* Register all configured ciphers, PKCS and hash functions. */
222 if (!silc_server_config_register_ciphers(server))
223 silc_cipher_register_default();
224 if (!silc_server_config_register_pkcs(server))
225 silc_pkcs_register_default();
226 if (!silc_server_config_register_hashfuncs(server))
227 silc_hash_register_default();
228 if (!silc_server_config_register_hmacs(server))
229 silc_hmac_register_default();
231 /* Initialize random number generator for the server. */
232 server->rng = silc_rng_alloc();
233 silc_rng_init(server->rng);
234 silc_rng_global_init(server->rng);
236 /* Initialize hash functions for server to use */
237 silc_hash_alloc("md5", &server->md5hash);
238 silc_hash_alloc("sha1", &server->sha1hash);
240 /* Allocate PKCS context for local public and private keys */
241 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
243 silc_pkcs_public_key_set(server->pkcs, server->public_key);
244 silc_pkcs_private_key_set(server->pkcs, server->private_key);
246 /* Initialize the scheduler */
247 server->schedule = silc_schedule_init(server->config->param.connections_max);
248 if (!server->schedule)
251 /* First, register log files configuration for error output */
252 silc_server_config_setlogfiles(server);
254 /* Initialize ID caches */
255 server->local_list->clients =
256 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
257 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
258 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
260 /* These are allocated for normal server as well as these hold some
261 global information that the server has fetched from its router. For
262 router these are used as they are supposed to be used on router. */
263 server->global_list->clients =
264 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
265 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
266 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
268 /* Init watcher list */
269 server->watcher_list =
270 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
271 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
273 if (!server->watcher_list)
276 /* Create a listening server */
277 if (!silc_server_listen(server,
278 server->config->server_info->primary == NULL ? NULL :
279 server->config->server_info->primary->server_ip,
280 server->config->server_info->primary == NULL ? 0 :
281 server->config->server_info->primary->port,
285 /* Set socket to non-blocking mode */
286 silc_net_set_socket_nonblock(sock);
289 /* Allocate the entire socket list that is used in server. Eventually
290 all connections will have entry in this table (it is a table of
291 pointers to the actual object that is allocated individually
293 server->sockets = silc_calloc(server->config->param.connections_max,
294 sizeof(*server->sockets));
295 if (!server->sockets)
298 /* Add ourselves also to the socket table. The entry allocated above
299 is sent as argument for fast referencing in the future. */
300 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
301 server->sockets[sock] = newsocket;
303 /* Perform name and address lookups to resolve the listenning address
305 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
307 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
309 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
310 newsocket->hostname ? newsocket->hostname :
311 newsocket->ip ? newsocket->ip : ""));
312 server->stat.conn_failures++;
315 if (!newsocket->hostname)
316 newsocket->hostname = strdup(newsocket->ip);
318 newsocket->port = silc_net_get_local_port(sock);
320 /* Create a Server ID for the server. */
321 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
326 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
327 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
328 server->id_type = SILC_ID_SERVER;
329 server->server_name = server->config->server_info->server_name;
330 server->config->server_info->server_name = NULL;
332 /* Add ourselves to the server list. We don't have a router yet
333 beacuse we haven't established a route yet. It will be done later.
334 For now, NULL is sent as router. This allocates new entry to
337 silc_idlist_add_server(server->local_list, strdup(server->server_name),
338 server->server_type, server->id, NULL, NULL);
340 SILC_LOG_ERROR(("Could not add ourselves to cache"));
343 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
345 /* Put the allocated socket pointer also to the entry allocated above
346 for fast back-referencing to the socket list. */
347 newsocket->user_data = (void *)id_entry;
348 id_entry->connection = (void *)newsocket;
349 server->id_entry = id_entry;
351 /* Register protocols */
352 silc_server_protocols_register();
354 /* Add the first task to the scheduler. This is task that is executed by
355 timeout. It expires as soon as the caller calls silc_server_run. This
356 task performs authentication protocol and key exchange with our
358 silc_schedule_task_add(server->schedule, 0,
359 silc_server_connect_to_router,
360 (void *)server, 0, 1,
362 SILC_TASK_PRI_NORMAL);
364 /* Add listener task to the scheduler. This task receives new connections
365 to the server. This task remains on the queue until the end of the
367 silc_schedule_task_add(server->schedule, sock,
368 silc_server_accept_new_connection,
369 (void *)server, 0, 0,
371 SILC_TASK_PRI_NORMAL);
373 if (silc_server_init_secondary(server) == FALSE)
376 server->listenning = TRUE;
378 /* If server connections has been configured then we must be router as
379 normal server cannot have server connections, only router connections. */
380 if (server->config->servers) {
381 SilcServerConfigServer *ptr = server->config->servers;
383 server->server_type = SILC_ROUTER;
385 if (ptr->backup_router) {
386 server->server_type = SILC_BACKUP_ROUTER;
387 server->backup_router = TRUE;
388 server->id_entry->server_type = SILC_BACKUP_ROUTER;
395 /* Register the ID Cache purge task. This periodically purges the ID cache
396 and removes the expired cache entries. */
398 /* Clients local list */
399 purge = silc_calloc(1, sizeof(*purge));
400 purge->cache = server->local_list->clients;
401 purge->schedule = server->schedule;
402 purge->timeout = 600;
403 silc_schedule_task_add(purge->schedule, 0,
405 (void *)purge, purge->timeout, 0,
406 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
408 /* Clients global list */
409 purge = silc_calloc(1, sizeof(*purge));
410 purge->cache = server->global_list->clients;
411 purge->schedule = server->schedule;
412 purge->timeout = 300;
413 silc_schedule_task_add(purge->schedule, 0,
415 (void *)purge, purge->timeout, 0,
416 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
418 /* If we are normal server we'll retrieve network statisticial information
419 once in a while from the router. */
420 if (server->server_type == SILC_SERVER)
421 silc_schedule_task_add(purge->schedule, 0, silc_server_get_stats,
422 server, 10, 0, SILC_TASK_TIMEOUT,
425 SILC_LOG_DEBUG(("Server initialized"));
427 /* We are done here, return succesfully */
431 silc_server_config_unref(&server->config_ref);
432 silc_net_close_server(sock);
436 /* This function basically reads the config file again and switches the config
437 object pointed by the server object. After that, we have to fix various
438 things such as the server_name and the listening ports.
439 Keep in mind that we no longer have the root privileges at this point. */
441 bool silc_server_rehash(SilcServer server)
443 SilcServerConfig newconfig;
445 SILC_LOG_INFO(("Rehashing server"));
447 /* Reset the logging system */
448 silc_log_quick = TRUE;
449 silc_log_flush_all();
451 /* Start the main rehash phase (read again the config file) */
452 newconfig = silc_server_config_alloc(server->config_file);
454 SILC_LOG_ERROR(("Rehash FAILED."));
458 /* Reinit scheduler if necessary */
459 if (newconfig->param.connections_max > server->config->param.connections_max)
460 if (!silc_schedule_reinit(server->schedule,
461 newconfig->param.connections_max))
464 /* Fix the server_name field */
465 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
466 silc_free(server->server_name);
467 server->server_name = newconfig->server_info->server_name;
468 newconfig->server_info->server_name = NULL;
470 /* Update the idcache list with a fresh pointer */
471 silc_free(server->id_entry->server_name);
472 server->id_entry->server_name = strdup(server->server_name);
473 if (!silc_idcache_del_by_context(server->local_list->servers,
476 if (!silc_idcache_add(server->local_list->servers,
477 server->id_entry->server_name,
478 server->id_entry->id, server->id_entry, 0, NULL))
483 silc_server_config_setlogfiles(server);
485 /* Change new key pair if necessary */
486 if (newconfig->server_info->public_key &&
487 !silc_pkcs_public_key_compare(server->public_key,
488 newconfig->server_info->public_key)) {
489 silc_pkcs_public_key_free(server->public_key);
490 silc_pkcs_private_key_free(server->private_key);
491 server->public_key = newconfig->server_info->public_key;
492 server->private_key = newconfig->server_info->private_key;
493 newconfig->server_info->public_key = NULL;
494 newconfig->server_info->private_key = NULL;
496 /* Allocate PKCS context for local public and private keys */
497 silc_pkcs_free(server->pkcs);
498 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
500 silc_pkcs_public_key_set(server->pkcs, server->public_key);
501 silc_pkcs_private_key_set(server->pkcs, server->private_key);
504 /* Go through all configured routers after rehash */
505 silc_schedule_task_add(server->schedule, 0,
506 silc_server_connect_to_router,
507 (void *)server, 0, 1,
509 SILC_TASK_PRI_NORMAL);
511 /* Check whether our router status has changed */
512 if (newconfig->servers) {
513 SilcServerConfigServer *ptr = newconfig->servers;
515 server->server_type = SILC_ROUTER;
517 if (ptr->backup_router) {
518 server->server_type = SILC_BACKUP_ROUTER;
519 server->backup_router = TRUE;
520 server->id_entry->server_type = SILC_BACKUP_ROUTER;
527 /* Our old config is gone now. We'll unreference our reference made in
528 silc_server_init and then destroy it since we are destroying it
529 underneath the application (layer which called silc_server_init). */
530 silc_server_config_unref(&server->config_ref);
531 silc_server_config_destroy(server->config);
533 /* Take new config context */
534 server->config = newconfig;
535 silc_server_config_ref(&server->config_ref, server->config, server->config);
537 SILC_LOG_DEBUG(("Server rehashed"));
542 /* The heart of the server. This runs the scheduler thus runs the server.
543 When this returns the server has been stopped and the program will
546 void silc_server_run(SilcServer server)
548 SILC_LOG_INFO(("SILC Server started"));
550 /* Start the scheduler, the heart of the SILC server. When this returns
551 the program will be terminated. */
552 silc_schedule(server->schedule);
555 /* Stops the SILC server. This function is used to shutdown the server.
556 This is usually called after the scheduler has returned. After stopping
557 the server one should call silc_server_free. */
559 void silc_server_stop(SilcServer server)
561 SILC_LOG_DEBUG(("Stopping server"));
563 if (server->schedule) {
564 silc_schedule_stop(server->schedule);
565 silc_schedule_uninit(server->schedule);
566 server->schedule = NULL;
569 silc_server_protocols_unregister();
571 SILC_LOG_DEBUG(("Server stopped"));
574 /* Function that is called when the network connection to a router has
575 been established. This will continue with the key exchange protocol
576 with the remote router. */
578 void silc_server_start_key_exchange(SilcServer server,
579 SilcServerConnection sconn,
582 SilcSocketConnection newsocket;
583 SilcProtocol protocol;
584 SilcServerKEInternalContext *proto_ctx;
585 SilcServerConfigRouter *conn =
586 (SilcServerConfigRouter *) sconn->conn.ref_ptr;
589 /* Cancel any possible retry timeouts */
590 silc_schedule_task_del_by_callback(server->schedule,
591 silc_server_connect_router);
593 /* Set socket options */
594 silc_net_set_socket_nonblock(sock);
595 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
597 /* Create socket connection for the connection. Even though we
598 know that we are connecting to a router we will mark the socket
599 to be unknown connection until we have executed authentication
601 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
602 server->sockets[sock] = newsocket;
603 newsocket->hostname = strdup(sconn->remote_host);
604 newsocket->ip = strdup(sconn->remote_host);
605 newsocket->port = sconn->remote_port;
606 sconn->sock = newsocket;
608 /* Allocate internal protocol context. This is sent as context
610 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
611 proto_ctx->server = (void *)server;
612 proto_ctx->context = (void *)sconn;
613 proto_ctx->sock = newsocket;
614 proto_ctx->rng = server->rng;
615 proto_ctx->responder = FALSE;
617 /* Set Key Exchange flags from configuration, but fall back to global
619 SILC_GET_SKE_FLAGS(conn, proto_ctx);
620 if (server->config->param.key_exchange_pfs)
621 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
623 /* Perform key exchange protocol. silc_server_connect_to_router_second
624 will be called after the protocol is finished. */
625 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
626 &protocol, proto_ctx,
627 silc_server_connect_to_router_second);
628 newsocket->protocol = protocol;
630 /* Register a timeout task that will be executed if the protocol
631 is not executed within set limit. */
632 proto_ctx->timeout_task =
633 silc_schedule_task_add(server->schedule, sock,
634 silc_server_timeout_remote,
635 server, server->config->key_exchange_timeout, 0,
639 /* Register the connection for network input and output. This sets
640 that scheduler will listen for incoming packets for this connection
641 and sets that outgoing packets may be sent to this connection as
642 well. However, this doesn't set the scheduler for outgoing traffic,
643 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
644 later when outgoing data is available. */
645 context = (void *)server;
646 SILC_REGISTER_CONNECTION_FOR_IO(sock);
648 /* Run the protocol */
649 silc_protocol_execute(protocol, server->schedule, 0, 0);
652 /* Timeout callback that will be called to retry connecting to remote
653 router. This is used by both normal and router server. This will wait
654 before retrying the connecting. The timeout is generated by exponential
655 backoff algorithm. */
657 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
659 SilcServerConnection sconn = (SilcServerConnection)context;
660 SilcServer server = sconn->server;
661 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
662 SilcServerConfigConnParams *param =
663 (conn->param ? conn->param : &server->config->param);
665 SILC_LOG_INFO(("Retrying connecting to a router"));
667 /* Calculate next timeout */
668 if (sconn->retry_count >= 1) {
669 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
670 if (sconn->retry_timeout > param->reconnect_interval_max)
671 sconn->retry_timeout = param->reconnect_interval_max;
673 sconn->retry_timeout = param->reconnect_interval;
675 sconn->retry_count++;
676 sconn->retry_timeout = sconn->retry_timeout +
677 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
679 /* If we've reached max retry count, give up. */
680 if ((sconn->retry_count > param->reconnect_count) &&
681 !param->reconnect_keep_trying) {
682 SILC_LOG_ERROR(("Could not connect to router, giving up"));
683 silc_server_config_unref(&sconn->conn);
684 silc_free(sconn->remote_host);
685 silc_free(sconn->backup_replace_ip);
690 /* We will lookup a fresh pointer later */
691 silc_server_config_unref(&sconn->conn);
693 /* Wait one before retrying */
694 silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
695 context, sconn->retry_timeout, 0,
696 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
699 /* Generic routine to use connect to a router. */
701 SILC_TASK_CALLBACK(silc_server_connect_router)
703 SilcServerConnection sconn = (SilcServerConnection)context;
704 SilcServer server = sconn->server;
705 SilcServerConfigRouter *rconn;
708 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
709 (sconn->backup ? "backup router" : "router"),
710 sconn->remote_host, sconn->remote_port));
712 server->router_connect = time(NULL);
713 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
716 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
717 (sconn->backup ? "backup router" : "router"),
718 sconn->remote_host, sconn->remote_port));
719 silc_free(sconn->remote_host);
720 silc_free(sconn->backup_replace_ip);
724 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
726 /* Connect to remote host */
727 sock = silc_net_create_connection(server->config->server_info->primary == NULL ? NULL :
728 server->config->server_info->primary->server_ip,
732 SILC_LOG_ERROR(("Could not connect to router %s:%d",
733 sconn->remote_host, sconn->remote_port));
734 if (!sconn->no_reconnect)
735 silc_schedule_task_add(server->schedule, 0,
736 silc_server_connect_to_router_retry,
737 context, 0, 1, SILC_TASK_TIMEOUT,
738 SILC_TASK_PRI_NORMAL);
740 silc_server_config_unref(&sconn->conn);
744 /* Continue with key exchange protocol */
745 silc_server_start_key_exchange(server, sconn, sock);
748 /* This function connects to our primary router or if we are a router this
749 establishes all our primary routes. This is called at the start of the
750 server to do authentication and key exchange with our router - called
753 SILC_TASK_CALLBACK(silc_server_connect_to_router)
755 SilcServer server = (SilcServer)context;
756 SilcServerConnection sconn;
757 SilcServerConfigRouter *ptr;
759 SILC_LOG_DEBUG(("Connecting to router(s)"));
761 if (server->server_type == SILC_SERVER) {
762 SILC_LOG_DEBUG(("We are normal server"));
763 } else if (server->server_type == SILC_ROUTER) {
764 SILC_LOG_DEBUG(("We are router"));
766 SILC_LOG_DEBUG(("We are backup router/normal server"));
769 if (!server->config->routers) {
770 /* There wasn't a configured router, we will continue but we don't
771 have a connection to outside world. We will be standalone server. */
772 SILC_LOG_DEBUG(("No router(s), server will be standalone"));
773 server->standalone = TRUE;
777 /* Cancel any possible retry timeouts */
778 silc_schedule_task_del_by_callback(server->schedule,
779 silc_server_connect_router);
780 silc_schedule_task_del_by_callback(server->schedule,
781 silc_server_connect_to_router_retry);
783 /* Create the connections to all our routes */
784 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
786 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
787 ptr->backup_router ? "Backup router" : "Router",
788 ptr->initiator ? "Initiator" : "Responder",
789 ptr->host, ptr->port));
791 if (ptr->initiator) {
792 /* Check whether we are connected to this host already */
793 if (silc_server_num_sockets_by_remote(server,
794 silc_net_is_ip(ptr->host) ?
796 silc_net_is_ip(ptr->host) ?
797 NULL : ptr->host, ptr->port,
798 SILC_SOCKET_TYPE_ROUTER)) {
799 SILC_LOG_DEBUG(("We are already connected to this router"));
803 /* Allocate connection object for hold connection specific stuff. */
804 sconn = silc_calloc(1, sizeof(*sconn));
805 sconn->server = server;
806 sconn->remote_host = strdup(ptr->host);
807 sconn->remote_port = ptr->port;
808 sconn->backup = ptr->backup_router;
810 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
811 sconn->backup_replace_port = ptr->backup_replace_port;
814 if (!server->router_conn && !sconn->backup)
815 server->router_conn = sconn;
817 silc_schedule_task_add(server->schedule, 0,
818 silc_server_connect_router,
819 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
820 SILC_TASK_PRI_NORMAL);
825 /* Second part of connecting to router(s). Key exchange protocol has been
826 executed and now we will execute authentication protocol. */
828 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
830 SilcProtocol protocol = (SilcProtocol)context;
831 SilcServerKEInternalContext *ctx =
832 (SilcServerKEInternalContext *)protocol->context;
833 SilcServer server = (SilcServer)ctx->server;
834 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
835 SilcSocketConnection sock = ctx->sock;
836 SilcServerConnAuthInternalContext *proto_ctx;
837 SilcServerConfigRouter *conn = NULL;
839 SILC_LOG_DEBUG(("Start"));
841 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
842 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
843 /* Error occured during protocol */
844 silc_protocol_free(protocol);
845 sock->protocol = NULL;
846 silc_ske_free_key_material(ctx->keymat);
848 silc_packet_context_free(ctx->packet);
850 silc_ske_free(ctx->ske);
851 silc_free(ctx->dest_id);
853 silc_server_config_unref(&sconn->conn);
854 silc_free(sconn->remote_host);
855 silc_free(sconn->backup_replace_ip);
857 silc_schedule_task_del_by_callback(server->schedule,
858 silc_server_failure_callback);
859 silc_server_disconnect_remote(server, sock,
860 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
864 /* We now have the key material as the result of the key exchange
865 protocol. Take the key material into use. Free the raw key material
866 as soon as we've set them into use. */
867 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
868 ctx->sock, ctx->keymat,
869 ctx->ske->prop->cipher,
870 ctx->ske->prop->pkcs,
871 ctx->ske->prop->hash,
872 ctx->ske->prop->hmac,
873 ctx->ske->prop->group,
875 silc_protocol_free(protocol);
876 sock->protocol = NULL;
877 silc_ske_free_key_material(ctx->keymat);
879 silc_packet_context_free(ctx->packet);
881 silc_ske_free(ctx->ske);
882 silc_free(ctx->dest_id);
884 silc_server_config_unref(&sconn->conn);
885 silc_free(sconn->remote_host);
886 silc_free(sconn->backup_replace_ip);
888 silc_schedule_task_del_by_callback(server->schedule,
889 silc_server_failure_callback);
890 silc_server_disconnect_remote(server, sock,
891 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
894 silc_ske_free_key_material(ctx->keymat);
896 /* Allocate internal context for the authentication protocol. This
897 is sent as context for the protocol. */
898 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
899 proto_ctx->server = (void *)server;
900 proto_ctx->context = (void *)sconn;
901 proto_ctx->sock = sock;
902 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
903 proto_ctx->dest_id_type = ctx->dest_id_type;
904 proto_ctx->dest_id = ctx->dest_id;
906 /* Resolve the authentication method used in this connection. Check if
907 we find a match from user configured connections */
908 if (!sconn->conn.ref_ptr)
909 conn = silc_server_config_find_router_conn(server, sock->hostname,
912 conn = sconn->conn.ref_ptr;
915 /* Match found. Use the configured authentication method. Take only
916 the passphrase, since for public key auth we automatically use
917 our local key pair. */
918 if (conn->passphrase) {
919 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
920 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
922 proto_ctx->auth_data = strdup(conn->passphrase);
923 proto_ctx->auth_data_len = strlen(conn->passphrase);
924 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
926 } else if (conn->publickeys) {
927 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
929 proto_ctx->auth_meth = SILC_AUTH_NONE;
932 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
933 sock->hostname, sock->ip, sock->port));
934 silc_protocol_free(protocol);
935 sock->protocol = NULL;
937 silc_packet_context_free(ctx->packet);
939 silc_ske_free(ctx->ske);
940 silc_free(ctx->dest_id);
942 silc_server_config_unref(&sconn->conn);
943 silc_free(sconn->remote_host);
944 silc_free(sconn->backup_replace_ip);
946 silc_schedule_task_del_by_callback(server->schedule,
947 silc_server_failure_callback);
948 silc_server_disconnect_remote(server, sock,
949 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
953 /* Free old protocol as it is finished now */
954 silc_protocol_free(protocol);
956 silc_packet_context_free(ctx->packet);
958 sock->protocol = NULL;
960 /* Allocate the authentication protocol. This is allocated here
961 but we won't start it yet. We will be receiving party of this
962 protocol thus we will wait that connecting party will make
964 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
965 &sock->protocol, proto_ctx,
966 silc_server_connect_to_router_final);
968 /* Register timeout task. If the protocol is not executed inside
969 this timelimit the connection will be terminated. */
970 proto_ctx->timeout_task =
971 silc_schedule_task_add(server->schedule, sock->sock,
972 silc_server_timeout_remote,
974 server->config->conn_auth_timeout, 0,
978 /* Run the protocol */
979 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
982 /* Finalizes the connection to router. Registers a server task to the
983 queue so that we can accept new connections. */
985 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
987 SilcProtocol protocol = (SilcProtocol)context;
988 SilcServerConnAuthInternalContext *ctx =
989 (SilcServerConnAuthInternalContext *)protocol->context;
990 SilcServer server = (SilcServer)ctx->server;
991 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
992 SilcSocketConnection sock = ctx->sock;
993 SilcServerEntry id_entry;
995 SilcServerHBContext hb_context;
996 unsigned char *id_string;
998 SilcIDListData idata;
999 SilcServerConfigRouter *conn = NULL;
1000 SilcServerConfigConnParams *param = NULL;
1002 SILC_LOG_DEBUG(("Start"));
1004 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1005 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1006 /* Error occured during protocol */
1007 silc_free(ctx->dest_id);
1008 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1013 /* Add a task to the queue. This task receives new connections to the
1014 server. This task remains on the queue until the end of the program. */
1015 if (!server->listenning && !sconn->backup) {
1016 silc_schedule_task_add(server->schedule, server->sock,
1017 silc_server_accept_new_connection,
1018 (void *)server, 0, 0,
1020 SILC_TASK_PRI_NORMAL);
1021 server->listenning = TRUE;
1024 /* Send NEW_SERVER packet to the router. We will become registered
1025 to the SILC network after sending this packet. */
1026 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
1027 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
1028 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
1029 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1030 silc_buffer_format(packet,
1031 SILC_STR_UI_SHORT(id_len),
1032 SILC_STR_UI_XNSTRING(id_string, id_len),
1033 SILC_STR_UI_SHORT(strlen(server->server_name)),
1034 SILC_STR_UI_XNSTRING(server->server_name,
1035 strlen(server->server_name)),
1038 /* Send the packet */
1039 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
1040 packet->data, packet->len, TRUE);
1041 silc_buffer_free(packet);
1042 silc_free(id_string);
1044 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
1046 /* Check that we do not have this ID already */
1047 id_entry = silc_idlist_find_server_by_id(server->local_list,
1048 ctx->dest_id, TRUE, NULL);
1050 silc_idcache_del_by_context(server->local_list->servers, id_entry);
1052 id_entry = silc_idlist_find_server_by_id(server->global_list,
1053 ctx->dest_id, TRUE, NULL);
1055 silc_idcache_del_by_context(server->global_list->servers, id_entry);
1058 SILC_LOG_DEBUG(("New server id(%s)",
1059 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
1061 /* Add the connected router to global server list */
1062 id_entry = silc_idlist_add_server(server->global_list,
1063 strdup(sock->hostname),
1064 SILC_ROUTER, ctx->dest_id, NULL, sock);
1066 silc_free(ctx->dest_id);
1067 SILC_LOG_ERROR(("Cannot add new server entry to cache"));
1068 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1073 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1074 silc_free(sock->user_data);
1075 sock->user_data = (void *)id_entry;
1076 sock->type = SILC_SOCKET_TYPE_ROUTER;
1077 idata = (SilcIDListData)sock->user_data;
1078 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1080 conn = sconn->conn.ref_ptr;
1081 param = &server->config->param;
1082 if (conn && conn->param)
1083 param = conn->param;
1085 /* Perform keepalive. The `hb_context' will be freed automatically
1086 when finally calling the silc_socket_free function. */
1087 hb_context = silc_calloc(1, sizeof(*hb_context));
1088 hb_context->server = server;
1089 silc_socket_set_heartbeat(sock, param->keepalive_secs, hb_context,
1090 silc_server_perform_heartbeat,
1093 /* Register re-key timeout */
1094 idata->rekey->timeout = param->key_exchange_rekey;
1095 idata->rekey->context = (void *)server;
1096 silc_schedule_task_add(server->schedule, sock->sock,
1097 silc_server_rekey_callback,
1098 (void *)sock, idata->rekey->timeout, 0,
1099 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1101 if (!sconn->backup) {
1102 /* Mark this router our primary router if we're still standalone */
1103 if (server->standalone) {
1104 server->id_entry->router = id_entry;
1105 server->router = id_entry;
1106 server->standalone = FALSE;
1108 /* If we are router then announce our possible servers. */
1109 if (server->server_type == SILC_ROUTER)
1110 silc_server_announce_servers(server, FALSE, 0,
1111 server->router->connection);
1113 /* Announce our clients and channels to the router */
1114 silc_server_announce_clients(server, 0, server->router->connection);
1115 silc_server_announce_channels(server, 0, server->router->connection);
1118 /* Add this server to be our backup router */
1119 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1120 sconn->backup_replace_port, FALSE);
1123 sock->protocol = NULL;
1125 /* Call the completion callback to indicate that we've connected to
1127 if (sconn->callback)
1128 (*sconn->callback)(server, id_entry, sconn->callback_context);
1131 /* Free the temporary connection data context */
1133 silc_server_config_unref(&sconn->conn);
1134 silc_free(sconn->remote_host);
1135 silc_free(sconn->backup_replace_ip);
1138 if (sconn == server->router_conn)
1139 server->router_conn = NULL;
1141 /* Free the protocol object */
1142 if (sock->protocol == protocol)
1143 sock->protocol = NULL;
1144 silc_protocol_free(protocol);
1146 silc_packet_context_free(ctx->packet);
1148 silc_ske_free(ctx->ske);
1149 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1150 silc_free(ctx->auth_data);
1154 /* Host lookup callback that is called after the incoming connection's
1155 IP and FQDN lookup is performed. This will actually check the acceptance
1156 of the incoming connection and will register the key exchange protocol
1157 for this connection. */
1160 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1163 SilcServerKEInternalContext *proto_ctx =
1164 (SilcServerKEInternalContext *)context;
1165 SilcServer server = (SilcServer)proto_ctx->server;
1166 SilcServerConfigClient *cconfig = NULL;
1167 SilcServerConfigServer *sconfig = NULL;
1168 SilcServerConfigRouter *rconfig = NULL;
1169 SilcServerConfigDeny *deny;
1172 context = (void *)server;
1174 SILC_LOG_DEBUG(("Start"));
1176 /* Check whether we could resolve both IP and FQDN. */
1177 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1178 server->config->require_reverse_lookup)) {
1179 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1180 sock->hostname ? sock->hostname :
1181 sock->ip ? sock->ip : ""));
1182 server->stat.conn_failures++;
1183 silc_server_disconnect_remote(server, sock,
1184 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1185 "Unknown host or IP");
1186 silc_free(proto_ctx);
1190 /* Register the connection for network input and output. This sets
1191 that scheduler will listen for incoming packets for this connection
1192 and sets that outgoing packets may be sent to this connection as well.
1193 However, this doesn't set the scheduler for outgoing traffic, it
1194 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1195 later when outgoing data is available. */
1196 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1198 SILC_LOG_INFO(("Incoming connection %s (%s)", sock->hostname,
1201 /* Listenning port */
1202 port = server->sockets[(SilcUInt32)proto_ctx->context]->port;
1204 /* Check whether this connection is denied to connect to us. */
1205 deny = silc_server_config_find_denied(server, sock->ip);
1207 deny = silc_server_config_find_denied(server, sock->hostname);
1209 /* The connection is denied */
1210 SILC_LOG_INFO(("Connection %s (%s) is denied",
1211 sock->hostname, sock->ip));
1212 silc_server_disconnect_remote(server, sock,
1213 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1215 server->stat.conn_failures++;
1216 silc_free(proto_ctx);
1220 /* Check whether we have configured this sort of connection at all. We
1221 have to check all configurations since we don't know what type of
1222 connection this is. */
1223 if (!(cconfig = silc_server_config_find_client(server, sock->ip)))
1224 cconfig = silc_server_config_find_client(server, sock->hostname);
1225 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1226 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1227 if (server->server_type == SILC_ROUTER) {
1228 if (!(rconfig = silc_server_config_find_router_conn(server,
1229 sock->ip, sock->port)))
1230 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1233 if (!cconfig && !sconfig && !rconfig) {
1234 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1236 silc_server_disconnect_remote(server, sock,
1237 SILC_STATUS_ERR_BANNED_FROM_SERVER);
1238 server->stat.conn_failures++;
1239 silc_free(proto_ctx);
1243 /* The connection is allowed */
1245 /* Set internal context for key exchange protocol. This is
1246 sent as context for the protocol. */
1247 proto_ctx->sock = sock;
1248 proto_ctx->rng = server->rng;
1249 proto_ctx->responder = TRUE;
1250 silc_server_config_ref(&proto_ctx->cconfig, server->config, cconfig);
1251 silc_server_config_ref(&proto_ctx->sconfig, server->config, sconfig);
1252 silc_server_config_ref(&proto_ctx->rconfig, server->config, rconfig);
1254 /* Take flags for key exchange. Since we do not know what type of connection
1255 this is, we go through all found configurations and use the global ones
1256 as well. This will result always into strictest key exchange flags. */
1257 SILC_GET_SKE_FLAGS(cconfig, proto_ctx);
1258 SILC_GET_SKE_FLAGS(sconfig, proto_ctx);
1259 SILC_GET_SKE_FLAGS(rconfig, proto_ctx);
1260 if (server->config->param.key_exchange_pfs)
1261 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
1263 /* Prepare the connection for key exchange protocol. We allocate the
1264 protocol but will not start it yet. The connector will be the
1265 initiator of the protocol thus we will wait for initiation from
1266 there before we start the protocol. */
1267 server->stat.auth_attempts++;
1268 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1269 &sock->protocol, proto_ctx,
1270 silc_server_accept_new_connection_second);
1272 /* Register a timeout task that will be executed if the connector
1273 will not start the key exchange protocol within specified timeout
1274 and the connection will be closed. */
1275 proto_ctx->timeout_task =
1276 silc_schedule_task_add(server->schedule, sock->sock,
1277 silc_server_timeout_remote,
1279 server->config->key_exchange_timeout, 0,
1284 /* Accepts new connections to the server. Accepting new connections are
1285 done in three parts to make it async. */
1287 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1289 SilcServer server = (SilcServer)context;
1290 SilcSocketConnection newsocket;
1291 SilcServerKEInternalContext *proto_ctx;
1294 SILC_LOG_DEBUG(("Accepting new connection"));
1296 server->stat.conn_attempts++;
1298 sock = silc_net_accept_connection(fd);
1300 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1301 server->stat.conn_failures++;
1305 /* Check for maximum allowed connections */
1306 if (sock > server->config->param.connections_max) {
1307 SILC_LOG_ERROR(("Refusing connection, server is full"));
1308 server->stat.conn_failures++;
1309 silc_net_close_connection(sock);
1313 /* Set socket options */
1314 silc_net_set_socket_nonblock(sock);
1315 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1317 /* We don't create a ID yet, since we don't know what type of connection
1318 this is yet. But, we do add the connection to the socket table. */
1319 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1320 server->sockets[sock] = newsocket;
1322 /* Perform asynchronous host lookup. This will lookup the IP and the
1323 FQDN of the remote connection. After the lookup is done the connection
1324 is accepted further. */
1325 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1326 proto_ctx->server = server;
1327 proto_ctx->context = (void *)fd;
1328 silc_socket_host_lookup(newsocket, TRUE,
1329 silc_server_accept_new_connection_lookup,
1330 (void *)proto_ctx, server->schedule);
1333 /* Second part of accepting new connection. Key exchange protocol has been
1334 performed and now it is time to do little connection authentication
1335 protocol to figure out whether this connection is client or server
1336 and whether it has right to access this server (especially server
1337 connections needs to be authenticated). */
1339 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1341 SilcProtocol protocol = (SilcProtocol)context;
1342 SilcServerKEInternalContext *ctx =
1343 (SilcServerKEInternalContext *)protocol->context;
1344 SilcServer server = (SilcServer)ctx->server;
1345 SilcSocketConnection sock = ctx->sock;
1346 SilcServerConnAuthInternalContext *proto_ctx;
1348 SILC_LOG_DEBUG(("Start"));
1350 if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
1351 (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
1352 /* Error occured during protocol */
1353 silc_protocol_free(protocol);
1354 sock->protocol = NULL;
1355 silc_ske_free_key_material(ctx->keymat);
1357 silc_packet_context_free(ctx->packet);
1359 silc_ske_free(ctx->ske);
1360 silc_free(ctx->dest_id);
1361 silc_server_config_unref(&ctx->cconfig);
1362 silc_server_config_unref(&ctx->sconfig);
1363 silc_server_config_unref(&ctx->rconfig);
1365 silc_schedule_task_del_by_callback(server->schedule,
1366 silc_server_failure_callback);
1367 silc_server_disconnect_remote(server, sock,
1368 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
1370 server->stat.auth_failures++;
1374 /* We now have the key material as the result of the key exchange
1375 protocol. Take the key material into use. Free the raw key material
1376 as soon as we've set them into use. */
1377 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1378 ctx->sock, ctx->keymat,
1379 ctx->ske->prop->cipher,
1380 ctx->ske->prop->pkcs,
1381 ctx->ske->prop->hash,
1382 ctx->ske->prop->hmac,
1383 ctx->ske->prop->group,
1385 silc_protocol_free(protocol);
1386 sock->protocol = NULL;
1387 silc_ske_free_key_material(ctx->keymat);
1389 silc_packet_context_free(ctx->packet);
1391 silc_ske_free(ctx->ske);
1392 silc_free(ctx->dest_id);
1393 silc_server_config_unref(&ctx->cconfig);
1394 silc_server_config_unref(&ctx->sconfig);
1395 silc_server_config_unref(&ctx->rconfig);
1397 silc_schedule_task_del_by_callback(server->schedule,
1398 silc_server_failure_callback);
1399 silc_server_disconnect_remote(server, sock,
1400 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1401 server->stat.auth_failures++;
1404 silc_ske_free_key_material(ctx->keymat);
1406 /* Allocate internal context for the authentication protocol. This
1407 is sent as context for the protocol. */
1408 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1409 proto_ctx->server = (void *)server;
1410 proto_ctx->sock = sock;
1411 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1412 proto_ctx->responder = TRUE;
1413 proto_ctx->dest_id_type = ctx->dest_id_type;
1414 proto_ctx->dest_id = ctx->dest_id;
1415 proto_ctx->cconfig = ctx->cconfig;
1416 proto_ctx->sconfig = ctx->sconfig;
1417 proto_ctx->rconfig = ctx->rconfig;
1419 /* Free old protocol as it is finished now */
1420 silc_protocol_free(protocol);
1422 silc_packet_context_free(ctx->packet);
1424 sock->protocol = NULL;
1426 /* Allocate the authentication protocol. This is allocated here
1427 but we won't start it yet. We will be receiving party of this
1428 protocol thus we will wait that connecting party will make
1429 their first move. */
1430 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1431 &sock->protocol, proto_ctx,
1432 silc_server_accept_new_connection_final);
1434 /* Register timeout task. If the protocol is not executed inside
1435 this timelimit the connection will be terminated. */
1436 proto_ctx->timeout_task =
1437 silc_schedule_task_add(server->schedule, sock->sock,
1438 silc_server_timeout_remote,
1440 server->config->conn_auth_timeout, 0,
1445 /* Final part of accepting new connection. The connection has now
1446 been authenticated and keys has been exchanged. We also know whether
1447 this is client or server connection. */
1449 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1451 SilcProtocol protocol = (SilcProtocol)context;
1452 SilcServerConnAuthInternalContext *ctx =
1453 (SilcServerConnAuthInternalContext *)protocol->context;
1454 SilcServer server = (SilcServer)ctx->server;
1455 SilcSocketConnection sock = ctx->sock;
1456 SilcServerHBContext hb_context;
1457 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1459 SilcUInt32 hearbeat_timeout = server->config->param.keepalive_secs;
1461 SILC_LOG_DEBUG(("Start"));
1463 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1464 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1465 /* Error occured during protocol */
1466 silc_protocol_free(protocol);
1467 sock->protocol = NULL;
1469 silc_packet_context_free(ctx->packet);
1471 silc_ske_free(ctx->ske);
1472 silc_free(ctx->dest_id);
1473 silc_server_config_unref(&ctx->cconfig);
1474 silc_server_config_unref(&ctx->sconfig);
1475 silc_server_config_unref(&ctx->rconfig);
1477 silc_schedule_task_del_by_callback(server->schedule,
1478 silc_server_failure_callback);
1479 silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
1481 server->stat.auth_failures++;
1485 entry->data.last_receive = time(NULL);
1487 switch (ctx->conn_type) {
1488 case SILC_SOCKET_TYPE_CLIENT:
1490 SilcClientEntry client;
1491 SilcServerConfigClient *conn = ctx->cconfig.ref_ptr;
1493 /* Verify whether this connection is after all allowed to connect */
1494 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1495 &server->config->param,
1496 conn->param, ctx->ske)) {
1497 server->stat.auth_failures++;
1501 SILC_LOG_DEBUG(("Remote host is client"));
1502 SILC_LOG_INFO(("Connection %s (%s) is client", sock->hostname,
1505 /* Add the client to the client ID cache. The nickname and Client ID
1506 and other information is created after we have received NEW_CLIENT
1507 packet from client. */
1508 client = silc_idlist_add_client(server->local_list,
1509 NULL, NULL, NULL, NULL, NULL, sock, 0);
1511 SILC_LOG_ERROR(("Could not add new client to cache"));
1512 silc_free(sock->user_data);
1513 silc_server_disconnect_remote(server, sock,
1514 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1515 server->stat.auth_failures++;
1520 server->stat.my_clients++;
1521 server->stat.clients++;
1522 server->stat.cell_clients++;
1524 /* Get connection parameters */
1526 if (conn->param->keepalive_secs)
1527 hearbeat_timeout = conn->param->keepalive_secs;
1530 id_entry = (void *)client;
1533 case SILC_SOCKET_TYPE_SERVER:
1534 case SILC_SOCKET_TYPE_ROUTER:
1536 SilcServerEntry new_server;
1537 bool initiator = FALSE;
1538 bool backup_local = FALSE;
1539 bool backup_router = FALSE;
1540 char *backup_replace_ip = NULL;
1541 SilcUInt16 backup_replace_port = 0;
1542 SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
1543 SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
1545 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1546 /* Verify whether this connection is after all allowed to connect */
1547 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1548 &server->config->param,
1549 rconn ? rconn->param : NULL,
1551 server->stat.auth_failures++;
1557 if (rconn->param->keepalive_secs)
1558 hearbeat_timeout = rconn->param->keepalive_secs;
1561 initiator = rconn->initiator;
1562 backup_local = rconn->backup_local;
1563 backup_router = rconn->backup_router;
1564 backup_replace_ip = rconn->backup_replace_ip;
1565 backup_replace_port = rconn->backup_replace_port;
1569 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
1570 /* Verify whether this connection is after all allowed to connect */
1571 if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
1572 &server->config->param,
1573 sconn ? sconn->param : NULL,
1575 server->stat.auth_failures++;
1580 if (sconn->param->keepalive_secs)
1581 hearbeat_timeout = sconn->param->keepalive_secs;
1584 backup_router = sconn->backup_router;
1588 SILC_LOG_DEBUG(("Remote host is %s",
1589 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1590 "server" : (backup_router ?
1591 "backup router" : "router")));
1592 SILC_LOG_INFO(("Connection %s (%s) is %s", sock->hostname,
1593 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1594 "server" : (backup_router ?
1595 "backup router" : "router")));
1597 /* Add the server into server cache. The server name and Server ID
1598 is updated after we have received NEW_SERVER packet from the
1599 server. We mark ourselves as router for this server if we really
1602 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1603 server->local_list : (backup_router ?
1604 server->local_list :
1605 server->global_list)),
1607 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1608 SILC_SERVER : SILC_ROUTER),
1610 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1611 server->id_entry : (backup_router ?
1612 server->id_entry : NULL)),
1615 SILC_LOG_ERROR(("Could not add new server to cache"));
1616 silc_free(sock->user_data);
1617 silc_server_disconnect_remote(server, sock,
1618 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1619 server->stat.auth_failures++;
1624 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER)
1625 server->stat.my_servers++;
1627 server->stat.my_routers++;
1628 server->stat.servers++;
1630 id_entry = (void *)new_server;
1632 /* If the incoming connection is router and marked as backup router
1633 then add it to be one of our backups */
1634 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
1635 silc_server_backup_add(server, new_server, backup_replace_ip,
1636 backup_replace_port, backup_local);
1638 /* Change it back to SERVER type since that's what it really is. */
1640 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1642 new_server->server_type = SILC_BACKUP_ROUTER;
1645 /* Check whether this connection is to be our primary router connection
1646 if we do not already have the primary route. */
1647 if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1648 if (silc_server_config_is_primary_route(server) && !initiator)
1651 SILC_LOG_DEBUG(("We are not standalone server anymore"));
1652 server->standalone = FALSE;
1653 if (!server->id_entry->router) {
1654 server->id_entry->router = id_entry;
1655 server->router = id_entry;
1666 sock->type = ctx->conn_type;
1668 /* Add the common data structure to the ID entry. */
1669 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1671 /* Add to sockets internal pointer for fast referencing */
1672 silc_free(sock->user_data);
1673 sock->user_data = id_entry;
1675 /* Connection has been fully established now. Everything is ok. */
1676 SILC_LOG_DEBUG(("New connection authenticated"));
1678 /* Perform keepalive. The `hb_context' will be freed automatically
1679 when finally calling the silc_socket_free function. */
1680 hb_context = silc_calloc(1, sizeof(*hb_context));
1681 hb_context->server = server;
1682 silc_socket_set_heartbeat(sock, hearbeat_timeout, hb_context,
1683 silc_server_perform_heartbeat,
1687 silc_schedule_task_del_by_callback(server->schedule,
1688 silc_server_failure_callback);
1689 silc_protocol_free(protocol);
1691 silc_packet_context_free(ctx->packet);
1693 silc_ske_free(ctx->ske);
1694 silc_free(ctx->dest_id);
1695 silc_server_config_unref(&ctx->cconfig);
1696 silc_server_config_unref(&ctx->sconfig);
1697 silc_server_config_unref(&ctx->rconfig);
1699 sock->protocol = NULL;
1702 /* This function is used to read packets from network and send packets to
1703 network. This is usually a generic task. */
1705 SILC_TASK_CALLBACK(silc_server_packet_process)
1707 SilcServer server = (SilcServer)context;
1708 SilcSocketConnection sock = server->sockets[fd];
1709 SilcIDListData idata;
1710 SilcCipher cipher = NULL;
1711 SilcHmac hmac = NULL;
1712 SilcUInt32 sequence = 0;
1718 SILC_LOG_DEBUG(("Processing packet"));
1720 /* Packet sending */
1722 if (type == SILC_TASK_WRITE) {
1723 /* Do not send data to disconnected connection */
1724 if (SILC_IS_DISCONNECTED(sock))
1727 server->stat.packets_sent++;
1729 /* Send the packet */
1730 ret = silc_packet_send(sock, TRUE);
1732 /* If returned -2 could not write to connection now, will do
1738 SILC_LOG_ERROR(("Error sending packet to connection "
1739 "%s:%d [%s]", sock->hostname, sock->port,
1740 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1741 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1742 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1747 /* The packet has been sent and now it is time to set the connection
1748 back to only for input. When there is again some outgoing data
1749 available for this connection it will be set for output as well.
1750 This call clears the output setting and sets it only for input. */
1751 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1752 SILC_UNSET_OUTBUF_PENDING(sock);
1754 silc_buffer_clear(sock->outbuf);
1758 /* Packet receiving */
1760 /* Read some data from connection */
1761 ret = silc_packet_receive(sock);
1765 SILC_LOG_ERROR(("Error receiving packet from connection "
1766 "%s:%d [%s] %s", sock->hostname, sock->port,
1767 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1768 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1769 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1770 "Router"), strerror(errno)));
1776 SILC_LOG_DEBUG(("Read EOF"));
1778 /* If connection is disconnecting already we will finally
1779 close the connection */
1780 if (SILC_IS_DISCONNECTING(sock)) {
1781 if (sock->user_data)
1782 silc_server_free_sock_user_data(server, sock, NULL);
1783 silc_server_close_connection(server, sock);
1787 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1788 SILC_SET_DISCONNECTING(sock);
1790 if (sock->user_data) {
1792 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
1793 silc_server_free_sock_user_data(server, sock, tmp);
1795 silc_server_free_sock_user_data(server, sock, NULL);
1796 } else if (server->router_conn && server->router_conn->sock == sock &&
1797 !server->router && server->standalone)
1798 silc_schedule_task_add(server->schedule, 0,
1799 silc_server_connect_to_router,
1802 SILC_TASK_PRI_NORMAL);
1804 silc_server_close_connection(server, sock);
1808 /* If connection is disconnecting or disconnected we will ignore
1810 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1811 SILC_LOG_DEBUG(("Ignoring read data from disconnected connection"));
1815 server->stat.packets_received++;
1817 /* Get keys and stuff from ID entry */
1818 idata = (SilcIDListData)sock->user_data;
1820 cipher = idata->receive_key;
1821 hmac = idata->hmac_receive;
1822 sequence = idata->psn_receive;
1825 /* Process the packet. This will call the parser that will then
1826 decrypt and parse the packet. */
1827 ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1828 TRUE : FALSE, cipher, hmac, sequence,
1829 silc_server_packet_parse, server);
1831 /* If this socket connection is not authenticated yet and the packet
1832 processing failed we will drop the connection since it can be
1833 a malicious flooder. */
1834 if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
1835 (!sock->protocol || sock->protocol->protocol->type ==
1836 SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
1837 SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
1838 SILC_SET_DISCONNECTING(sock);
1840 if (sock->user_data)
1841 silc_server_free_sock_user_data(server, sock, NULL);
1842 silc_server_close_connection(server, sock);
1846 /* Parses whole packet, received earlier. */
1848 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1850 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1851 SilcServer server = (SilcServer)parse_ctx->context;
1852 SilcSocketConnection sock = parse_ctx->sock;
1853 SilcPacketContext *packet = parse_ctx->packet;
1854 SilcIDListData idata = (SilcIDListData)sock->user_data;
1857 SILC_LOG_DEBUG(("Start"));
1859 /* Parse the packet */
1860 if (parse_ctx->normal)
1861 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1863 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1865 /* If entry is disabled ignore what we got. */
1866 if (ret != SILC_PACKET_RESUME_ROUTER &&
1867 idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1868 SILC_LOG_DEBUG(("Connection is disabled"));
1872 if (ret == SILC_PACKET_NONE)
1875 /* Check that the the current client ID is same as in the client's packet. */
1876 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1877 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1878 if (client && client->id) {
1879 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1880 packet->src_id_type);
1881 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1889 if (server->server_type == SILC_ROUTER) {
1890 /* Route the packet if it is not destined to us. Other ID types but
1891 server are handled separately after processing them. */
1892 if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1893 packet->dst_id_type == SILC_ID_SERVER &&
1894 sock->type != SILC_SOCKET_TYPE_CLIENT &&
1895 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1897 /* Route the packet to fastest route for the destination ID */
1898 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1899 packet->dst_id_type);
1902 silc_server_packet_route(server,
1903 silc_server_route_get(server, id,
1904 packet->dst_id_type),
1911 /* Parse the incoming packet type */
1912 silc_server_packet_parse_type(server, sock, packet);
1914 if (server->server_type == SILC_ROUTER) {
1915 /* Broadcast packet if it is marked as broadcast packet and it is
1916 originated from router and we are router. */
1917 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1918 packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1919 !server->standalone) {
1920 /* Broadcast to our primary route */
1921 silc_server_packet_broadcast(server, server->router->connection, packet);
1923 /* If we have backup routers then we need to feed all broadcast
1924 data to those servers. */
1925 silc_server_backup_broadcast(server, sock, packet);
1930 silc_packet_context_free(packet);
1931 silc_free(parse_ctx);
1934 /* Parser callback called by silc_packet_receive_process. This merely
1935 registers timeout that will handle the actual parsing when appropriate. */
1937 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1940 SilcServer server = (SilcServer)context;
1941 SilcSocketConnection sock = parser_context->sock;
1942 SilcIDListData idata = (SilcIDListData)sock->user_data;
1945 idata->psn_receive = parser_context->packet->sequence + 1;
1947 /* If protocol for this connection is key exchange or rekey then we'll
1948 process all packets synchronously, since there might be packets in
1949 queue that we are not able to decrypt without first processing the
1950 packets before them. */
1951 if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1952 parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1953 (sock->protocol && sock->protocol->protocol &&
1954 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1955 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1956 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1959 /* Reprocess data since we'll return FALSE here. This is because
1960 the idata->receive_key might have become valid in the last packet
1961 and we want to call this processor with valid cipher. */
1963 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1964 TRUE : FALSE, idata->receive_key,
1965 idata->hmac_receive, idata->psn_receive,
1966 silc_server_packet_parse, server);
1968 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1969 TRUE : FALSE, NULL, NULL, 0,
1970 silc_server_packet_parse, server);
1974 switch (sock->type) {
1975 case SILC_SOCKET_TYPE_UNKNOWN:
1976 case SILC_SOCKET_TYPE_CLIENT:
1977 /* Parse the packet with timeout */
1978 silc_schedule_task_add(server->schedule, sock->sock,
1979 silc_server_packet_parse_real,
1980 (void *)parser_context, 0, 100000,
1982 SILC_TASK_PRI_NORMAL);
1984 case SILC_SOCKET_TYPE_SERVER:
1985 case SILC_SOCKET_TYPE_ROUTER:
1986 /* Packets from servers are parsed immediately */
1987 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1997 /* Parses the packet type and calls what ever routines the packet type
1998 requires. This is done for all incoming packets. */
2000 void silc_server_packet_parse_type(SilcServer server,
2001 SilcSocketConnection sock,
2002 SilcPacketContext *packet)
2004 SilcPacketType type = packet->type;
2005 SilcIDListData idata = (SilcIDListData)sock->user_data;
2007 SILC_LOG_DEBUG(("Parsing packet type %d", type));
2009 /* Parse the packet type */
2011 case SILC_PACKET_DISCONNECT:
2014 char *message = NULL;
2016 SILC_LOG_DEBUG(("Disconnect packet"));
2018 if (packet->flags & SILC_PACKET_FLAG_LIST)
2020 if (packet->buffer->len < 1)
2023 status = (SilcStatus)packet->buffer->data[0];
2024 if (packet->buffer->len > 1 &&
2025 silc_utf8_valid(packet->buffer->data + 1, packet->buffer->len - 1))
2026 message = silc_memdup(packet->buffer->data, packet->buffer->len);
2028 SILC_LOG_ERROR(("Disconnected by %s (%s): %s (%d) %s",
2029 sock->ip, sock->hostname,
2030 silc_get_status_message(status), status,
2031 message ? message : ""));
2036 case SILC_PACKET_SUCCESS:
2038 * Success received for something. For now we can have only
2039 * one protocol for connection executing at once hence this
2040 * success message is for whatever protocol is executing currently.
2042 SILC_LOG_DEBUG(("Success packet"));
2043 if (packet->flags & SILC_PACKET_FLAG_LIST)
2046 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2049 case SILC_PACKET_FAILURE:
2051 * Failure received for something. For now we can have only
2052 * one protocol for connection executing at once hence this
2053 * failure message is for whatever protocol is executing currently.
2055 SILC_LOG_DEBUG(("Failure packet"));
2056 if (packet->flags & SILC_PACKET_FLAG_LIST)
2058 if (sock->protocol) {
2059 SilcServerFailureContext f;
2060 f = silc_calloc(1, sizeof(*f));
2064 /* We will wait 5 seconds to process this failure packet */
2065 silc_schedule_task_add(server->schedule, sock->sock,
2066 silc_server_failure_callback, (void *)f, 5, 0,
2067 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2071 case SILC_PACKET_REJECT:
2072 SILC_LOG_DEBUG(("Reject packet"));
2073 if (packet->flags & SILC_PACKET_FLAG_LIST)
2078 case SILC_PACKET_NOTIFY:
2080 * Received notify packet. Server can receive notify packets from
2081 * router. Server then relays the notify messages to clients if needed.
2083 SILC_LOG_DEBUG(("Notify packet"));
2084 if (packet->flags & SILC_PACKET_FLAG_LIST)
2085 silc_server_notify_list(server, sock, packet);
2087 silc_server_notify(server, sock, packet);
2093 case SILC_PACKET_CHANNEL_MESSAGE:
2095 * Received channel message. Channel messages are special packets
2096 * (although probably most common ones) thus they are handled
2099 SILC_LOG_DEBUG(("Channel Message packet"));
2100 if (packet->flags & SILC_PACKET_FLAG_LIST)
2102 idata->last_receive = time(NULL);
2103 silc_server_channel_message(server, sock, packet);
2106 case SILC_PACKET_CHANNEL_KEY:
2108 * Received key for channel. As channels are created by the router
2109 * the keys are as well. We will distribute the key to all of our
2110 * locally connected clients on the particular channel. Router
2111 * never receives this channel and thus is ignored.
2113 SILC_LOG_DEBUG(("Channel Key packet"));
2114 if (packet->flags & SILC_PACKET_FLAG_LIST)
2116 silc_server_channel_key(server, sock, packet);
2122 case SILC_PACKET_COMMAND:
2124 * Recived command. Processes the command request and allocates the
2125 * command context and calls the command.
2127 SILC_LOG_DEBUG(("Command packet"));
2128 if (packet->flags & SILC_PACKET_FLAG_LIST)
2130 silc_server_command_process(server, sock, packet);
2133 case SILC_PACKET_COMMAND_REPLY:
2135 * Received command reply packet. Received command reply to command. It
2136 * may be reply to command sent by us or reply to command sent by client
2137 * that we've routed further.
2139 SILC_LOG_DEBUG(("Command Reply packet"));
2140 if (packet->flags & SILC_PACKET_FLAG_LIST)
2142 silc_server_command_reply(server, sock, packet);
2146 * Private Message packets
2148 case SILC_PACKET_PRIVATE_MESSAGE:
2150 * Received private message packet. The packet is coming from either
2153 SILC_LOG_DEBUG(("Private Message packet"));
2154 if (packet->flags & SILC_PACKET_FLAG_LIST)
2156 idata->last_receive = time(NULL);
2157 silc_server_private_message(server, sock, packet);
2160 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
2162 * Private message key packet.
2164 if (packet->flags & SILC_PACKET_FLAG_LIST)
2166 silc_server_private_message_key(server, sock, packet);
2170 * Key Exchange protocol packets
2172 case SILC_PACKET_KEY_EXCHANGE:
2173 SILC_LOG_DEBUG(("KE packet"));
2174 if (packet->flags & SILC_PACKET_FLAG_LIST)
2177 if (sock->protocol && sock->protocol->protocol &&
2178 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
2179 SilcServerKEInternalContext *proto_ctx =
2180 (SilcServerKEInternalContext *)sock->protocol->context;
2182 proto_ctx->packet = silc_packet_context_dup(packet);
2184 /* Let the protocol handle the packet */
2185 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
2187 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
2188 "protocol active, packet dropped."));
2192 case SILC_PACKET_KEY_EXCHANGE_1:
2193 SILC_LOG_DEBUG(("KE 1 packet"));
2194 if (packet->flags & SILC_PACKET_FLAG_LIST)
2197 if (sock->protocol && sock->protocol->protocol &&
2198 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2199 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2201 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2202 SilcServerRekeyInternalContext *proto_ctx =
2203 (SilcServerRekeyInternalContext *)sock->protocol->context;
2205 if (proto_ctx->packet)
2206 silc_packet_context_free(proto_ctx->packet);
2208 proto_ctx->packet = silc_packet_context_dup(packet);
2210 /* Let the protocol handle the packet */
2211 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2213 SilcServerKEInternalContext *proto_ctx =
2214 (SilcServerKEInternalContext *)sock->protocol->context;
2216 if (proto_ctx->packet)
2217 silc_packet_context_free(proto_ctx->packet);
2219 proto_ctx->packet = silc_packet_context_dup(packet);
2220 proto_ctx->dest_id_type = packet->src_id_type;
2221 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2222 packet->src_id_type);
2223 if (!proto_ctx->dest_id)
2226 /* Let the protocol handle the packet */
2227 silc_protocol_execute(sock->protocol, server->schedule,
2231 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
2232 "protocol active, packet dropped."));
2236 case SILC_PACKET_KEY_EXCHANGE_2:
2237 SILC_LOG_DEBUG(("KE 2 packet"));
2238 if (packet->flags & SILC_PACKET_FLAG_LIST)
2241 if (sock->protocol && sock->protocol->protocol &&
2242 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2243 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2245 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2246 SilcServerRekeyInternalContext *proto_ctx =
2247 (SilcServerRekeyInternalContext *)sock->protocol->context;
2249 if (proto_ctx->packet)
2250 silc_packet_context_free(proto_ctx->packet);
2252 proto_ctx->packet = silc_packet_context_dup(packet);
2254 /* Let the protocol handle the packet */
2255 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2257 SilcServerKEInternalContext *proto_ctx =
2258 (SilcServerKEInternalContext *)sock->protocol->context;
2260 if (proto_ctx->packet)
2261 silc_packet_context_free(proto_ctx->packet);
2263 proto_ctx->packet = silc_packet_context_dup(packet);
2264 proto_ctx->dest_id_type = packet->src_id_type;
2265 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2266 packet->src_id_type);
2267 if (!proto_ctx->dest_id)
2270 /* Let the protocol handle the packet */
2271 silc_protocol_execute(sock->protocol, server->schedule,
2275 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2276 "protocol active, packet dropped."));
2280 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2282 * Connection authentication request packet. When we receive this packet
2283 * we will send to the other end information about our mandatory
2284 * authentication method for the connection. This packet maybe received
2287 SILC_LOG_DEBUG(("Connection authentication request packet"));
2288 if (packet->flags & SILC_PACKET_FLAG_LIST)
2290 silc_server_connection_auth_request(server, sock, packet);
2294 * Connection Authentication protocol packets
2296 case SILC_PACKET_CONNECTION_AUTH:
2297 /* Start of the authentication protocol. We receive here the
2298 authentication data and will verify it. */
2299 SILC_LOG_DEBUG(("Connection auth packet"));
2300 if (packet->flags & SILC_PACKET_FLAG_LIST)
2303 if (sock->protocol && sock->protocol->protocol->type
2304 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2306 SilcServerConnAuthInternalContext *proto_ctx =
2307 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2309 proto_ctx->packet = silc_packet_context_dup(packet);
2311 /* Let the protocol handle the packet */
2312 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2314 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2315 "protocol active, packet dropped."));
2319 case SILC_PACKET_NEW_ID:
2321 * Received New ID packet. This includes some new ID that has been
2322 * created. It may be for client, server or channel. This is the way
2323 * to distribute information about new registered entities in the
2326 SILC_LOG_DEBUG(("New ID packet"));
2327 if (packet->flags & SILC_PACKET_FLAG_LIST)
2328 silc_server_new_id_list(server, sock, packet);
2330 silc_server_new_id(server, sock, packet);
2333 case SILC_PACKET_NEW_CLIENT:
2335 * Received new client packet. This includes client information that
2336 * we will use to create initial client ID. After creating new
2337 * ID we will send it to the client.
2339 SILC_LOG_DEBUG(("New Client packet"));
2340 if (packet->flags & SILC_PACKET_FLAG_LIST)
2342 silc_server_new_client(server, sock, packet);
2345 case SILC_PACKET_NEW_SERVER:
2347 * Received new server packet. This includes Server ID and some other
2348 * information that we may save. This is received after server has
2351 SILC_LOG_DEBUG(("New Server packet"));
2352 if (packet->flags & SILC_PACKET_FLAG_LIST)
2354 silc_server_new_server(server, sock, packet);
2357 case SILC_PACKET_NEW_CHANNEL:
2359 * Received new channel packet. Information about new channel in the
2360 * network are distributed using this packet.
2362 SILC_LOG_DEBUG(("New Channel packet"));
2363 if (packet->flags & SILC_PACKET_FLAG_LIST)
2364 silc_server_new_channel_list(server, sock, packet);
2366 silc_server_new_channel(server, sock, packet);
2369 case SILC_PACKET_HEARTBEAT:
2371 * Received heartbeat.
2373 SILC_LOG_DEBUG(("Heartbeat packet"));
2374 if (packet->flags & SILC_PACKET_FLAG_LIST)
2378 case SILC_PACKET_KEY_AGREEMENT:
2380 * Received heartbeat.
2382 SILC_LOG_DEBUG(("Key agreement packet"));
2383 if (packet->flags & SILC_PACKET_FLAG_LIST)
2385 silc_server_key_agreement(server, sock, packet);
2388 case SILC_PACKET_REKEY:
2390 * Received re-key packet. The sender wants to regenerate the session
2393 SILC_LOG_DEBUG(("Re-key packet"));
2394 if (packet->flags & SILC_PACKET_FLAG_LIST)
2396 silc_server_rekey(server, sock, packet);
2399 case SILC_PACKET_REKEY_DONE:
2401 * The re-key is done.
2403 SILC_LOG_DEBUG(("Re-key done packet"));
2404 if (packet->flags & SILC_PACKET_FLAG_LIST)
2407 if (sock->protocol && sock->protocol->protocol &&
2408 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2410 SilcServerRekeyInternalContext *proto_ctx =
2411 (SilcServerRekeyInternalContext *)sock->protocol->context;
2413 if (proto_ctx->packet)
2414 silc_packet_context_free(proto_ctx->packet);
2416 proto_ctx->packet = silc_packet_context_dup(packet);
2418 /* Let the protocol handle the packet */
2419 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2421 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2422 "protocol active, packet dropped."));
2426 case SILC_PACKET_FTP:
2428 SILC_LOG_DEBUG(("FTP packet"));
2429 if (packet->flags & SILC_PACKET_FLAG_LIST)
2431 silc_server_ftp(server, sock, packet);
2434 case SILC_PACKET_RESUME_CLIENT:
2436 SILC_LOG_DEBUG(("Resume Client packet"));
2437 if (packet->flags & SILC_PACKET_FLAG_LIST)
2439 silc_server_resume_client(server, sock, packet);
2442 case SILC_PACKET_RESUME_ROUTER:
2443 /* Resume router packet received. This packet is received for backup
2444 router resuming protocol. */
2445 SILC_LOG_DEBUG(("Resume router packet"));
2446 if (packet->flags & SILC_PACKET_FLAG_LIST)
2448 silc_server_backup_resume_router(server, sock, packet);
2452 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2458 /* Creates connection to a remote router. */
2460 void silc_server_create_connection(SilcServer server,
2461 const char *remote_host, SilcUInt32 port)
2463 SilcServerConnection sconn;
2465 /* Allocate connection object for hold connection specific stuff. */
2466 sconn = silc_calloc(1, sizeof(*sconn));
2467 sconn->server = server;
2468 sconn->remote_host = strdup(remote_host);
2469 sconn->remote_port = port;
2470 sconn->no_reconnect = TRUE;
2472 silc_schedule_task_add(server->schedule, 0,
2473 silc_server_connect_router,
2474 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
2475 SILC_TASK_PRI_NORMAL);
2478 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2480 silc_socket_free((SilcSocketConnection)context);
2483 /* Closes connection to socket connection */
2485 void silc_server_close_connection(SilcServer server,
2486 SilcSocketConnection sock)
2488 if (!server->sockets[sock->sock])
2491 SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2493 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2494 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2495 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2498 /* We won't listen for this connection anymore */
2499 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2501 /* Unregister all tasks */
2502 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2504 /* Close the actual connection */
2505 silc_net_close_connection(sock->sock);
2506 server->sockets[sock->sock] = NULL;
2508 /* If sock->user_data is NULL then we'll check for active protocols
2509 here since the silc_server_free_sock_user_data has not been called
2510 for this connection. */
2511 if (!sock->user_data) {
2512 /* If any protocol is active cancel its execution. It will call
2513 the final callback which will finalize the disconnection. */
2514 if (sock->protocol) {
2515 silc_protocol_cancel(sock->protocol, server->schedule);
2516 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2517 silc_protocol_execute_final(sock->protocol, server->schedule);
2518 sock->protocol = NULL;
2523 silc_schedule_task_add(server->schedule, 0,
2524 silc_server_close_connection_final,
2525 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
2526 SILC_TASK_PRI_NORMAL);
2529 /* Sends disconnect message to remote connection and disconnects the
2532 void silc_server_disconnect_remote(SilcServer server,
2533 SilcSocketConnection sock,
2534 SilcStatus status, ...)
2537 unsigned char buf[512];
2545 memset(buf, 0, sizeof(buf));
2546 va_start(ap, status);
2547 cp = va_arg(ap, char *);
2549 vsnprintf(buf, sizeof(buf) - 1, cp, ap);
2554 SILC_LOG_DEBUG(("Disconnecting remote host"));
2556 /* Notify remote end that the conversation is over. The notify message
2557 is tried to be sent immediately. */
2561 len += silc_utf8_encoded_len(buf, strlen(buf), SILC_STRING_ASCII);
2563 buffer = silc_buffer_alloc_size(len);
2567 buffer->data[0] = status;
2569 silc_utf8_encode(buf, strlen(buf), SILC_STRING_ASCII, buffer->data + 1,
2571 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
2572 buffer->data, buffer->len, TRUE);
2573 silc_buffer_free(buffer);
2576 silc_server_packet_queue_purge(server, sock);
2578 /* Mark the connection to be disconnected */
2579 SILC_SET_DISCONNECTED(sock);
2580 silc_server_close_connection(server, sock);
2585 SilcClientEntry client;
2586 } *FreeClientInternal;
2588 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2590 FreeClientInternal i = (FreeClientInternal)context;
2592 silc_idlist_del_data(i->client);
2593 silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2597 /* Frees client data and notifies about client's signoff. */
2599 void silc_server_free_client_data(SilcServer server,
2600 SilcSocketConnection sock,
2601 SilcClientEntry client,
2603 const char *signoff)
2605 FreeClientInternal i = silc_calloc(1, sizeof(*i));
2607 /* If there is pending outgoing data for the client then purge it
2608 to the network before removing the client entry. */
2609 silc_server_packet_queue_purge(server, sock);
2612 /* Check if anyone is watching this nickname */
2613 if (server->server_type == SILC_ROUTER)
2614 silc_server_check_watcher_list(server, client, NULL,
2615 SILC_NOTIFY_TYPE_SIGNOFF);
2617 /* Send SIGNOFF notify to routers. */
2618 if (notify && !server->standalone && server->router)
2619 silc_server_send_notify_signoff(server, server->router->connection,
2620 server->server_type == SILC_SERVER ?
2621 FALSE : TRUE, client->id, signoff);
2623 /* Remove client from all channels */
2625 silc_server_remove_from_channels(server, NULL, client,
2626 TRUE, (char *)signoff, TRUE);
2628 silc_server_remove_from_channels(server, NULL, client,
2629 FALSE, NULL, FALSE);
2631 /* Remove this client from watcher list if it is */
2632 silc_server_del_from_watcher_list(server, client);
2635 /* Update statistics */
2636 server->stat.my_clients--;
2637 server->stat.clients--;
2638 if (server->stat.cell_clients)
2639 server->stat.cell_clients--;
2640 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2641 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2642 silc_schedule_task_del_by_context(server->schedule, client);
2644 /* We will not delete the client entry right away. We will take it
2645 into history (for WHOWAS command) for 5 minutes */
2648 silc_schedule_task_add(server->schedule, 0,
2649 silc_server_free_client_data_timeout,
2651 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2652 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2654 client->router = NULL;
2655 client->connection = NULL;
2658 /* Frees user_data pointer from socket connection object. This also sends
2659 appropriate notify packets to the network to inform about leaving
2662 void silc_server_free_sock_user_data(SilcServer server,
2663 SilcSocketConnection sock,
2664 const char *signoff_message)
2666 SILC_LOG_DEBUG(("Start"));
2668 switch (sock->type) {
2669 case SILC_SOCKET_TYPE_CLIENT:
2671 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2672 silc_server_free_client_data(server, sock, user_data, TRUE,
2676 case SILC_SOCKET_TYPE_SERVER:
2677 case SILC_SOCKET_TYPE_ROUTER:
2679 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2680 SilcServerEntry backup_router = NULL;
2683 backup_router = silc_server_backup_get(server, user_data->id);
2685 /* If this was our primary router connection then we're lost to
2686 the outside world. */
2687 if (server->router == user_data) {
2688 /* Check whether we have a backup router connection */
2689 if (!backup_router || backup_router == user_data) {
2690 silc_schedule_task_add(server->schedule, 0,
2691 silc_server_connect_to_router,
2694 SILC_TASK_PRI_NORMAL);
2696 server->id_entry->router = NULL;
2697 server->router = NULL;
2698 server->standalone = TRUE;
2699 backup_router = NULL;
2701 SILC_LOG_INFO(("New primary router is backup router %s",
2702 backup_router->server_name));
2703 SILC_LOG_DEBUG(("New primary router is backup router %s",
2704 backup_router->server_name));
2705 server->id_entry->router = backup_router;
2706 server->router = backup_router;
2707 server->router_connect = time(0);
2708 server->backup_primary = TRUE;
2709 if (server->server_type == SILC_BACKUP_ROUTER) {
2710 server->server_type = SILC_ROUTER;
2712 /* We'll need to constantly try to reconnect to the primary
2713 router so that we'll see when it comes back online. */
2714 silc_server_backup_reconnect(server, sock->ip, sock->port,
2715 silc_server_backup_connected,
2719 /* Mark this connection as replaced */
2720 silc_server_backup_replaced_add(server, user_data->id,
2723 } else if (backup_router) {
2724 SILC_LOG_INFO(("Enabling the use of backup router %s",
2725 backup_router->server_name));
2726 SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2727 backup_router->server_name));
2729 /* Mark this connection as replaced */
2730 silc_server_backup_replaced_add(server, user_data->id,
2734 if (!backup_router) {
2735 /* Free all client entries that this server owns as they will
2736 become invalid now as well. */
2738 silc_server_remove_clients_by_server(server, user_data, TRUE);
2739 if (server->server_type == SILC_SERVER)
2740 silc_server_remove_channels_by_server(server, user_data);
2742 /* Update the client entries of this server to the new backup
2743 router. This also removes the clients that *really* was owned
2744 by the primary router and went down with the router. */
2745 silc_server_update_clients_by_server(server, user_data, backup_router,
2747 silc_server_update_servers_by_server(server, user_data, backup_router);
2748 if (server->server_type == SILC_SERVER)
2749 silc_server_update_channels_by_server(server, user_data,
2753 /* Free the server entry */
2754 silc_server_backup_del(server, user_data);
2755 silc_server_backup_replaced_del(server, user_data);
2756 silc_idlist_del_data(user_data);
2757 if (!silc_idlist_del_server(server->local_list, user_data))
2758 silc_idlist_del_server(server->global_list, user_data);
2759 server->stat.my_servers--;
2760 server->stat.servers--;
2761 if (server->server_type == SILC_ROUTER)
2762 server->stat.cell_servers--;
2764 if (backup_router) {
2765 /* Announce all of our stuff that was created about 5 minutes ago.
2766 The backup router knows all the other stuff already. */
2767 if (server->server_type == SILC_ROUTER)
2768 silc_server_announce_servers(server, FALSE, time(0) - 300,
2769 backup_router->connection);
2771 /* Announce our clients and channels to the router */
2772 silc_server_announce_clients(server, time(0) - 300,
2773 backup_router->connection);
2774 silc_server_announce_channels(server, time(0) - 300,
2775 backup_router->connection);
2781 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2783 silc_idlist_del_data(user_data);
2784 silc_free(user_data);
2789 /* If any protocol is active cancel its execution */
2790 if (sock->protocol) {
2791 silc_protocol_cancel(sock->protocol, server->schedule);
2792 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2793 silc_protocol_execute_final(sock->protocol, server->schedule);
2794 sock->protocol = NULL;
2797 sock->user_data = NULL;
2800 /* Removes client from all channels it has joined. This is used when client
2801 connection is disconnected. If the client on a channel is last, the
2802 channel is removed as well. This sends the SIGNOFF notify types. */
2804 void silc_server_remove_from_channels(SilcServer server,
2805 SilcSocketConnection sock,
2806 SilcClientEntry client,
2808 const char *signoff_message,
2811 SilcChannelEntry channel;
2812 SilcChannelClientEntry chl;
2813 SilcHashTableList htl;
2816 SILC_LOG_DEBUG(("Start"));
2818 if (!client || !client->id)
2821 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2825 /* Remove the client from all channels. The client is removed from
2826 the channels' user list. */
2827 silc_hash_table_list(client->channels, &htl);
2828 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2829 channel = chl->channel;
2831 /* Remove channel if this is last client leaving the channel, unless
2832 the channel is permanent. */
2833 if (server->server_type == SILC_ROUTER &&
2834 silc_hash_table_count(channel->user_list) < 2) {
2835 silc_server_channel_delete(server, channel);
2839 silc_hash_table_del(client->channels, channel);
2840 silc_hash_table_del(channel->user_list, chl->client);
2841 channel->user_count--;
2843 /* If there is no global users on the channel anymore mark the channel
2844 as local channel. Do not check if the removed client is local client. */
2845 if (server->server_type != SILC_ROUTER && channel->global_users &&
2846 chl->client->router && !silc_server_channel_has_global(channel))
2847 channel->global_users = FALSE;
2850 server->stat.my_chanclients--;
2852 /* If there is not at least one local user on the channel then we don't
2853 need the channel entry anymore, we can remove it safely, unless the
2854 channel is permanent channel */
2855 if (server->server_type != SILC_ROUTER &&
2856 !silc_server_channel_has_local(channel)) {
2857 /* Notify about leaving client if this channel has global users. */
2858 if (notify && channel->global_users)
2859 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2860 SILC_NOTIFY_TYPE_SIGNOFF,
2861 signoff_message ? 2 : 1,
2862 clidp->data, clidp->len,
2863 signoff_message, signoff_message ?
2864 strlen(signoff_message) : 0);
2866 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2867 silc_server_channel_delete(server, channel);
2871 /* Send notify to channel about client leaving SILC and channel too */
2873 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2874 SILC_NOTIFY_TYPE_SIGNOFF,
2875 signoff_message ? 2 : 1,
2876 clidp->data, clidp->len,
2877 signoff_message, signoff_message ?
2878 strlen(signoff_message) : 0);
2880 /* Re-generate channel key if needed */
2881 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2882 if (!silc_server_create_channel_key(server, channel, 0))
2885 /* Send the channel key to the channel. The key of course is not sent
2886 to the client who was removed from the channel. */
2887 silc_server_send_channel_key(server, client->connection, channel,
2888 server->server_type == SILC_ROUTER ?
2889 FALSE : !server->standalone);
2893 silc_hash_table_list_reset(&htl);
2894 silc_buffer_free(clidp);
2897 /* Removes client from one channel. This is used for example when client
2898 calls LEAVE command to remove itself from the channel. Returns TRUE
2899 if channel still exists and FALSE if the channel is removed when
2900 last client leaves the channel. If `notify' is FALSE notify messages
2903 bool silc_server_remove_from_one_channel(SilcServer server,
2904 SilcSocketConnection sock,
2905 SilcChannelEntry channel,
2906 SilcClientEntry client,
2909 SilcChannelClientEntry chl;
2912 SILC_LOG_DEBUG(("Removing %s from channel %s",
2913 silc_id_render(client->id, SILC_ID_CLIENT),
2914 channel->channel_name));
2916 /* Get the entry to the channel, if this client is not on the channel
2918 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2921 /* Remove channel if this is last client leaving the channel, unless
2922 the channel is permanent. */
2923 if (server->server_type == SILC_ROUTER &&
2924 silc_hash_table_count(channel->user_list) < 2) {
2925 silc_server_channel_delete(server, channel);
2929 silc_hash_table_del(client->channels, chl->channel);
2930 silc_hash_table_del(channel->user_list, chl->client);
2931 channel->user_count--;
2933 /* If there is no global users on the channel anymore mark the channel
2934 as local channel. Do not check if the client is local client. */
2935 if (server->server_type != SILC_ROUTER && channel->global_users &&
2936 chl->client->router && !silc_server_channel_has_global(channel))
2937 channel->global_users = FALSE;
2940 server->stat.my_chanclients--;
2942 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2946 /* If there is not at least one local user on the channel then we don't
2947 need the channel entry anymore, we can remove it safely, unless the
2948 channel is permanent channel */
2949 if (server->server_type != SILC_ROUTER &&
2950 !silc_server_channel_has_local(channel)) {
2951 /* Notify about leaving client if this channel has global users. */
2952 if (notify && channel->global_users)
2953 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2954 SILC_NOTIFY_TYPE_LEAVE, 1,
2955 clidp->data, clidp->len);
2957 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2958 silc_server_channel_delete(server, channel);
2959 silc_buffer_free(clidp);
2963 /* Send notify to channel about client leaving the channel */
2965 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2966 SILC_NOTIFY_TYPE_LEAVE, 1,
2967 clidp->data, clidp->len);
2969 silc_buffer_free(clidp);
2973 /* Timeout callback. This is called if connection is idle or for some
2974 other reason is not responding within some period of time. This
2975 disconnects the remote end. */
2977 SILC_TASK_CALLBACK(silc_server_timeout_remote)
2979 SilcServer server = (SilcServer)context;
2980 SilcSocketConnection sock = server->sockets[fd];
2981 SilcProtocolType protocol = 0;
2983 SILC_LOG_DEBUG(("Start"));
2988 SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
2989 sock->hostname, sock->ip));
2991 /* If we have protocol active we must assure that we call the protocol's
2992 final callback so that all the memory is freed. */
2993 if (sock->protocol) {
2994 protocol = sock->protocol->protocol->type;
2995 silc_protocol_cancel(sock->protocol, server->schedule);
2996 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2997 silc_protocol_execute_final(sock->protocol, server->schedule);
2998 sock->protocol = NULL;
3002 if (sock->user_data)
3003 silc_server_free_sock_user_data(server, sock, NULL);
3005 silc_server_disconnect_remote(server, sock,
3007 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3008 SILC_STATUS_ERR_AUTH_FAILED :
3009 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3010 "Connection timeout");
3013 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3014 function may be used only by router. In real SILC network all channels
3015 are created by routers thus this function is never used by normal
3018 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3019 SilcServerID *router_id,
3025 SilcChannelID *channel_id;
3026 SilcChannelEntry entry;
3030 SILC_LOG_DEBUG(("Creating new channel"));
3033 cipher = SILC_DEFAULT_CIPHER;
3035 hmac = SILC_DEFAULT_HMAC;
3037 /* Allocate cipher */
3038 if (!silc_cipher_alloc(cipher, &key))
3042 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3043 silc_cipher_free(key);
3047 channel_name = strdup(channel_name);
3049 /* Create the channel ID */
3050 if (!silc_id_create_channel_id(server, router_id, server->rng,
3052 silc_free(channel_name);
3053 silc_cipher_free(key);
3054 silc_hmac_free(newhmac);
3058 /* Create the channel */
3059 entry = silc_idlist_add_channel(server->local_list, channel_name,
3060 SILC_CHANNEL_MODE_NONE, channel_id,
3061 NULL, key, newhmac, 0);
3063 silc_free(channel_name);
3064 silc_cipher_free(key);
3065 silc_hmac_free(newhmac);
3066 silc_free(channel_id);
3070 entry->cipher = strdup(cipher);
3071 entry->hmac_name = strdup(hmac);
3073 /* Now create the actual key material */
3074 if (!silc_server_create_channel_key(server, entry,
3075 silc_cipher_get_key_len(key) / 8)) {
3076 silc_idlist_del_channel(server->local_list, entry);
3080 /* Notify other routers about the new channel. We send the packet
3081 to our primary route. */
3082 if (broadcast && server->standalone == FALSE)
3083 silc_server_send_new_channel(server, server->router->connection, TRUE,
3084 channel_name, entry->id,
3085 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3088 server->stat.my_channels++;
3090 if (server->server_type == SILC_ROUTER)
3091 entry->users_resolved = TRUE;
3096 /* Same as above but creates the channel with Channel ID `channel_id. */
3099 silc_server_create_new_channel_with_id(SilcServer server,
3103 SilcChannelID *channel_id,
3106 SilcChannelEntry entry;
3110 SILC_LOG_DEBUG(("Creating new channel"));
3113 cipher = SILC_DEFAULT_CIPHER;
3115 hmac = SILC_DEFAULT_HMAC;
3117 /* Allocate cipher */
3118 if (!silc_cipher_alloc(cipher, &key))
3122 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3123 silc_cipher_free(key);
3127 channel_name = strdup(channel_name);
3129 /* Create the channel */
3130 entry = silc_idlist_add_channel(server->local_list, channel_name,
3131 SILC_CHANNEL_MODE_NONE, channel_id,
3132 NULL, key, newhmac, 0);
3134 silc_cipher_free(key);
3135 silc_hmac_free(newhmac);
3136 silc_free(channel_name);
3140 /* Now create the actual key material */
3141 if (!silc_server_create_channel_key(server, entry,
3142 silc_cipher_get_key_len(key) / 8)) {
3143 silc_idlist_del_channel(server->local_list, entry);
3147 /* Notify other routers about the new channel. We send the packet
3148 to our primary route. */
3149 if (broadcast && server->standalone == FALSE)
3150 silc_server_send_new_channel(server, server->router->connection, TRUE,
3151 channel_name, entry->id,
3152 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3155 server->stat.my_channels++;
3157 if (server->server_type == SILC_ROUTER)
3158 entry->users_resolved = TRUE;
3163 /* Channel's key re-key timeout callback. */
3165 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3167 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3168 SilcServer server = (SilcServer)rekey->context;
3172 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3175 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3178 /* Generates new channel key. This is used to create the initial channel key
3179 but also to re-generate new key for channel. If `key_len' is provided
3180 it is the bytes of the key length. */
3182 bool silc_server_create_channel_key(SilcServer server,
3183 SilcChannelEntry channel,
3187 unsigned char channel_key[32], hash[32];
3190 SILC_LOG_DEBUG(("Generating channel key"));
3192 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3193 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3197 if (!channel->channel_key)
3198 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
3199 channel->channel_key = NULL;
3205 else if (channel->key_len)
3206 len = channel->key_len / 8;
3208 len = silc_cipher_get_key_len(channel->channel_key) / 8;
3210 /* Create channel key */
3211 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3214 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
3216 /* Remove old key if exists */
3218 memset(channel->key, 0, channel->key_len / 8);
3219 silc_free(channel->key);
3223 channel->key_len = len * 8;
3224 channel->key = silc_memdup(channel_key, len);
3225 memset(channel_key, 0, sizeof(channel_key));
3227 /* Generate HMAC key from the channel key data and set it */
3229 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3230 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3231 silc_hmac_set_key(channel->hmac, hash,
3232 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3233 memset(hash, 0, sizeof(hash));
3235 if (server->server_type == SILC_ROUTER) {
3236 if (!channel->rekey)
3237 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3238 channel->rekey->context = (void *)server;
3239 channel->rekey->channel = channel;
3240 channel->rekey->key_len = key_len;
3241 if (channel->rekey->task)
3242 silc_schedule_task_del(server->schedule, channel->rekey->task);
3244 channel->rekey->task =
3245 silc_schedule_task_add(server->schedule, 0,
3246 silc_server_channel_key_rekey,
3247 (void *)channel->rekey,
3248 server->config->channel_rekey_secs, 0,
3250 SILC_TASK_PRI_NORMAL);
3256 /* Saves the channel key found in the encoded `key_payload' buffer. This
3257 function is used when we receive Channel Key Payload and also when we're
3258 processing JOIN command reply. Returns entry to the channel. */
3260 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3261 SilcBuffer key_payload,
3262 SilcChannelEntry channel)
3264 SilcChannelKeyPayload payload = NULL;
3265 SilcChannelID *id = NULL;
3266 unsigned char *tmp, hash[32];
3270 SILC_LOG_DEBUG(("Start"));
3272 /* Decode channel key payload */
3273 payload = silc_channel_key_payload_parse(key_payload->data,
3276 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3281 /* Get the channel entry */
3284 /* Get channel ID */
3285 tmp = silc_channel_key_get_id(payload, &tmp_len);
3286 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
3292 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
3294 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
3296 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3297 silc_id_render(id, SILC_ID_CHANNEL)));
3303 tmp = silc_channel_key_get_key(payload, &tmp_len);
3309 cipher = silc_channel_key_get_cipher(payload, NULL);
3315 /* Remove old key if exists */
3317 memset(channel->key, 0, channel->key_len / 8);
3318 silc_free(channel->key);
3319 silc_cipher_free(channel->channel_key);
3322 /* Create new cipher */
3323 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3324 channel->channel_key = NULL;
3329 if (channel->cipher)
3330 silc_free(channel->cipher);
3331 channel->cipher = strdup(cipher);
3334 channel->key_len = tmp_len * 8;
3335 channel->key = silc_memdup(tmp, tmp_len);
3336 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3338 /* Generate HMAC key from the channel key data and set it */
3340 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3341 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3342 silc_hmac_set_key(channel->hmac, hash,
3343 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3345 memset(hash, 0, sizeof(hash));
3346 memset(tmp, 0, tmp_len);
3348 if (server->server_type == SILC_ROUTER) {
3349 if (!channel->rekey)
3350 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3351 channel->rekey->context = (void *)server;
3352 channel->rekey->channel = channel;
3353 if (channel->rekey->task)
3354 silc_schedule_task_del(server->schedule, channel->rekey->task);
3356 channel->rekey->task =
3357 silc_schedule_task_add(server->schedule, 0,
3358 silc_server_channel_key_rekey,
3359 (void *)channel->rekey,
3360 server->config->channel_rekey_secs, 0,
3362 SILC_TASK_PRI_NORMAL);
3368 silc_channel_key_payload_free(payload);
3373 /* Heartbeat callback. This function is set as argument for the
3374 silc_socket_set_heartbeat function. The library will call this function
3375 at the set time interval. */
3377 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3380 SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3382 SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
3384 /* Send the heartbeat */
3385 silc_server_send_heartbeat(hb->server, sock);
3388 /* Returns assembled of all servers in the given ID list. The packet's
3389 form is dictated by the New ID payload. */
3391 static void silc_server_announce_get_servers(SilcServer server,
3392 SilcServerEntry remote,
3394 SilcBuffer *servers,
3395 unsigned long creation_time)
3397 SilcIDCacheList list;
3398 SilcIDCacheEntry id_cache;
3399 SilcServerEntry entry;
3402 /* Go through all clients in the list */
3403 if (silc_idcache_get_all(id_list->servers, &list)) {
3404 if (silc_idcache_list_first(list, &id_cache)) {
3406 entry = (SilcServerEntry)id_cache->context;
3408 /* Do not announce the one we've sending our announcements and
3409 do not announce ourself. Also check the creation time if it's
3411 if ((entry == remote) || (entry == server->id_entry) ||
3412 (creation_time && entry->data.created < creation_time)) {
3413 if (!silc_idcache_list_next(list, &id_cache))
3418 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3420 *servers = silc_buffer_realloc(*servers,
3422 (*servers)->truelen + idp->len :
3424 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3425 silc_buffer_put(*servers, idp->data, idp->len);
3426 silc_buffer_pull(*servers, idp->len);
3427 silc_buffer_free(idp);
3429 if (!silc_idcache_list_next(list, &id_cache))
3434 silc_idcache_list_free(list);
3439 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3445 p = silc_notify_payload_encode(notify, argc, ap);
3451 /* This function is used by router to announce existing servers to our
3452 primary router when we've connected to it. If `creation_time' is non-zero
3453 then only the servers that has been created after the `creation_time'
3454 will be announced. */
3456 void silc_server_announce_servers(SilcServer server, bool global,
3457 unsigned long creation_time,
3458 SilcSocketConnection remote)
3460 SilcBuffer servers = NULL;
3462 SILC_LOG_DEBUG(("Announcing servers"));
3464 /* Get servers in local list */
3465 silc_server_announce_get_servers(server, remote->user_data,
3466 server->local_list, &servers,
3470 /* Get servers in global list */
3471 silc_server_announce_get_servers(server, remote->user_data,
3472 server->global_list, &servers,
3476 silc_buffer_push(servers, servers->data - servers->head);
3477 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3479 /* Send the packet */
3480 silc_server_packet_send(server, remote,
3481 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3482 servers->data, servers->len, TRUE);
3484 silc_buffer_free(servers);
3488 /* Returns assembled packet of all clients in the given ID list. The
3489 packet's form is dictated by the New ID Payload. */
3491 static void silc_server_announce_get_clients(SilcServer server,
3493 SilcBuffer *clients,
3495 unsigned long creation_time)
3497 SilcIDCacheList list;
3498 SilcIDCacheEntry id_cache;
3499 SilcClientEntry client;
3502 unsigned char mode[4];
3504 /* Go through all clients in the list */
3505 if (silc_idcache_get_all(id_list->clients, &list)) {
3506 if (silc_idcache_list_first(list, &id_cache)) {
3508 client = (SilcClientEntry)id_cache->context;
3510 if (creation_time && client->data.created < creation_time) {
3511 if (!silc_idcache_list_next(list, &id_cache))
3516 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3518 *clients = silc_buffer_realloc(*clients,
3520 (*clients)->truelen + idp->len :
3522 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3523 silc_buffer_put(*clients, idp->data, idp->len);
3524 silc_buffer_pull(*clients, idp->len);
3526 SILC_PUT32_MSB(client->mode, mode);
3527 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3528 2, idp->data, idp->len,
3530 *umodes = silc_buffer_realloc(*umodes,
3532 (*umodes)->truelen + tmp->len :
3534 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3535 silc_buffer_put(*umodes, tmp->data, tmp->len);
3536 silc_buffer_pull(*umodes, tmp->len);
3537 silc_buffer_free(tmp);
3539 silc_buffer_free(idp);
3541 if (!silc_idcache_list_next(list, &id_cache))
3546 silc_idcache_list_free(list);
3550 /* This function is used to announce our existing clients to our router
3551 when we've connected to it. If `creation_time' is non-zero then only
3552 the clients that has been created after the `creation_time' will be
3555 void silc_server_announce_clients(SilcServer server,
3556 unsigned long creation_time,
3557 SilcSocketConnection remote)
3559 SilcBuffer clients = NULL;
3560 SilcBuffer umodes = NULL;
3562 SILC_LOG_DEBUG(("Announcing clients"));
3564 /* Get clients in local list */
3565 silc_server_announce_get_clients(server, server->local_list,
3566 &clients, &umodes, creation_time);
3568 /* As router we announce our global list as well */
3569 if (server->server_type == SILC_ROUTER)
3570 silc_server_announce_get_clients(server, server->global_list,
3571 &clients, &umodes, creation_time);
3574 silc_buffer_push(clients, clients->data - clients->head);
3575 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3577 /* Send the packet */
3578 silc_server_packet_send(server, remote,
3579 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3580 clients->data, clients->len, TRUE);
3582 silc_buffer_free(clients);
3586 silc_buffer_push(umodes, umodes->data - umodes->head);
3587 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
3589 /* Send the packet */
3590 silc_server_packet_send(server, remote,
3591 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3592 umodes->data, umodes->len, TRUE);
3594 silc_buffer_free(umodes);
3598 /* Returns channel's topic for announcing it */
3600 void silc_server_announce_get_channel_topic(SilcServer server,
3601 SilcChannelEntry channel,
3606 if (channel->topic) {
3607 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3608 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3609 chidp->data, chidp->len,
3611 strlen(channel->topic));
3612 silc_buffer_free(chidp);
3616 /* Returns assembled packets for channel users of the `channel'. */
3618 void silc_server_announce_get_channel_users(SilcServer server,
3619 SilcChannelEntry channel,
3620 SilcBuffer *channel_modes,
3621 SilcBuffer *channel_users,
3622 SilcBuffer *channel_users_modes)
3624 SilcChannelClientEntry chl;
3625 SilcHashTableList htl;
3626 SilcBuffer chidp, clidp, csidp;
3629 unsigned char mode[4], *fkey = NULL;
3630 SilcUInt32 fkey_len = 0;
3633 SILC_LOG_DEBUG(("Start"));
3635 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3636 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
3639 SILC_PUT32_MSB(channel->mode, mode);
3640 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
3641 if (channel->founder_key)
3642 fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
3644 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
3645 6, csidp->data, csidp->len,
3648 hmac, hmac ? strlen(hmac) : 0,
3649 channel->passphrase,
3650 channel->passphrase ?
3651 strlen(channel->passphrase) : 0,
3655 silc_buffer_realloc(*channel_modes,
3657 (*channel_modes)->truelen + len : len));
3658 silc_buffer_pull_tail(*channel_modes,
3659 ((*channel_modes)->end -
3660 (*channel_modes)->data));
3661 silc_buffer_put(*channel_modes, tmp->data, tmp->len);
3662 silc_buffer_pull(*channel_modes, len);
3663 silc_buffer_free(tmp);
3666 /* Now find all users on the channel */
3667 silc_hash_table_list(channel->user_list, &htl);
3668 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3669 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3672 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
3673 clidp->data, clidp->len,
3674 chidp->data, chidp->len);
3677 silc_buffer_realloc(*channel_users,
3679 (*channel_users)->truelen + len : len));
3680 silc_buffer_pull_tail(*channel_users,
3681 ((*channel_users)->end -
3682 (*channel_users)->data));
3684 silc_buffer_put(*channel_users, tmp->data, tmp->len);
3685 silc_buffer_pull(*channel_users, len);
3686 silc_buffer_free(tmp);
3688 /* CUMODE notify for mode change on the channel */
3689 SILC_PUT32_MSB(chl->mode, mode);
3690 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
3691 fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
3692 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
3693 4, csidp->data, csidp->len,
3695 clidp->data, clidp->len,
3698 *channel_users_modes =
3699 silc_buffer_realloc(*channel_users_modes,
3700 (*channel_users_modes ?
3701 (*channel_users_modes)->truelen + len : len));
3702 silc_buffer_pull_tail(*channel_users_modes,
3703 ((*channel_users_modes)->end -
3704 (*channel_users_modes)->data));
3706 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3707 silc_buffer_pull(*channel_users_modes, len);
3708 silc_buffer_free(tmp);
3710 silc_buffer_free(clidp);
3712 silc_hash_table_list_reset(&htl);
3713 silc_buffer_free(chidp);
3714 silc_buffer_free(csidp);
3717 /* Returns assembled packets for all channels and users on those channels
3718 from the given ID List. The packets are in the form dictated by the
3719 New Channel and New Channel User payloads. */
3721 void silc_server_announce_get_channels(SilcServer server,
3723 SilcBuffer *channels,
3724 SilcBuffer **channel_modes,
3725 SilcBuffer *channel_users,
3726 SilcBuffer **channel_users_modes,
3727 SilcUInt32 *channel_users_modes_c,
3728 SilcBuffer **channel_topics,
3729 SilcChannelID ***channel_ids,
3730 unsigned long creation_time)
3732 SilcIDCacheList list;
3733 SilcIDCacheEntry id_cache;
3734 SilcChannelEntry channel;
3737 SilcUInt16 name_len;
3739 int i = *channel_users_modes_c;
3742 SILC_LOG_DEBUG(("Start"));
3744 /* Go through all channels in the list */
3745 if (silc_idcache_get_all(id_list->channels, &list)) {
3746 if (silc_idcache_list_first(list, &id_cache)) {
3748 channel = (SilcChannelEntry)id_cache->context;
3750 if (creation_time && channel->created < creation_time)
3755 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3756 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3757 name_len = strlen(channel->channel_name);
3760 len = 4 + name_len + id_len + 4;
3762 silc_buffer_realloc(*channels,
3763 (*channels ? (*channels)->truelen +
3765 silc_buffer_pull_tail(*channels,
3766 ((*channels)->end - (*channels)->data));
3767 silc_buffer_format(*channels,
3768 SILC_STR_UI_SHORT(name_len),
3769 SILC_STR_UI_XNSTRING(channel->channel_name,
3771 SILC_STR_UI_SHORT(id_len),
3772 SILC_STR_UI_XNSTRING(cid, id_len),
3773 SILC_STR_UI_INT(channel->mode),
3775 silc_buffer_pull(*channels, len);
3778 /* Channel user modes */
3779 *channel_users_modes = silc_realloc(*channel_users_modes,
3780 sizeof(**channel_users_modes) *
3782 (*channel_users_modes)[i] = NULL;
3783 *channel_modes = silc_realloc(*channel_modes,
3784 sizeof(**channel_modes) * (i + 1));
3785 (*channel_modes)[i] = NULL;
3786 *channel_ids = silc_realloc(*channel_ids,
3787 sizeof(**channel_ids) * (i + 1));
3788 (*channel_ids)[i] = NULL;
3789 silc_server_announce_get_channel_users(server, channel,
3790 &(*channel_modes)[i],
3792 &(*channel_users_modes)[i]);
3793 (*channel_ids)[i] = channel->id;
3795 /* Channel's topic */
3796 *channel_topics = silc_realloc(*channel_topics,
3797 sizeof(**channel_topics) * (i + 1));
3798 (*channel_topics)[i] = NULL;
3799 silc_server_announce_get_channel_topic(server, channel,
3800 &(*channel_topics)[i]);
3803 if (!silc_idcache_list_next(list, &id_cache))
3807 *channel_users_modes_c += i;
3810 silc_idcache_list_free(list);
3814 /* This function is used to announce our existing channels to our router
3815 when we've connected to it. This also announces the users on the
3816 channels to the router. If the `creation_time' is non-zero only the
3817 channels that was created after the `creation_time' are announced.
3818 Note that the channel users are still announced even if the `creation_time'
3821 void silc_server_announce_channels(SilcServer server,
3822 unsigned long creation_time,
3823 SilcSocketConnection remote)
3825 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
3826 SilcBuffer *channel_users_modes = NULL;
3827 SilcBuffer *channel_topics = NULL;
3828 SilcUInt32 channel_users_modes_c = 0;
3829 SilcChannelID **channel_ids = NULL;
3831 SILC_LOG_DEBUG(("Announcing channels and channel users"));
3833 /* Get channels and channel users in local list */
3834 silc_server_announce_get_channels(server, server->local_list,
3835 &channels, &channel_modes,
3837 &channel_users_modes,
3838 &channel_users_modes_c,
3840 &channel_ids, creation_time);
3842 /* Get channels and channel users in global list */
3843 if (server->server_type != SILC_SERVER)
3844 silc_server_announce_get_channels(server, server->global_list,
3845 &channels, &channel_modes,
3847 &channel_users_modes,
3848 &channel_users_modes_c,
3850 &channel_ids, creation_time);
3853 silc_buffer_push(channels, channels->data - channels->head);
3854 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3856 /* Send the packet */
3857 silc_server_packet_send(server, remote,
3858 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3859 channels->data, channels->len,
3862 silc_buffer_free(channels);
3865 if (channel_modes) {
3868 for (i = 0; i < channel_users_modes_c; i++) {
3869 if (!channel_modes[i])
3871 silc_buffer_push(channel_modes[i],
3872 channel_modes[i]->data -
3873 channel_modes[i]->head);
3874 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
3875 channel_modes[i]->len);
3876 silc_server_packet_send_dest(server, remote,
3877 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3878 channel_ids[i], SILC_ID_CHANNEL,
3879 channel_modes[i]->data,
3880 channel_modes[i]->len,
3882 silc_buffer_free(channel_modes[i]);
3884 silc_free(channel_modes);
3887 if (channel_users) {
3888 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3889 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
3890 channel_users->len);
3892 /* Send the packet */
3893 silc_server_packet_send(server, remote,
3894 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3895 channel_users->data, channel_users->len,
3898 silc_buffer_free(channel_users);
3901 if (channel_users_modes) {
3904 for (i = 0; i < channel_users_modes_c; i++) {
3905 if (!channel_users_modes[i])
3907 silc_buffer_push(channel_users_modes[i],
3908 channel_users_modes[i]->data -
3909 channel_users_modes[i]->head);
3910 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
3911 channel_users_modes[i]->len);
3912 silc_server_packet_send_dest(server, remote,
3913 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3914 channel_ids[i], SILC_ID_CHANNEL,
3915 channel_users_modes[i]->data,
3916 channel_users_modes[i]->len,
3918 silc_buffer_free(channel_users_modes[i]);
3920 silc_free(channel_users_modes);
3923 if (channel_topics) {
3926 for (i = 0; i < channel_users_modes_c; i++) {
3927 if (!channel_topics[i])
3930 silc_buffer_push(channel_topics[i],
3931 channel_topics[i]->data -
3932 channel_topics[i]->head);
3933 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
3934 channel_topics[i]->len);
3935 silc_server_packet_send_dest(server, remote,
3936 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3937 channel_ids[i], SILC_ID_CHANNEL,
3938 channel_topics[i]->data,
3939 channel_topics[i]->len,
3941 silc_buffer_free(channel_topics[i]);
3943 silc_free(channel_topics);
3946 silc_free(channel_ids);
3949 /* Failure timeout callback. If this is called then we will immediately
3950 process the received failure. We always process the failure with timeout
3951 since we do not want to blindly trust to received failure packets.
3952 This won't be called (the timeout is cancelled) if the failure was
3953 bogus (it is bogus if remote does not close the connection after sending
3956 SILC_TASK_CALLBACK(silc_server_failure_callback)
3958 SilcServerFailureContext f = (SilcServerFailureContext)context;
3960 if (f->sock->protocol) {
3961 f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
3962 silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
3968 /* Assembles user list and users mode list from the `channel'. */
3970 bool silc_server_get_users_on_channel(SilcServer server,
3971 SilcChannelEntry channel,
3972 SilcBuffer *user_list,
3973 SilcBuffer *mode_list,
3974 SilcUInt32 *user_count)
3976 SilcChannelClientEntry chl;
3977 SilcHashTableList htl;
3978 SilcBuffer client_id_list;
3979 SilcBuffer client_mode_list;
3981 SilcUInt32 list_count = 0, len = 0;
3983 if (!silc_hash_table_count(channel->user_list))
3986 silc_hash_table_list(channel->user_list, &htl);
3987 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
3988 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
3989 silc_hash_table_list_reset(&htl);
3991 client_id_list = silc_buffer_alloc(len);
3993 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
3994 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
3995 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
3997 silc_hash_table_list(channel->user_list, &htl);
3998 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4000 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4001 silc_buffer_put(client_id_list, idp->data, idp->len);
4002 silc_buffer_pull(client_id_list, idp->len);
4003 silc_buffer_free(idp);
4005 /* Client's mode on channel */
4006 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4007 silc_buffer_pull(client_mode_list, 4);
4011 silc_hash_table_list_reset(&htl);
4012 silc_buffer_push(client_id_list,
4013 client_id_list->data - client_id_list->head);
4014 silc_buffer_push(client_mode_list,
4015 client_mode_list->data - client_mode_list->head);
4017 *user_list = client_id_list;
4018 *mode_list = client_mode_list;
4019 *user_count = list_count;
4023 /* Saves users and their modes to the `channel'. */
4025 void silc_server_save_users_on_channel(SilcServer server,
4026 SilcSocketConnection sock,
4027 SilcChannelEntry channel,
4028 SilcClientID *noadd,
4029 SilcBuffer user_list,
4030 SilcBuffer mode_list,
4031 SilcUInt32 user_count)
4036 SilcClientID *client_id;
4037 SilcClientEntry client;
4038 SilcIDCacheEntry cache;
4039 SilcChannelClientEntry chl;
4042 SILC_LOG_DEBUG(("Start"));
4044 for (i = 0; i < user_count; i++) {
4046 SILC_GET16_MSB(idp_len, user_list->data + 2);
4048 client_id = silc_id_payload_parse_id(user_list->data, idp_len, NULL);
4049 silc_buffer_pull(user_list, idp_len);
4054 SILC_GET32_MSB(mode, mode_list->data);
4055 silc_buffer_pull(mode_list, 4);
4057 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
4058 silc_free(client_id);
4064 /* Check if we have this client cached already. */
4065 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4066 server->server_type, &cache);
4068 client = silc_idlist_find_client_by_id(server->global_list,
4069 client_id, server->server_type,
4074 /* If router did not find such Client ID in its lists then this must
4075 be bogus client or some router in the net is buggy. */
4076 if (server->server_type == SILC_ROUTER) {
4077 silc_free(client_id);
4081 /* We don't have that client anywhere, add it. The client is added
4082 to global list since server didn't have it in the lists so it must be
4084 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4085 silc_id_dup(client_id, SILC_ID_CLIENT),
4086 sock->user_data, NULL, 0);
4088 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4089 silc_free(client_id);
4093 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4095 /* Found, if it is from global list we'll assure that we won't
4096 expire it now that the entry is on channel. */
4101 silc_free(client_id);
4103 if (!silc_server_client_on_channel(client, channel, &chl)) {
4104 /* Client was not on the channel, add it. */
4105 chl = silc_calloc(1, sizeof(*chl));
4106 chl->client = client;
4108 chl->channel = channel;
4109 silc_hash_table_add(channel->user_list, chl->client, chl);
4110 silc_hash_table_add(client->channels, chl->channel, chl);
4111 channel->user_count++;
4119 /* Saves channels and channels user modes to the `client'. Removes
4120 the client from those channels that are not sent in the list but
4123 void silc_server_save_user_channels(SilcServer server,
4124 SilcSocketConnection sock,
4125 SilcClientEntry client,
4126 SilcBuffer channels,
4127 SilcBuffer channels_user_modes)
4130 SilcUInt32 *chumodes;
4131 SilcChannelPayload entry;
4132 SilcChannelEntry channel;
4133 SilcChannelID *channel_id;
4134 SilcChannelClientEntry chl;
4135 SilcHashTable ht = NULL;
4136 SilcHashTableList htl;
4140 if (!channels ||!channels_user_modes)
4143 ch = silc_channel_payload_parse_list(channels->data, channels->len);
4144 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4146 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4147 NULL, NULL, NULL, TRUE);
4148 silc_dlist_start(ch);
4149 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4150 /* Check if we have this channel, and add it if we don't have it.
4151 Also add the client on the channel unless it is there already. */
4152 channel_id = silc_channel_get_id_parse(entry);
4153 channel = silc_idlist_find_channel_by_id(server->local_list,
4156 channel = silc_idlist_find_channel_by_id(server->global_list,
4159 if (server->server_type != SILC_SERVER) {
4160 silc_free(channel_id);
4165 /* We don't have that channel anywhere, add it. */
4166 name = silc_channel_get_name(entry, NULL);
4167 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4168 channel_id, server->router,
4171 silc_free(channel_id);
4178 channel->mode = silc_channel_get_mode(entry);
4180 /* Add the client on the channel */
4181 if (!silc_server_client_on_channel(client, channel, &chl)) {
4182 chl = silc_calloc(1, sizeof(*chl));
4183 chl->client = client;
4184 chl->mode = chumodes[i++];
4185 chl->channel = channel;
4186 silc_hash_table_add(channel->user_list, chl->client, chl);
4187 silc_hash_table_add(client->channels, chl->channel, chl);
4188 channel->user_count++;
4191 chl->mode = chumodes[i++];
4194 silc_hash_table_add(ht, channel, channel);
4195 silc_free(channel_id);
4197 silc_channel_payload_list_free(ch);
4198 silc_free(chumodes);
4202 /* Go through the list again and remove client from channels that
4203 are no part of the list. */
4205 silc_hash_table_list(client->channels, &htl);
4206 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
4207 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4208 silc_hash_table_del(chl->channel->user_list, chl->client);
4209 silc_hash_table_del(chl->client->channels, chl->channel);
4213 silc_hash_table_list_reset(&htl);
4214 silc_hash_table_free(ht);
4216 silc_hash_table_list(client->channels, &htl);
4217 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
4218 silc_hash_table_del(chl->channel->user_list, chl->client);
4219 silc_hash_table_del(chl->client->channels, chl->channel);
4222 silc_hash_table_list_reset(&htl);
4226 /* Lookups route to the client indicated by the `id_data'. The connection
4227 object and internal data object is returned. Returns NULL if route
4228 could not be found to the client. If the `client_id' is specified then
4229 it is used and the `id_data' is ignored. */
4231 SilcSocketConnection
4232 silc_server_get_client_route(SilcServer server,
4233 unsigned char *id_data,
4235 SilcClientID *client_id,
4236 SilcIDListData *idata,
4237 SilcClientEntry *client_entry)
4240 SilcClientEntry client;
4242 SILC_LOG_DEBUG(("Start"));
4245 *client_entry = NULL;
4247 /* Decode destination Client ID */
4249 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
4251 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
4255 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4258 /* If the destination belongs to our server we don't have to route
4259 the packet anywhere but to send it to the local destination. */
4260 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4264 /* If we are router and the client has router then the client is in
4265 our cell but not directly connected to us. */
4266 if (server->server_type == SILC_ROUTER && client->router) {
4267 /* We are of course in this case the client's router thus the route
4268 to the client is the server who owns the client. So, we will send
4269 the packet to that server. */
4271 *idata = (SilcIDListData)client->router;
4272 return client->router->connection;
4275 /* Seems that client really is directly connected to us */
4277 *idata = (SilcIDListData)client;
4279 *client_entry = client;
4280 return client->connection;
4283 /* Destination belongs to someone not in this server. If we are normal
4284 server our action is to send the packet to our router. */
4285 if (server->server_type != SILC_ROUTER && !server->standalone) {
4288 *idata = (SilcIDListData)server->router;
4289 return server->router->connection;
4292 /* We are router and we will perform route lookup for the destination
4293 and send the packet to fastest route. */
4294 if (server->server_type == SILC_ROUTER && !server->standalone) {
4295 /* Check first that the ID is valid */
4296 client = silc_idlist_find_client_by_id(server->global_list, id,
4299 SilcSocketConnection dst_sock;
4301 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4305 *idata = (SilcIDListData)dst_sock->user_data;
4314 /* Encodes and returns channel list of channels the `client' has joined.
4315 Secret channels are not put to the list. */
4317 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4318 SilcClientEntry client,
4321 SilcBuffer *user_mode_list)
4323 SilcBuffer buffer = NULL;
4324 SilcChannelEntry channel;
4325 SilcChannelClientEntry chl;
4326 SilcHashTableList htl;
4329 SilcUInt16 name_len;
4333 *user_mode_list = NULL;
4335 silc_hash_table_list(client->channels, &htl);
4336 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4337 channel = chl->channel;
4339 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4341 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4344 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
4345 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
4346 name_len = strlen(channel->channel_name);
4348 len = 4 + name_len + id_len + 4;
4349 buffer = silc_buffer_realloc(buffer,
4350 (buffer ? buffer->truelen + len : len));
4351 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4352 silc_buffer_format(buffer,
4353 SILC_STR_UI_SHORT(name_len),
4354 SILC_STR_UI_XNSTRING(channel->channel_name,
4356 SILC_STR_UI_SHORT(id_len),
4357 SILC_STR_UI_XNSTRING(cid, id_len),
4358 SILC_STR_UI_INT(chl->channel->mode),
4360 silc_buffer_pull(buffer, len);
4363 if (user_mode_list) {
4364 *user_mode_list = silc_buffer_realloc(*user_mode_list,
4366 (*user_mode_list)->truelen + 4 :
4368 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
4369 (*user_mode_list)->data));
4370 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
4371 silc_buffer_pull(*user_mode_list, 4);
4374 silc_hash_table_list_reset(&htl);
4377 silc_buffer_push(buffer, buffer->data - buffer->head);
4378 if (user_mode_list && *user_mode_list)
4379 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
4380 (*user_mode_list)->head));
4385 /* Finds client entry by Client ID and if it is not found then resolves
4386 it using WHOIS command. */
4388 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
4389 SilcClientID *client_id,
4390 bool always_resolve,
4393 SilcClientEntry client;
4398 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4401 client = silc_idlist_find_client_by_id(server->global_list,
4402 client_id, TRUE, NULL);
4403 if (!client && server->server_type == SILC_ROUTER)
4407 if (!client && server->standalone)
4410 if (!client || !client->nickname || !client->username ||
4412 SilcBuffer buffer, idp;
4415 client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
4416 client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
4417 client->resolve_cmd_ident = ++server->cmd_ident;
4420 idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
4421 buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
4422 server->cmd_ident, 1,
4423 4, idp->data, idp->len);
4424 silc_server_packet_send(server, client ? client->router->connection :
4425 server->router->connection,
4426 SILC_PACKET_COMMAND, 0,
4427 buffer->data, buffer->len, FALSE);
4428 silc_buffer_free(idp);
4429 silc_buffer_free(buffer);
4440 /* A timeout callback for the re-key. We will be the initiator of the
4443 SILC_TASK_CALLBACK(silc_server_rekey_callback)
4445 SilcSocketConnection sock = (SilcSocketConnection)context;
4446 SilcIDListData idata = (SilcIDListData)sock->user_data;
4447 SilcServer server = (SilcServer)idata->rekey->context;
4448 SilcProtocol protocol;
4449 SilcServerRekeyInternalContext *proto_ctx;
4451 SILC_LOG_DEBUG(("Start"));
4453 /* Allocate internal protocol context. This is sent as context
4455 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
4456 proto_ctx->server = (void *)server;
4457 proto_ctx->sock = sock;
4458 proto_ctx->responder = FALSE;
4459 proto_ctx->pfs = idata->rekey->pfs;
4461 /* Perform rekey protocol. Will call the final callback after the
4462 protocol is over. */
4463 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
4464 &protocol, proto_ctx, silc_server_rekey_final);
4465 sock->protocol = protocol;
4467 /* Run the protocol */
4468 silc_protocol_execute(protocol, server->schedule, 0, 0);
4470 /* Re-register re-key timeout */
4471 silc_schedule_task_add(server->schedule, sock->sock,
4472 silc_server_rekey_callback,
4473 context, idata->rekey->timeout, 0,
4474 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
4477 /* The final callback for the REKEY protocol. This will actually take the
4478 new key material into use. */
4480 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
4482 SilcProtocol protocol = (SilcProtocol)context;
4483 SilcServerRekeyInternalContext *ctx =
4484 (SilcServerRekeyInternalContext *)protocol->context;
4485 SilcServer server = (SilcServer)ctx->server;
4486 SilcSocketConnection sock = ctx->sock;
4488 SILC_LOG_DEBUG(("Start"));
4490 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
4491 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
4492 /* Error occured during protocol */
4493 SILC_LOG_ERROR(("Error occurred during rekey protocol"));
4494 silc_protocol_cancel(protocol, server->schedule);
4495 silc_protocol_free(protocol);
4496 sock->protocol = NULL;
4498 silc_packet_context_free(ctx->packet);
4500 silc_ske_free(ctx->ske);
4505 /* Purge the outgoing data queue to assure that all rekey packets really
4506 go to the network before we quit the protocol. */
4507 silc_server_packet_queue_purge(server, sock);
4510 silc_protocol_free(protocol);
4511 sock->protocol = NULL;
4513 silc_packet_context_free(ctx->packet);
4515 silc_ske_free(ctx->ske);
4519 /* Task callback used to retrieve network statistical information from
4520 router server once in a while. */
4522 SILC_TASK_CALLBACK(silc_server_get_stats)
4524 SilcServer server = (SilcServer)context;
4525 SilcBuffer idp, packet;
4527 SILC_LOG_DEBUG(("Retrieving stats from router"));
4529 if (!server->standalone) {
4530 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
4531 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
4532 ++server->cmd_ident, 1,
4533 1, idp->data, idp->len);
4534 silc_server_packet_send(server, server->router->connection,
4535 SILC_PACKET_COMMAND, 0, packet->data,
4536 packet->len, FALSE);
4537 silc_buffer_free(packet);
4538 silc_buffer_free(idp);
4541 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
4542 server, 120, 0, SILC_TASK_TIMEOUT,