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_router);
32 SILC_TASK_CALLBACK(silc_server_connect_to_router);
33 SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
34 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
35 SILC_TASK_CALLBACK(silc_server_accept_new_connection);
36 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second);
37 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final);
38 SILC_TASK_CALLBACK(silc_server_packet_process);
39 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
40 SILC_TASK_CALLBACK(silc_server_timeout_remote);
41 SILC_TASK_CALLBACK(silc_server_failure_callback);
42 SILC_TASK_CALLBACK(silc_server_rekey_callback);
44 /* Allocates a new SILC server object. This has to be done before the server
45 can be used. After allocation one must call silc_server_init to initialize
46 the server. The new allocated server object is returned to the new_server
49 int silc_server_alloc(SilcServer *new_server)
53 SILC_LOG_DEBUG(("Allocating new server object"));
55 server = silc_calloc(1, sizeof(*server));
56 server->server_type = SILC_SERVER;
57 server->standalone = TRUE;
58 server->local_list = silc_calloc(1, sizeof(*server->local_list));
59 server->global_list = silc_calloc(1, sizeof(*server->global_list));
60 server->pending_commands = silc_dlist_init();
62 server->sim = silc_dlist_init();
70 /* Free's the SILC server object. This is called at the very end before
73 void silc_server_free(SilcServer server)
80 silc_free(server->local_list);
81 silc_free(server->global_list);
83 silc_rng_free(server->rng);
86 silc_pkcs_free(server->pkcs);
89 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
90 silc_dlist_del(server->sim, sim);
93 silc_dlist_uninit(server->sim);
96 if (server->pending_commands)
97 silc_dlist_uninit(server->pending_commands);
103 /* Initializes the entire SILC server. This is called always before running
104 the server. This is called only once at the initialization of the program.
105 This binds the server to its listenning port. After this function returns
106 one should call silc_server_run to start the server. This returns TRUE
107 when everything is ok to run the server. Configuration file must be
108 read and parsed before calling this. */
110 int silc_server_init(SilcServer server)
114 SilcServerEntry id_entry;
115 SilcIDListPurge purge;
117 SILC_LOG_DEBUG(("Initializing server"));
119 assert(server->config);
121 /* Set public and private keys */
122 if (!server->config->server_info ||
123 !server->config->server_info->public_key ||
124 !server->config->server_info->private_key) {
125 SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
128 server->public_key = server->config->server_info->public_key;
129 server->private_key = server->config->server_info->private_key;
131 /* Set default to configuration parameters */
132 silc_server_config_set_defaults(server);
134 /* Register all configured ciphers, PKCS and hash functions. */
135 if (!silc_server_config_register_ciphers(server))
136 silc_cipher_register_default();
137 if (!silc_server_config_register_pkcs(server))
138 silc_pkcs_register_default();
139 if (!silc_server_config_register_hashfuncs(server))
140 silc_hash_register_default();
141 if (!silc_server_config_register_hmacs(server))
142 silc_hmac_register_default();
144 /* Initialize random number generator for the server. */
145 server->rng = silc_rng_alloc();
146 silc_rng_init(server->rng);
147 silc_rng_global_init(server->rng);
149 /* Initialize hash functions for server to use */
150 silc_hash_alloc("md5", &server->md5hash);
151 silc_hash_alloc("sha1", &server->sha1hash);
153 /* Allocate PKCS context for local public and private keys */
154 silc_pkcs_alloc(server->public_key->name, &server->pkcs);
155 silc_pkcs_public_key_set(server->pkcs, server->public_key);
156 silc_pkcs_private_key_set(server->pkcs, server->private_key);
158 /* Create a listening server */
159 sock = silc_net_create_server(server->config->server_info->port,
160 server->config->server_info->server_ip);
161 /* XXX What if I want my errno? Where is my errno?!? -Johnny */
163 SILC_LOG_ERROR(("Could not create server listener: %s on %hu",
164 server->config->server_info->server_ip,
165 server->config->server_info->port));
169 /* Initialize ID caches */
170 server->local_list->clients =
171 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
172 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
173 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
175 /* These are allocated for normal server as well as these hold some
176 global information that the server has fetched from its router. For
177 router these are used as they are supposed to be used on router. */
178 server->global_list->clients =
179 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
180 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
181 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
183 /* Allocate the entire socket list that is used in server. Eventually
184 all connections will have entry in this table (it is a table of
185 pointers to the actual object that is allocated individually
187 server->sockets = silc_calloc(SILC_SERVER_MAX_CONNECTIONS,
188 sizeof(*server->sockets));
191 SilcSocketConnection newsocket = NULL;
193 /* Set socket to non-blocking mode */
194 silc_net_set_socket_nonblock(sock);
197 /* Add ourselves also to the socket table. The entry allocated above
198 is sent as argument for fast referencing in the future. */
199 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
200 server->sockets[sock] = newsocket;
202 /* Perform name and address lookups to resolve the listenning address
204 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
206 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
208 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
209 newsocket->hostname ? newsocket->hostname :
210 newsocket->ip ? newsocket->ip : ""));
211 server->stat.conn_failures++;
214 if (!newsocket->hostname)
215 newsocket->hostname = strdup(newsocket->ip);
217 newsocket->port = silc_net_get_local_port(sock);
219 /* Create a Server ID for the server. */
220 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
225 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
226 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
227 server->id_type = SILC_ID_SERVER;
228 server->server_name = server->config->server_info->server_name;
230 /* Add ourselves to the server list. We don't have a router yet
231 beacuse we haven't established a route yet. It will be done later.
232 For now, NULL is sent as router. This allocates new entry to
235 silc_idlist_add_server(server->local_list,
236 server->config->server_info->server_name,
237 server->server_type, server->id, NULL, NULL);
239 SILC_LOG_ERROR(("Could not add ourselves to cache"));
242 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
244 /* Put the allocated socket pointer also to the entry allocated above
245 for fast back-referencing to the socket list. */
246 newsocket->user_data = (void *)id_entry;
247 id_entry->connection = (void *)newsocket;
248 server->id_entry = id_entry;
251 /* Register protocols */
252 silc_server_protocols_register();
254 /* Initialize the scheduler. */
255 server->schedule = silc_schedule_init(SILC_SERVER_MAX_CONNECTIONS);
256 if (!server->schedule)
259 /* Add the first task to the scheduler. This is task that is executed by
260 timeout. It expires as soon as the caller calls silc_server_run. This
261 task performs authentication protocol and key exchange with our
263 silc_schedule_task_add(server->schedule, sock,
264 silc_server_connect_to_router,
265 (void *)server, 0, 1,
267 SILC_TASK_PRI_NORMAL);
269 /* Add listener task to the scheduler. This task receives new connections
270 to the server. This task remains on the queue until the end of the
272 silc_schedule_task_add(server->schedule, sock,
273 silc_server_accept_new_connection,
274 (void *)server, 0, 0,
276 SILC_TASK_PRI_NORMAL);
277 server->listenning = TRUE;
279 /* Send log file configuration */
280 silc_server_config_setlogfiles(server);
282 /* If server connections has been configured then we must be router as
283 normal server cannot have server connections, only router connections. */
284 if (server->config->servers) {
285 SilcServerConfigSectionServer *ptr = server->config->servers;
287 server->server_type = SILC_ROUTER;
289 if (ptr->backup_router) {
290 server->server_type = SILC_BACKUP_ROUTER;
291 server->backup_router = TRUE;
292 server->id_entry->server_type = SILC_BACKUP_ROUTER;
299 /* Register the ID Cache purge task. This periodically purges the ID cache
300 and removes the expired cache entries. */
302 /* Clients local list */
303 purge = silc_calloc(1, sizeof(*purge));
304 purge->cache = server->local_list->clients;
305 purge->schedule = server->schedule;
306 purge->timeout = 600;
307 silc_schedule_task_add(purge->schedule, 0,
309 (void *)purge, purge->timeout, 0,
310 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
312 /* Clients global list */
313 purge = silc_calloc(1, sizeof(*purge));
314 purge->cache = server->global_list->clients;
315 purge->schedule = server->schedule;
316 purge->timeout = 300;
317 silc_schedule_task_add(purge->schedule, 0,
319 (void *)purge, purge->timeout, 0,
320 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
322 SILC_LOG_DEBUG(("Server initialized"));
324 /* We are done here, return succesfully */
328 silc_net_close_server(sock);
332 /* Fork server to background */
334 void silc_server_daemonise(SilcServer server)
338 SILC_LOG_DEBUG(("Forking SILC server to background"));
343 SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
348 SILC_LOG_DEBUG(("Server started as user"));
350 SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
356 /* Drop root privligies. If this cannot be done, die. */
358 void silc_server_drop(SilcServer server)
360 /* Are we executing silcd as root or a regular user? */
366 /* Get the values given for user and group in configuration file */
367 user = server->config->server_info->user;
368 group = server->config->server_info->group;
370 if (!user || !group) {
371 fprintf(stderr, "Error:" /* XXX update this error message */
372 "\tSILC server must not be run as root. For the security of your\n"
373 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
374 "\tuser account. Modify the [Identity] configuration section to run\n"
375 "\tthe server as non-root user.\n");
379 /* Check whether the user/group does not begin with a number */
380 if (isdigit(user[0]) || isdigit(group[0])) {
381 SILC_LOG_DEBUG(("User and/or group starts with a number"));
382 fprintf(stderr, "Invalid user and/or group information\n");
383 fprintf(stderr, "Please assign them as names, not numbers\n");
387 if (!(pw = getpwnam(user))) {
388 fprintf(stderr, "Error: No such user %s found.\n", user);
391 if (!(gr = getgrnam(group))) {
392 fprintf(stderr, "Error: No such group %s found.\n", group);
396 /* Check whether user and/or group is set to root. If yes, exit
397 immediately. Otherwise, setgid and setuid server to user.group */
398 if ((gr->gr_gid == 0) || (pw->pw_uid == 0)) {
399 fprintf(stderr, "Error:"
400 "\tSILC server must not be run as root. For the security of your\n"
401 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
402 "\tuser account. Modify the [Identity] configuration section to run\n"
403 "\tthe server as non-root user.\n");
407 SILC_LOG_DEBUG(("Changing to group %s (gid=%u)", group, gr->gr_gid));
408 if (setgid(gr->gr_gid) != 0) {
409 fprintf(stderr, "Error: Failed setgid() to %s (gid=%u). Exiting.\n",
413 #if defined HAVE_SETGROUPS && defined HAVE_INITGROUPS
414 SILC_LOG_DEBUG(("Removing supplementary groups"));
415 if (setgroups(0, NULL) != 0) {
416 fprintf(stderr, "Error: Failed setgroups() to NULL. Exiting.\n");
419 SILC_LOG_DEBUG(("Setting supplementary groups for user %s", user));
420 if (initgroups(user, gr->gr_gid) != 0) {
421 fprintf(stderr, "Error: Failed initgroups() for user %s (gid=%u). "
422 "Exiting.\n", user, gr->gr_gid);
426 SILC_LOG_DEBUG(("Changing to user %s (uid=%u)", user, pw->pw_uid));
427 if (setuid(pw->pw_uid) != 0) {
428 fprintf(stderr, "Error: Failed to setuid() to %s (gid=%u). Exiting.\n",
435 /* The heart of the server. This runs the scheduler thus runs the server.
436 When this returns the server has been stopped and the program will
439 void silc_server_run(SilcServer server)
441 SILC_LOG_DEBUG(("Running server"));
443 SILC_LOG_INFO(("SILC Server started"));
445 /* Start the scheduler, the heart of the SILC server. When this returns
446 the program will be terminated. */
447 silc_schedule(server->schedule);
450 /* Stops the SILC server. This function is used to shutdown the server.
451 This is usually called after the scheduler has returned. After stopping
452 the server one should call silc_server_free. */
454 void silc_server_stop(SilcServer server)
456 SILC_LOG_DEBUG(("Stopping server"));
458 if (server->schedule) {
459 silc_schedule_stop(server->schedule);
460 silc_schedule_uninit(server->schedule);
461 server->schedule = NULL;
464 silc_server_protocols_unregister();
466 SILC_LOG_DEBUG(("Server stopped"));
469 /* Function that is called when the network connection to a router has
470 been established. This will continue with the key exchange protocol
471 with the remote router. */
473 void silc_server_start_key_exchange(SilcServer server,
474 SilcServerConnection sconn,
477 SilcSocketConnection newsocket;
478 SilcProtocol protocol;
479 SilcServerKEInternalContext *proto_ctx;
482 /* Cancel any possible retry timeouts */
483 silc_schedule_task_del_by_callback(server->schedule,
484 silc_server_connect_router);
486 /* Set socket options */
487 silc_net_set_socket_nonblock(sock);
488 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
490 /* Create socket connection for the connection. Even though we
491 know that we are connecting to a router we will mark the socket
492 to be unknown connection until we have executed authentication
494 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
495 server->sockets[sock] = newsocket;
496 newsocket->hostname = strdup(sconn->remote_host);
497 newsocket->ip = strdup(sconn->remote_host);
498 newsocket->port = sconn->remote_port;
499 sconn->sock = newsocket;
501 /* Allocate internal protocol context. This is sent as context
503 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
504 proto_ctx->server = (void *)server;
505 proto_ctx->context = (void *)sconn;
506 proto_ctx->sock = newsocket;
507 proto_ctx->rng = server->rng;
508 proto_ctx->responder = FALSE;
510 /* Perform key exchange protocol. silc_server_connect_to_router_second
511 will be called after the protocol is finished. */
512 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
513 &protocol, proto_ctx,
514 silc_server_connect_to_router_second);
515 newsocket->protocol = protocol;
517 /* Register a timeout task that will be executed if the protocol
518 is not executed within set limit. */
519 proto_ctx->timeout_task =
520 silc_schedule_task_add(server->schedule, sock,
521 silc_server_timeout_remote,
522 server, 60, 0, /* XXX hardcoded */
526 /* Register the connection for network input and output. This sets
527 that scheduler will listen for incoming packets for this connection
528 and sets that outgoing packets may be sent to this connection as
529 well. However, this doesn't set the scheduler for outgoing traffic,
530 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
531 later when outgoing data is available. */
532 context = (void *)server;
533 SILC_REGISTER_CONNECTION_FOR_IO(sock);
535 /* Run the protocol */
536 silc_protocol_execute(protocol, server->schedule, 0, 0);
539 /* Timeout callback that will be called to retry connecting to remote
540 router. This is used by both normal and router server. This will wait
541 before retrying the connecting. The timeout is generated by exponential
542 backoff algorithm. */
544 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
546 SilcServerConnection sconn = (SilcServerConnection)context;
547 SilcServer server = sconn->server;
548 SilcServerConfigSectionConnectionParam *param;
550 param = (sconn->param ? sconn->param : &server->config->param);
552 SILC_LOG_INFO(("Retrying connecting to a router"));
554 /* Calculate next timeout */
555 if (sconn->retry_count >= 1) {
556 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
557 if (sconn->retry_timeout > param->reconnect_interval_max)
558 sconn->retry_timeout = param->reconnect_interval_max;
560 sconn->retry_timeout = param->reconnect_interval;
562 sconn->retry_count++;
563 sconn->retry_timeout = sconn->retry_timeout +
564 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
566 /* If we've reached max retry count, give up. */
567 if (sconn->retry_count > param->reconnect_count &&
568 param->reconnect_keep_trying == FALSE) {
569 SILC_LOG_ERROR(("Could not connect to router, giving up"));
570 silc_free(sconn->remote_host);
575 /* Wait one before retrying */
576 silc_schedule_task_add(server->schedule, fd, silc_server_connect_router,
577 context, sconn->retry_timeout, 0,
578 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
581 /* Generic routine to use connect to a router. */
583 SILC_TASK_CALLBACK(silc_server_connect_router)
585 SilcServerConnection sconn = (SilcServerConnection)context;
586 SilcServer server = sconn->server;
589 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
590 (sconn->backup ? "backup router" : "router"),
591 sconn->remote_host, sconn->remote_port));
593 server->router_connect = time(NULL);
595 /* Connect to remote host */
596 sock = silc_net_create_connection(server->config->server_info->server_ip,
600 SILC_LOG_ERROR(("Could not connect to router %s:%d",
601 sconn->remote_host, sconn->remote_port));
602 if (!sconn->no_reconnect)
603 silc_schedule_task_add(server->schedule, fd,
604 silc_server_connect_to_router_retry,
605 context, 0, 1, SILC_TASK_TIMEOUT,
606 SILC_TASK_PRI_NORMAL);
610 /* Continue with key exchange protocol */
611 silc_server_start_key_exchange(server, sconn, sock);
614 /* This function connects to our primary router or if we are a router this
615 establishes all our primary routes. This is called at the start of the
616 server to do authentication and key exchange with our router - called
619 SILC_TASK_CALLBACK(silc_server_connect_to_router)
621 SilcServer server = (SilcServer)context;
622 SilcServerConnection sconn;
623 SilcServerConfigSectionRouter *ptr;
625 SILC_LOG_DEBUG(("Connecting to router(s)"));
627 if (server->server_type == SILC_SERVER) {
628 SILC_LOG_DEBUG(("We are normal server"));
629 } else if (server->server_type == SILC_ROUTER) {
630 SILC_LOG_DEBUG(("We are router"));
632 SILC_LOG_DEBUG(("We are backup router/normal server"));
635 /* Create the connections to all our routes */
636 ptr = server->config->routers;
639 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
640 ptr->backup_router ? "Backup router" : "Router",
641 ptr->initiator ? "Initiator" : "Responder",
642 ptr->host, ptr->port));
644 if (ptr->initiator) {
645 /* Allocate connection object for hold connection specific stuff. */
646 sconn = silc_calloc(1, sizeof(*sconn));
647 sconn->server = server;
648 sconn->remote_host = strdup(ptr->host);
649 sconn->remote_port = ptr->port;
650 sconn->backup = ptr->backup_router;
652 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
653 sconn->backup_replace_port = ptr->backup_replace_port;
656 if (!server->router_conn && !sconn->backup)
657 server->router_conn = sconn;
660 sconn->param = ptr->param;
662 silc_schedule_task_add(server->schedule, fd,
663 silc_server_connect_router,
664 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
665 SILC_TASK_PRI_NORMAL);
674 SILC_LOG_DEBUG(("No router(s), server will be standalone"));
676 /* There wasn't a configured router, we will continue but we don't
677 have a connection to outside world. We will be standalone server. */
678 server->standalone = TRUE;
681 /* Second part of connecting to router(s). Key exchange protocol has been
682 executed and now we will execute authentication protocol. */
684 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
686 SilcProtocol protocol = (SilcProtocol)context;
687 SilcServerKEInternalContext *ctx =
688 (SilcServerKEInternalContext *)protocol->context;
689 SilcServer server = (SilcServer)ctx->server;
690 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
691 SilcSocketConnection sock = ctx->sock;
692 SilcServerConnAuthInternalContext *proto_ctx;
693 SilcServerConfigSectionRouter *conn = NULL;
695 SILC_LOG_DEBUG(("Start"));
697 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
698 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
699 /* Error occured during protocol */
700 silc_protocol_free(protocol);
701 sock->protocol = NULL;
702 silc_ske_free_key_material(ctx->keymat);
704 silc_packet_context_free(ctx->packet);
706 silc_ske_free(ctx->ske);
707 silc_free(ctx->dest_id);
709 silc_schedule_task_del_by_callback(server->schedule,
710 silc_server_failure_callback);
711 silc_server_disconnect_remote(server, sock, "Server closed connection: "
712 "Key exchange failed");
716 /* We now have the key material as the result of the key exchange
717 protocol. Take the key material into use. Free the raw key material
718 as soon as we've set them into use. */
719 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
720 ctx->sock, ctx->keymat,
721 ctx->ske->prop->cipher,
722 ctx->ske->prop->pkcs,
723 ctx->ske->prop->hash,
724 ctx->ske->prop->hmac,
725 ctx->ske->prop->group,
727 silc_protocol_free(protocol);
728 sock->protocol = NULL;
729 silc_ske_free_key_material(ctx->keymat);
731 silc_packet_context_free(ctx->packet);
733 silc_ske_free(ctx->ske);
734 silc_free(ctx->dest_id);
736 silc_schedule_task_del_by_callback(server->schedule,
737 silc_server_failure_callback);
738 silc_server_disconnect_remote(server, sock, "Server closed connection: "
739 "Key exchange failed");
742 silc_ske_free_key_material(ctx->keymat);
744 /* Allocate internal context for the authentication protocol. This
745 is sent as context for the protocol. */
746 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
747 proto_ctx->server = (void *)server;
748 proto_ctx->context = (void *)sconn;
749 proto_ctx->sock = sock;
750 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
751 proto_ctx->dest_id_type = ctx->dest_id_type;
752 proto_ctx->dest_id = ctx->dest_id;
754 /* Resolve the authentication method used in this connection. Check if
755 we find a match from user configured connections */
757 conn = silc_server_config_find_router_conn(server, sock->hostname,
763 /* Match found. Use the configured authentication method */
764 if (conn->passphrase) {
765 if (conn->publickey && !server->config->prefer_passphrase_auth) {
766 proto_ctx->auth_data = conn->publickey;
767 proto_ctx->auth_data_len = 0;
768 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
770 proto_ctx->auth_data = strdup(conn->passphrase);
771 proto_ctx->auth_data_len = strlen(conn->passphrase);
772 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
774 } else if (conn->publickey) {
775 proto_ctx->auth_data = conn->publickey;
776 proto_ctx->auth_data_len = 0;
777 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
779 proto_ctx->auth_meth = SILC_AUTH_NONE;
782 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
783 sock->hostname, sock->ip, sock->port));
784 silc_protocol_free(protocol);
785 sock->protocol = NULL;
787 silc_packet_context_free(ctx->packet);
789 silc_ske_free(ctx->ske);
790 silc_free(ctx->dest_id);
792 silc_schedule_task_del_by_callback(server->schedule,
793 silc_server_failure_callback);
794 silc_server_disconnect_remote(server, sock, "Server closed connection: "
795 "Key exchange failed");
799 /* Free old protocol as it is finished now */
800 silc_protocol_free(protocol);
802 silc_packet_context_free(ctx->packet);
804 sock->protocol = NULL;
806 /* Allocate the authentication protocol. This is allocated here
807 but we won't start it yet. We will be receiving party of this
808 protocol thus we will wait that connecting party will make
810 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
811 &sock->protocol, proto_ctx,
812 silc_server_connect_to_router_final);
814 /* Register timeout task. If the protocol is not executed inside
815 this timelimit the connection will be terminated. */
816 proto_ctx->timeout_task =
817 silc_schedule_task_add(server->schedule, sock->sock,
818 silc_server_timeout_remote,
819 (void *)server, 15, 0, /* XXX hardcoded */
823 /* Run the protocol */
824 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
827 /* Finalizes the connection to router. Registers a server task to the
828 queue so that we can accept new connections. */
830 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
832 SilcProtocol protocol = (SilcProtocol)context;
833 SilcServerConnAuthInternalContext *ctx =
834 (SilcServerConnAuthInternalContext *)protocol->context;
835 SilcServer server = (SilcServer)ctx->server;
836 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
837 SilcSocketConnection sock = ctx->sock;
838 SilcServerEntry id_entry;
840 SilcServerHBContext hb_context;
841 unsigned char *id_string;
843 SilcIDListData idata;
844 SilcServerConfigSectionConnectionParam *param;
846 SILC_LOG_DEBUG(("Start"));
848 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
849 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
850 /* Error occured during protocol */
851 silc_free(ctx->dest_id);
852 silc_server_disconnect_remote(server, sock, "Server closed connection: "
853 "Authentication failed");
857 /* Add a task to the queue. This task receives new connections to the
858 server. This task remains on the queue until the end of the program. */
859 if (!server->listenning && !sconn->backup) {
860 silc_schedule_task_add(server->schedule, server->sock,
861 silc_server_accept_new_connection,
862 (void *)server, 0, 0,
864 SILC_TASK_PRI_NORMAL);
865 server->listenning = TRUE;
868 /* Send NEW_SERVER packet to the router. We will become registered
869 to the SILC network after sending this packet. */
870 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
871 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
872 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
873 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
874 silc_buffer_format(packet,
875 SILC_STR_UI_SHORT(id_len),
876 SILC_STR_UI_XNSTRING(id_string, id_len),
877 SILC_STR_UI_SHORT(strlen(server->server_name)),
878 SILC_STR_UI_XNSTRING(server->server_name,
879 strlen(server->server_name)),
882 /* Send the packet */
883 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
884 packet->data, packet->len, TRUE);
885 silc_buffer_free(packet);
886 silc_free(id_string);
888 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
890 /* Check that we do not have this ID already */
891 id_entry = silc_idlist_find_server_by_id(server->local_list,
892 ctx->dest_id, TRUE, NULL);
894 silc_idcache_del_by_context(server->local_list->servers, id_entry);
896 id_entry = silc_idlist_find_server_by_id(server->global_list,
897 ctx->dest_id, TRUE, NULL);
899 silc_idcache_del_by_context(server->global_list->servers, id_entry);
902 SILC_LOG_DEBUG(("New server id(%s)",
903 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
905 /* Add the connected router to global server list */
906 id_entry = silc_idlist_add_server(server->global_list,
907 strdup(sock->hostname),
908 SILC_ROUTER, ctx->dest_id, NULL, sock);
910 silc_free(ctx->dest_id);
911 silc_server_disconnect_remote(server, sock, "Server closed connection: "
912 "Authentication failed");
916 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
917 silc_free(sock->user_data);
918 sock->user_data = (void *)id_entry;
919 sock->type = SILC_SOCKET_TYPE_ROUTER;
920 idata = (SilcIDListData)sock->user_data;
921 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
923 param = (sconn->param ? sconn->param : &server->config->param);
925 /* Perform keepalive. The `hb_context' will be freed automatically
926 when finally calling the silc_socket_free function. XXX hardcoded
928 hb_context = silc_calloc(1, sizeof(*hb_context));
929 hb_context->server = server;
930 silc_socket_set_heartbeat(sock, param->keepalive_secs, hb_context,
931 silc_server_perform_heartbeat,
934 /* Register re-key timeout */
935 idata->rekey->timeout = 3600; /* XXX hardcoded */
936 idata->rekey->context = (void *)server;
937 silc_schedule_task_add(server->schedule, sock->sock,
938 silc_server_rekey_callback,
939 (void *)sock, idata->rekey->timeout, 0,
940 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
942 if (!sconn->backup) {
943 /* Mark this router our primary router if we're still standalone */
944 if (server->standalone) {
945 server->id_entry->router = id_entry;
946 server->router = id_entry;
947 server->standalone = FALSE;
949 /* If we are router then announce our possible servers. */
950 if (server->server_type == SILC_ROUTER)
951 silc_server_announce_servers(server, FALSE, 0,
952 server->router->connection);
954 /* Announce our clients and channels to the router */
955 silc_server_announce_clients(server, 0, server->router->connection);
956 silc_server_announce_channels(server, 0, server->router->connection);
959 /* Add this server to be our backup router */
960 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
961 sconn->backup_replace_port, FALSE);
964 sock->protocol = NULL;
966 /* Call the completion callback to indicate that we've connected to
969 (*sconn->callback)(server, id_entry, sconn->callback_context);
972 /* Free the temporary connection data context */
974 silc_free(sconn->remote_host);
975 silc_free(sconn->backup_replace_ip);
978 if (sconn == server->router_conn)
979 server->router_conn = NULL;
981 /* Free the protocol object */
982 if (sock->protocol == protocol)
983 sock->protocol = NULL;
984 silc_protocol_free(protocol);
986 silc_packet_context_free(ctx->packet);
988 silc_ske_free(ctx->ske);
989 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
990 silc_free(ctx->auth_data);
994 /* Host lookup callbcak that is called after the incoming connection's
995 IP and FQDN lookup is performed. This will actually check the acceptance
996 of the incoming connection and will register the key exchange protocol
997 for this connection. */
1000 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1003 SilcServer server = (SilcServer)context;
1004 SilcServerKEInternalContext *proto_ctx;
1005 void *cconfig, *sconfig, *rconfig;
1006 SilcServerConfigSectionDeny *deny;
1009 SILC_LOG_DEBUG(("Start"));
1011 /* Check whether we could resolve both IP and FQDN. */
1012 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1013 server->config->require_reverse_lookup)) {
1014 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1015 sock->hostname ? sock->hostname :
1016 sock->ip ? sock->ip : ""));
1017 server->stat.conn_failures++;
1018 silc_server_disconnect_remote(server, sock,
1019 "Server closed connection: Unknown host");
1023 /* Register the connection for network input and output. This sets
1024 that scheduler will listen for incoming packets for this connection
1025 and sets that outgoing packets may be sent to this connection as well.
1026 However, this doesn't set the scheduler for outgoing traffic, it
1027 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1028 later when outgoing data is available. */
1029 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1031 SILC_LOG_INFO(("Incoming connection from %s (%s)", sock->hostname,
1034 port = server->sockets[server->sock]->port; /* Listenning port */
1036 /* Check whether this connection is denied to connect to us. */
1037 deny = silc_server_config_find_denied(server, sock->ip, port);
1039 deny = silc_server_config_find_denied(server, sock->hostname, port);
1041 /* The connection is denied */
1042 SILC_LOG_INFO(("Connection %s (%s) is denied",
1043 sock->hostname, sock->ip));
1044 silc_server_disconnect_remote(server, sock, deny->reason ?
1046 "Server closed connection: "
1047 "Connection refused");
1048 server->stat.conn_failures++;
1052 /* Check whether we have configred this sort of connection at all. We
1053 have to check all configurations since we don't know what type of
1054 connection this is. */
1055 if (!(cconfig = silc_server_config_find_client(server, sock->ip, port)))
1056 cconfig = silc_server_config_find_client(server, sock->hostname, port);
1057 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1058 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1059 if (!(rconfig = silc_server_config_find_router_conn(server, sock->ip, port)))
1060 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1062 if (!cconfig && !sconfig && !rconfig) {
1063 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1065 silc_server_disconnect_remote(server, sock,
1066 "Server closed connection: "
1067 "Connection refused");
1068 server->stat.conn_failures++;
1072 /* The connection is allowed */
1074 /* Allocate internal context for key exchange protocol. This is
1075 sent as context for the protocol. */
1076 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1077 proto_ctx->server = context;
1078 proto_ctx->sock = sock;
1079 proto_ctx->rng = server->rng;
1080 proto_ctx->responder = TRUE;
1081 proto_ctx->cconfig = cconfig;
1082 proto_ctx->sconfig = sconfig;
1083 proto_ctx->rconfig = rconfig;
1085 /* Prepare the connection for key exchange protocol. We allocate the
1086 protocol but will not start it yet. The connector will be the
1087 initiator of the protocol thus we will wait for initiation from
1088 there before we start the protocol. */
1089 server->stat.auth_attempts++;
1090 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1091 &sock->protocol, proto_ctx,
1092 silc_server_accept_new_connection_second);
1094 /* Register a timeout task that will be executed if the connector
1095 will not start the key exchange protocol within 60 seconds. For
1096 now, this is a hard coded limit. After the timeout the connection will
1097 be closed if the key exchange protocol has not been started. */
1098 proto_ctx->timeout_task =
1099 silc_schedule_task_add(server->schedule, sock->sock,
1100 silc_server_timeout_remote,
1101 context, 60, 0, /* XXX hardcoded */
1106 /* Accepts new connections to the server. Accepting new connections are
1107 done in three parts to make it async. */
1109 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1111 SilcServer server = (SilcServer)context;
1112 SilcSocketConnection newsocket;
1115 SILC_LOG_DEBUG(("Accepting new connection"));
1117 server->stat.conn_attempts++;
1119 sock = silc_net_accept_connection(server->sock);
1121 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1122 server->stat.conn_failures++;
1126 /* Check max connections */
1127 if (sock > SILC_SERVER_MAX_CONNECTIONS) {
1128 SILC_LOG_ERROR(("Refusing connection, server is full"));
1129 server->stat.conn_failures++;
1133 /* Set socket options */
1134 silc_net_set_socket_nonblock(sock);
1135 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1137 /* We don't create a ID yet, since we don't know what type of connection
1138 this is yet. But, we do add the connection to the socket table. */
1139 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1140 server->sockets[sock] = newsocket;
1142 /* Perform asynchronous host lookup. This will lookup the IP and the
1143 FQDN of the remote connection. After the lookup is done the connection
1144 is accepted further. */
1145 silc_socket_host_lookup(newsocket, TRUE,
1146 silc_server_accept_new_connection_lookup, context,
1150 /* Second part of accepting new connection. Key exchange protocol has been
1151 performed and now it is time to do little connection authentication
1152 protocol to figure out whether this connection is client or server
1153 and whether it has right to access this server (especially server
1154 connections needs to be authenticated). */
1156 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1158 SilcProtocol protocol = (SilcProtocol)context;
1159 SilcServerKEInternalContext *ctx =
1160 (SilcServerKEInternalContext *)protocol->context;
1161 SilcServer server = (SilcServer)ctx->server;
1162 SilcSocketConnection sock = ctx->sock;
1163 SilcServerConnAuthInternalContext *proto_ctx;
1165 SILC_LOG_DEBUG(("Start"));
1167 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1168 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1169 /* Error occured during protocol */
1170 silc_protocol_free(protocol);
1171 sock->protocol = NULL;
1172 silc_ske_free_key_material(ctx->keymat);
1174 silc_packet_context_free(ctx->packet);
1176 silc_ske_free(ctx->ske);
1177 silc_free(ctx->dest_id);
1179 silc_schedule_task_del_by_callback(server->schedule,
1180 silc_server_failure_callback);
1181 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1182 "Key exchange failed");
1183 server->stat.auth_failures++;
1187 /* We now have the key material as the result of the key exchange
1188 protocol. Take the key material into use. Free the raw key material
1189 as soon as we've set them into use. */
1190 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1191 ctx->sock, ctx->keymat,
1192 ctx->ske->prop->cipher,
1193 ctx->ske->prop->pkcs,
1194 ctx->ske->prop->hash,
1195 ctx->ske->prop->hmac,
1196 ctx->ske->prop->group,
1198 silc_protocol_free(protocol);
1199 sock->protocol = NULL;
1200 silc_ske_free_key_material(ctx->keymat);
1202 silc_packet_context_free(ctx->packet);
1204 silc_ske_free(ctx->ske);
1205 silc_free(ctx->dest_id);
1207 silc_schedule_task_del_by_callback(server->schedule,
1208 silc_server_failure_callback);
1209 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1210 "Key exchange failed");
1211 server->stat.auth_failures++;
1214 silc_ske_free_key_material(ctx->keymat);
1216 /* Allocate internal context for the authentication protocol. This
1217 is sent as context for the protocol. */
1218 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1219 proto_ctx->server = (void *)server;
1220 proto_ctx->sock = sock;
1221 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1222 proto_ctx->responder = TRUE;
1223 proto_ctx->dest_id_type = ctx->dest_id_type;
1224 proto_ctx->dest_id = ctx->dest_id;
1225 proto_ctx->cconfig = ctx->cconfig;
1226 proto_ctx->sconfig = ctx->sconfig;
1227 proto_ctx->rconfig = ctx->rconfig;
1229 /* Free old protocol as it is finished now */
1230 silc_protocol_free(protocol);
1232 silc_packet_context_free(ctx->packet);
1234 sock->protocol = NULL;
1236 /* Allocate the authentication protocol. This is allocated here
1237 but we won't start it yet. We will be receiving party of this
1238 protocol thus we will wait that connecting party will make
1239 their first move. */
1240 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1241 &sock->protocol, proto_ctx,
1242 silc_server_accept_new_connection_final);
1244 /* Register timeout task. If the protocol is not executed inside
1245 this timelimit the connection will be terminated. */
1246 proto_ctx->timeout_task =
1247 silc_schedule_task_add(server->schedule, sock->sock,
1248 silc_server_timeout_remote,
1249 (void *)server, 60, 0, /* XXX hardcoded */
1254 /* Final part of accepting new connection. The connection has now
1255 been authenticated and keys has been exchanged. We also know whether
1256 this is client or server connection. */
1258 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1260 SilcProtocol protocol = (SilcProtocol)context;
1261 SilcServerConnAuthInternalContext *ctx =
1262 (SilcServerConnAuthInternalContext *)protocol->context;
1263 SilcServer server = (SilcServer)ctx->server;
1264 SilcSocketConnection sock = ctx->sock;
1265 SilcServerHBContext hb_context;
1266 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1268 uint32 hearbeat_timeout = SILC_SERVER_KEEPALIVE;
1270 SILC_LOG_DEBUG(("Start"));
1272 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1273 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1274 /* Error occured during protocol */
1275 silc_protocol_free(protocol);
1276 sock->protocol = NULL;
1278 silc_packet_context_free(ctx->packet);
1280 silc_ske_free(ctx->ske);
1281 silc_free(ctx->dest_id);
1283 silc_schedule_task_del_by_callback(server->schedule,
1284 silc_server_failure_callback);
1285 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1286 "Authentication failed");
1287 server->stat.auth_failures++;
1291 entry->data.last_receive = time(NULL);
1293 switch (ctx->conn_type) {
1294 case SILC_SOCKET_TYPE_CLIENT:
1296 SilcClientEntry client;
1297 SilcServerConfigSectionClient *conn = ctx->cconfig;
1299 SILC_LOG_DEBUG(("Remote host is client"));
1300 SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname,
1303 /* Add the client to the client ID cache. The nickname and Client ID
1304 and other information is created after we have received NEW_CLIENT
1305 packet from client. */
1306 client = silc_idlist_add_client(server->local_list,
1307 NULL, NULL, NULL, NULL, NULL, sock, 0);
1309 SILC_LOG_ERROR(("Could not add new client to cache"));
1310 silc_free(sock->user_data);
1311 silc_server_disconnect_remote(server, sock,
1312 "Server closed connection: "
1313 "Authentication failed");
1314 server->stat.auth_failures++;
1319 server->stat.my_clients++;
1320 server->stat.clients++;
1321 if (server->server_type == SILC_ROUTER)
1322 server->stat.cell_clients++;
1324 /* Get connection parameters */
1326 if (conn->param->keepalive_secs)
1327 hearbeat_timeout = conn->param->keepalive_secs;
1330 id_entry = (void *)client;
1333 case SILC_SOCKET_TYPE_SERVER:
1334 case SILC_SOCKET_TYPE_ROUTER:
1336 SilcServerEntry new_server;
1337 bool initiator = FALSE;
1338 bool backup_local = FALSE;
1339 bool backup_router = FALSE;
1340 char *backup_replace_ip = NULL;
1341 uint16 backup_replace_port = 0;
1342 SilcServerConfigSectionServer *sconn = ctx->sconfig;
1343 SilcServerConfigSectionRouter *rconn = ctx->rconfig;
1345 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && rconn) {
1346 initiator = rconn->initiator;
1347 backup_local = rconn->backup_local;
1348 backup_router = rconn->backup_router;
1349 backup_replace_ip = rconn->backup_replace_ip;
1350 backup_replace_port = rconn->backup_replace_port;
1353 if (rconn->param->keepalive_secs)
1354 hearbeat_timeout = rconn->param->keepalive_secs;
1358 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER && sconn) {
1359 backup_router = sconn->backup_router;
1362 if (sconn->param->keepalive_secs)
1363 hearbeat_timeout = sconn->param->keepalive_secs;
1367 SILC_LOG_DEBUG(("Remote host is %s",
1368 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1369 "server" : (backup_router ?
1370 "backup router" : "router")));
1371 SILC_LOG_INFO(("Connection from %s (%s) is %s", sock->hostname,
1372 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1373 "server" : (backup_router ?
1374 "backup router" : "router")));
1376 /* Add the server into server cache. The server name and Server ID
1377 is updated after we have received NEW_SERVER packet from the
1378 server. We mark ourselves as router for this server if we really
1381 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1382 server->local_list : (backup_router ?
1383 server->local_list :
1384 server->global_list)),
1386 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1387 SILC_SERVER : SILC_ROUTER),
1389 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1390 server->id_entry : (backup_router ?
1391 server->id_entry : NULL)),
1394 SILC_LOG_ERROR(("Could not add new server to cache"));
1395 silc_free(sock->user_data);
1396 silc_server_disconnect_remote(server, sock,
1397 "Server closed connection: "
1398 "Authentication failed");
1399 server->stat.auth_failures++;
1404 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER)
1405 server->stat.my_servers++;
1407 server->stat.my_routers++;
1408 server->stat.servers++;
1410 id_entry = (void *)new_server;
1412 /* If the incoming connection is router and marked as backup router
1413 then add it to be one of our backups */
1414 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
1415 silc_server_backup_add(server, new_server, backup_replace_ip,
1416 backup_replace_port, backup_local);
1418 /* Change it back to SERVER type since that's what it really is. */
1420 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1422 new_server->server_type = SILC_BACKUP_ROUTER;
1425 /* Check whether this connection is to be our primary router connection
1426 if we do not already have the primary route. */
1427 if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1428 if (silc_server_config_is_primary_route(server) && !initiator)
1431 SILC_LOG_DEBUG(("We are not standalone server anymore"));
1432 server->standalone = FALSE;
1433 if (!server->id_entry->router) {
1434 server->id_entry->router = id_entry;
1435 server->router = id_entry;
1446 sock->type = ctx->conn_type;
1448 /* Add the common data structure to the ID entry. */
1449 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1451 /* Add to sockets internal pointer for fast referencing */
1452 silc_free(sock->user_data);
1453 sock->user_data = id_entry;
1455 /* Connection has been fully established now. Everything is ok. */
1456 SILC_LOG_DEBUG(("New connection authenticated"));
1458 /* Perform keepalive. The `hb_context' will be freed automatically
1459 when finally calling the silc_socket_free function. */
1460 hb_context = silc_calloc(1, sizeof(*hb_context));
1461 hb_context->server = server;
1462 silc_socket_set_heartbeat(sock, hearbeat_timeout, hb_context,
1463 silc_server_perform_heartbeat,
1467 silc_schedule_task_del_by_callback(server->schedule,
1468 silc_server_failure_callback);
1469 silc_protocol_free(protocol);
1471 silc_packet_context_free(ctx->packet);
1473 silc_ske_free(ctx->ske);
1474 silc_free(ctx->dest_id);
1476 sock->protocol = NULL;
1479 /* This function is used to read packets from network and send packets to
1480 network. This is usually a generic task. */
1482 SILC_TASK_CALLBACK(silc_server_packet_process)
1484 SilcServer server = (SilcServer)context;
1485 SilcSocketConnection sock = server->sockets[fd];
1486 SilcIDListData idata;
1487 SilcCipher cipher = NULL;
1488 SilcHmac hmac = NULL;
1489 uint32 sequence = 0;
1495 SILC_LOG_DEBUG(("Processing packet"));
1497 /* Packet sending */
1499 if (type == SILC_TASK_WRITE) {
1500 /* Do not send data to disconnected connection */
1501 if (SILC_IS_DISCONNECTED(sock))
1504 server->stat.packets_sent++;
1506 if (sock->outbuf->data - sock->outbuf->head)
1507 silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
1509 /* Send the packet */
1510 ret = silc_packet_send(sock, TRUE);
1512 /* If returned -2 could not write to connection now, will do
1518 SILC_LOG_ERROR(("Error sending packet to connection "
1519 "%s:%d [%s]", sock->hostname, sock->port,
1520 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1521 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1522 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1527 /* The packet has been sent and now it is time to set the connection
1528 back to only for input. When there is again some outgoing data
1529 available for this connection it will be set for output as well.
1530 This call clears the output setting and sets it only for input. */
1531 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1532 SILC_UNSET_OUTBUF_PENDING(sock);
1534 silc_buffer_clear(sock->outbuf);
1538 /* Packet receiving */
1540 /* Read some data from connection */
1541 ret = silc_packet_receive(sock);
1545 SILC_LOG_ERROR(("Error receiving packet from connection "
1546 "%s:%d [%s] %s", sock->hostname, sock->port,
1547 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1548 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1549 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1550 "Router"), strerror(errno)));
1556 SILC_LOG_DEBUG(("Read EOF"));
1558 /* If connection is disconnecting already we will finally
1559 close the connection */
1560 if (SILC_IS_DISCONNECTING(sock)) {
1561 if (sock->user_data)
1562 silc_server_free_sock_user_data(server, sock, NULL);
1563 silc_server_close_connection(server, sock);
1567 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1568 SILC_SET_DISCONNECTING(sock);
1570 if (sock->user_data) {
1572 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
1573 silc_server_free_sock_user_data(server, sock, tmp);
1575 silc_server_free_sock_user_data(server, sock, NULL);
1576 } else if (server->router_conn && server->router_conn->sock == sock &&
1577 !server->router && server->standalone)
1578 silc_schedule_task_add(server->schedule, 0,
1579 silc_server_connect_to_router,
1582 SILC_TASK_PRI_NORMAL);
1584 silc_server_close_connection(server, sock);
1588 /* If connection is disconnecting or disconnected we will ignore
1590 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1591 SILC_LOG_DEBUG(("Ignoring read data from disonnected connection"));
1595 server->stat.packets_received++;
1597 /* Get keys and stuff from ID entry */
1598 idata = (SilcIDListData)sock->user_data;
1600 cipher = idata->receive_key;
1601 hmac = idata->hmac_receive;
1602 sequence = idata->psn_receive;
1605 /* Process the packet. This will call the parser that will then
1606 decrypt and parse the packet. */
1607 ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1608 TRUE : FALSE, cipher, hmac, sequence,
1609 silc_server_packet_parse, server);
1611 /* If this socket connection is not authenticated yet and the packet
1612 processing failed we will drop the connection since it can be
1613 a malicious flooder. */
1614 if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
1615 (!sock->protocol || sock->protocol->protocol->type ==
1616 SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
1617 SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
1618 SILC_SET_DISCONNECTING(sock);
1620 if (sock->user_data)
1621 silc_server_free_sock_user_data(server, sock, NULL);
1622 silc_server_close_connection(server, sock);
1626 /* Parses whole packet, received earlier. */
1628 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1630 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1631 SilcServer server = (SilcServer)parse_ctx->context;
1632 SilcSocketConnection sock = parse_ctx->sock;
1633 SilcPacketContext *packet = parse_ctx->packet;
1634 SilcIDListData idata = (SilcIDListData)sock->user_data;
1637 SILC_LOG_DEBUG(("Start"));
1639 /* Parse the packet */
1640 if (parse_ctx->normal)
1641 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1643 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1645 /* If entry is disabled ignore what we got. */
1646 if (ret != SILC_PACKET_RESUME_ROUTER &&
1647 idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1648 SILC_LOG_DEBUG(("Connection is disabled"));
1652 if (ret == SILC_PACKET_NONE)
1655 /* Check that the the current client ID is same as in the client's packet. */
1656 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1657 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1658 if (client && client->id) {
1659 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1660 packet->src_id_type);
1661 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1669 if (server->server_type == SILC_ROUTER) {
1670 /* Route the packet if it is not destined to us. Other ID types but
1671 server are handled separately after processing them. */
1672 if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1673 packet->dst_id_type == SILC_ID_SERVER &&
1674 sock->type != SILC_SOCKET_TYPE_CLIENT &&
1675 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1677 /* Route the packet to fastest route for the destination ID */
1678 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1679 packet->dst_id_type);
1682 silc_server_packet_route(server,
1683 silc_server_route_get(server, id,
1684 packet->dst_id_type),
1691 /* Parse the incoming packet type */
1692 silc_server_packet_parse_type(server, sock, packet);
1694 if (server->server_type == SILC_ROUTER) {
1695 /* Broadcast packet if it is marked as broadcast packet and it is
1696 originated from router and we are router. */
1697 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1698 packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1699 !server->standalone) {
1700 /* Broadcast to our primary route */
1701 silc_server_packet_broadcast(server, server->router->connection, packet);
1703 /* If we have backup routers then we need to feed all broadcast
1704 data to those servers. */
1705 silc_server_backup_broadcast(server, sock, packet);
1710 silc_packet_context_free(packet);
1711 silc_free(parse_ctx);
1714 /* Parser callback called by silc_packet_receive_process. This merely
1715 registers timeout that will handle the actual parsing when appropriate. */
1717 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1720 SilcServer server = (SilcServer)context;
1721 SilcSocketConnection sock = parser_context->sock;
1722 SilcIDListData idata = (SilcIDListData)sock->user_data;
1725 idata->psn_receive = parser_context->packet->sequence + 1;
1727 /* If protocol for this connection is key exchange or rekey then we'll
1728 process all packets synchronously, since there might be packets in
1729 queue that we are not able to decrypt without first processing the
1730 packets before them. */
1731 if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1732 parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1733 (sock->protocol && sock->protocol->protocol &&
1734 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1735 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1736 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1739 /* Reprocess data since we'll return FALSE here. This is because
1740 the idata->receive_key might have become valid in the last packet
1741 and we want to call this processor with valid cipher. */
1743 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1744 TRUE : FALSE, idata->receive_key,
1745 idata->hmac_receive, idata->psn_receive,
1746 silc_server_packet_parse, server);
1748 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1749 TRUE : FALSE, NULL, NULL, 0,
1750 silc_server_packet_parse, server);
1754 switch (sock->type) {
1755 case SILC_SOCKET_TYPE_UNKNOWN:
1756 case SILC_SOCKET_TYPE_CLIENT:
1757 /* Parse the packet with timeout */
1758 silc_schedule_task_add(server->schedule, sock->sock,
1759 silc_server_packet_parse_real,
1760 (void *)parser_context, 0, 100000,
1762 SILC_TASK_PRI_NORMAL);
1764 case SILC_SOCKET_TYPE_SERVER:
1765 case SILC_SOCKET_TYPE_ROUTER:
1766 /* Packets from servers are parsed immediately */
1767 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1777 /* Parses the packet type and calls what ever routines the packet type
1778 requires. This is done for all incoming packets. */
1780 void silc_server_packet_parse_type(SilcServer server,
1781 SilcSocketConnection sock,
1782 SilcPacketContext *packet)
1784 SilcPacketType type = packet->type;
1785 SilcIDListData idata = (SilcIDListData)sock->user_data;
1787 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1789 /* Parse the packet type */
1791 case SILC_PACKET_DISCONNECT:
1792 SILC_LOG_DEBUG(("Disconnect packet"));
1793 if (packet->flags & SILC_PACKET_FLAG_LIST)
1797 case SILC_PACKET_SUCCESS:
1799 * Success received for something. For now we can have only
1800 * one protocol for connection executing at once hence this
1801 * success message is for whatever protocol is executing currently.
1803 SILC_LOG_DEBUG(("Success packet"));
1804 if (packet->flags & SILC_PACKET_FLAG_LIST)
1807 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1810 case SILC_PACKET_FAILURE:
1812 * Failure received for something. For now we can have only
1813 * one protocol for connection executing at once hence this
1814 * failure message is for whatever protocol is executing currently.
1816 SILC_LOG_DEBUG(("Failure packet"));
1817 if (packet->flags & SILC_PACKET_FLAG_LIST)
1819 if (sock->protocol) {
1820 SilcServerFailureContext f;
1821 f = silc_calloc(1, sizeof(*f));
1825 /* We will wait 5 seconds to process this failure packet */
1826 silc_schedule_task_add(server->schedule, sock->sock,
1827 silc_server_failure_callback, (void *)f, 5, 0,
1828 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1832 case SILC_PACKET_REJECT:
1833 SILC_LOG_DEBUG(("Reject packet"));
1834 if (packet->flags & SILC_PACKET_FLAG_LIST)
1839 case SILC_PACKET_NOTIFY:
1841 * Received notify packet. Server can receive notify packets from
1842 * router. Server then relays the notify messages to clients if needed.
1844 SILC_LOG_DEBUG(("Notify packet"));
1845 if (packet->flags & SILC_PACKET_FLAG_LIST)
1846 silc_server_notify_list(server, sock, packet);
1848 silc_server_notify(server, sock, packet);
1854 case SILC_PACKET_CHANNEL_MESSAGE:
1856 * Received channel message. Channel messages are special packets
1857 * (although probably most common ones) thus they are handled
1860 SILC_LOG_DEBUG(("Channel Message packet"));
1861 if (packet->flags & SILC_PACKET_FLAG_LIST)
1863 idata->last_receive = time(NULL);
1864 silc_server_channel_message(server, sock, packet);
1867 case SILC_PACKET_CHANNEL_KEY:
1869 * Received key for channel. As channels are created by the router
1870 * the keys are as well. We will distribute the key to all of our
1871 * locally connected clients on the particular channel. Router
1872 * never receives this channel and thus is ignored.
1874 SILC_LOG_DEBUG(("Channel Key packet"));
1875 if (packet->flags & SILC_PACKET_FLAG_LIST)
1877 silc_server_channel_key(server, sock, packet);
1883 case SILC_PACKET_COMMAND:
1885 * Recived command. Processes the command request and allocates the
1886 * command context and calls the command.
1888 SILC_LOG_DEBUG(("Command packet"));
1889 if (packet->flags & SILC_PACKET_FLAG_LIST)
1891 silc_server_command_process(server, sock, packet);
1894 case SILC_PACKET_COMMAND_REPLY:
1896 * Received command reply packet. Received command reply to command. It
1897 * may be reply to command sent by us or reply to command sent by client
1898 * that we've routed further.
1900 SILC_LOG_DEBUG(("Command Reply packet"));
1901 if (packet->flags & SILC_PACKET_FLAG_LIST)
1903 silc_server_command_reply(server, sock, packet);
1907 * Private Message packets
1909 case SILC_PACKET_PRIVATE_MESSAGE:
1911 * Received private message packet. The packet is coming from either
1914 SILC_LOG_DEBUG(("Private Message packet"));
1915 if (packet->flags & SILC_PACKET_FLAG_LIST)
1917 idata->last_receive = time(NULL);
1918 silc_server_private_message(server, sock, packet);
1921 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1923 * Private message key packet.
1925 if (packet->flags & SILC_PACKET_FLAG_LIST)
1927 silc_server_private_message_key(server, sock, packet);
1931 * Key Exchange protocol packets
1933 case SILC_PACKET_KEY_EXCHANGE:
1934 SILC_LOG_DEBUG(("KE packet"));
1935 if (packet->flags & SILC_PACKET_FLAG_LIST)
1938 if (sock->protocol && sock->protocol->protocol &&
1939 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
1941 SilcServerKEInternalContext *proto_ctx =
1942 (SilcServerKEInternalContext *)sock->protocol->context;
1944 proto_ctx->packet = silc_packet_context_dup(packet);
1946 /* Let the protocol handle the packet */
1947 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
1949 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1950 "protocol active, packet dropped."));
1954 case SILC_PACKET_KEY_EXCHANGE_1:
1955 SILC_LOG_DEBUG(("KE 1 packet"));
1956 if (packet->flags & SILC_PACKET_FLAG_LIST)
1959 if (sock->protocol && sock->protocol->protocol &&
1960 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1961 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
1963 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
1964 SilcServerRekeyInternalContext *proto_ctx =
1965 (SilcServerRekeyInternalContext *)sock->protocol->context;
1967 if (proto_ctx->packet)
1968 silc_packet_context_free(proto_ctx->packet);
1970 proto_ctx->packet = silc_packet_context_dup(packet);
1972 /* Let the protocol handle the packet */
1973 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1975 SilcServerKEInternalContext *proto_ctx =
1976 (SilcServerKEInternalContext *)sock->protocol->context;
1978 if (proto_ctx->packet)
1979 silc_packet_context_free(proto_ctx->packet);
1981 proto_ctx->packet = silc_packet_context_dup(packet);
1982 proto_ctx->dest_id_type = packet->src_id_type;
1983 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1984 packet->src_id_type);
1985 if (!proto_ctx->dest_id)
1988 /* Let the protocol handle the packet */
1989 silc_protocol_execute(sock->protocol, server->schedule,
1993 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1994 "protocol active, packet dropped."));
1998 case SILC_PACKET_KEY_EXCHANGE_2:
1999 SILC_LOG_DEBUG(("KE 2 packet"));
2000 if (packet->flags & SILC_PACKET_FLAG_LIST)
2003 if (sock->protocol && sock->protocol->protocol &&
2004 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2005 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2007 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2008 SilcServerRekeyInternalContext *proto_ctx =
2009 (SilcServerRekeyInternalContext *)sock->protocol->context;
2011 if (proto_ctx->packet)
2012 silc_packet_context_free(proto_ctx->packet);
2014 proto_ctx->packet = silc_packet_context_dup(packet);
2016 /* Let the protocol handle the packet */
2017 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2019 SilcServerKEInternalContext *proto_ctx =
2020 (SilcServerKEInternalContext *)sock->protocol->context;
2022 if (proto_ctx->packet)
2023 silc_packet_context_free(proto_ctx->packet);
2025 proto_ctx->packet = silc_packet_context_dup(packet);
2026 proto_ctx->dest_id_type = packet->src_id_type;
2027 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2028 packet->src_id_type);
2029 if (!proto_ctx->dest_id)
2032 /* Let the protocol handle the packet */
2033 silc_protocol_execute(sock->protocol, server->schedule,
2037 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2038 "protocol active, packet dropped."));
2042 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2044 * Connection authentication request packet. When we receive this packet
2045 * we will send to the other end information about our mandatory
2046 * authentication method for the connection. This packet maybe received
2049 SILC_LOG_DEBUG(("Connection authentication request packet"));
2050 if (packet->flags & SILC_PACKET_FLAG_LIST)
2052 silc_server_connection_auth_request(server, sock, packet);
2056 * Connection Authentication protocol packets
2058 case SILC_PACKET_CONNECTION_AUTH:
2059 /* Start of the authentication protocol. We receive here the
2060 authentication data and will verify it. */
2061 SILC_LOG_DEBUG(("Connection auth packet"));
2062 if (packet->flags & SILC_PACKET_FLAG_LIST)
2065 if (sock->protocol && sock->protocol->protocol->type
2066 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2068 SilcServerConnAuthInternalContext *proto_ctx =
2069 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2071 proto_ctx->packet = silc_packet_context_dup(packet);
2073 /* Let the protocol handle the packet */
2074 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2076 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2077 "protocol active, packet dropped."));
2081 case SILC_PACKET_NEW_ID:
2083 * Received New ID packet. This includes some new ID that has been
2084 * created. It may be for client, server or channel. This is the way
2085 * to distribute information about new registered entities in the
2088 SILC_LOG_DEBUG(("New ID packet"));
2089 if (packet->flags & SILC_PACKET_FLAG_LIST)
2090 silc_server_new_id_list(server, sock, packet);
2092 silc_server_new_id(server, sock, packet);
2095 case SILC_PACKET_NEW_CLIENT:
2097 * Received new client packet. This includes client information that
2098 * we will use to create initial client ID. After creating new
2099 * ID we will send it to the client.
2101 SILC_LOG_DEBUG(("New Client packet"));
2102 if (packet->flags & SILC_PACKET_FLAG_LIST)
2104 silc_server_new_client(server, sock, packet);
2107 case SILC_PACKET_NEW_SERVER:
2109 * Received new server packet. This includes Server ID and some other
2110 * information that we may save. This is received after server has
2113 SILC_LOG_DEBUG(("New Server packet"));
2114 if (packet->flags & SILC_PACKET_FLAG_LIST)
2116 silc_server_new_server(server, sock, packet);
2119 case SILC_PACKET_NEW_CHANNEL:
2121 * Received new channel packet. Information about new channel in the
2122 * network are distributed using this packet.
2124 SILC_LOG_DEBUG(("New Channel packet"));
2125 if (packet->flags & SILC_PACKET_FLAG_LIST)
2126 silc_server_new_channel_list(server, sock, packet);
2128 silc_server_new_channel(server, sock, packet);
2131 case SILC_PACKET_HEARTBEAT:
2133 * Received heartbeat.
2135 SILC_LOG_DEBUG(("Heartbeat packet"));
2136 if (packet->flags & SILC_PACKET_FLAG_LIST)
2140 case SILC_PACKET_KEY_AGREEMENT:
2142 * Received heartbeat.
2144 SILC_LOG_DEBUG(("Key agreement packet"));
2145 if (packet->flags & SILC_PACKET_FLAG_LIST)
2147 silc_server_key_agreement(server, sock, packet);
2150 case SILC_PACKET_REKEY:
2152 * Received re-key packet. The sender wants to regenerate the session
2155 SILC_LOG_DEBUG(("Re-key packet"));
2156 if (packet->flags & SILC_PACKET_FLAG_LIST)
2158 silc_server_rekey(server, sock, packet);
2161 case SILC_PACKET_REKEY_DONE:
2163 * The re-key is done.
2165 SILC_LOG_DEBUG(("Re-key done packet"));
2166 if (packet->flags & SILC_PACKET_FLAG_LIST)
2169 if (sock->protocol && sock->protocol->protocol &&
2170 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2172 SilcServerRekeyInternalContext *proto_ctx =
2173 (SilcServerRekeyInternalContext *)sock->protocol->context;
2175 if (proto_ctx->packet)
2176 silc_packet_context_free(proto_ctx->packet);
2178 proto_ctx->packet = silc_packet_context_dup(packet);
2180 /* Let the protocol handle the packet */
2181 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2183 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2184 "protocol active, packet dropped."));
2188 case SILC_PACKET_FTP:
2190 SILC_LOG_DEBUG(("FTP packet"));
2191 if (packet->flags & SILC_PACKET_FLAG_LIST)
2193 silc_server_ftp(server, sock, packet);
2196 case SILC_PACKET_RESUME_ROUTER:
2197 /* Resume router packet received. This packet is received for backup
2198 router resuming protocol. */
2199 SILC_LOG_DEBUG(("Resume router packet"));
2200 if (packet->flags & SILC_PACKET_FLAG_LIST)
2202 silc_server_backup_resume_router(server, sock, packet);
2206 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2212 /* Creates connection to a remote router. */
2214 void silc_server_create_connection(SilcServer server,
2215 const char *remote_host, uint32 port)
2217 SilcServerConnection sconn;
2219 /* Allocate connection object for hold connection specific stuff. */
2220 sconn = silc_calloc(1, sizeof(*sconn));
2221 sconn->server = server;
2222 sconn->remote_host = strdup(remote_host);
2223 sconn->remote_port = port;
2224 sconn->no_reconnect = TRUE;
2225 sconn->param = &server->config->param;
2227 silc_schedule_task_add(server->schedule, 0,
2228 silc_server_connect_router,
2229 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
2230 SILC_TASK_PRI_NORMAL);
2233 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2235 silc_socket_free((SilcSocketConnection)context);
2238 /* Closes connection to socket connection */
2240 void silc_server_close_connection(SilcServer server,
2241 SilcSocketConnection sock)
2243 if (!server->sockets[sock->sock])
2246 SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2248 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2249 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2250 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2253 /* We won't listen for this connection anymore */
2254 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2256 /* Unregister all tasks */
2257 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2259 /* Close the actual connection */
2260 silc_net_close_connection(sock->sock);
2261 server->sockets[sock->sock] = NULL;
2263 /* If sock->user_data is NULL then we'll check for active protocols
2264 here since the silc_server_free_sock_user_data has not been called
2265 for this connection. */
2266 if (!sock->user_data) {
2267 /* If any protocol is active cancel its execution. It will call
2268 the final callback which will finalize the disconnection. */
2269 if (sock->protocol) {
2270 silc_protocol_cancel(sock->protocol, server->schedule);
2271 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2272 silc_protocol_execute_final(sock->protocol, server->schedule);
2273 sock->protocol = NULL;
2278 silc_schedule_task_add(server->schedule, 0,
2279 silc_server_close_connection_final,
2280 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
2281 SILC_TASK_PRI_NORMAL);
2284 /* Sends disconnect message to remote connection and disconnects the
2287 void silc_server_disconnect_remote(SilcServer server,
2288 SilcSocketConnection sock,
2289 const char *fmt, ...)
2292 unsigned char buf[4096];
2297 memset(buf, 0, sizeof(buf));
2299 vsprintf(buf, fmt, ap);
2302 SILC_LOG_DEBUG(("Disconnecting remote host"));
2304 /* Notify remote end that the conversation is over. The notify message
2305 is tried to be sent immediately. */
2306 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
2307 buf, strlen(buf), TRUE);
2309 /* Mark the connection to be disconnected */
2310 SILC_SET_DISCONNECTED(sock);
2311 silc_server_close_connection(server, sock);
2316 SilcClientEntry client;
2317 } *FreeClientInternal;
2319 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2321 FreeClientInternal i = (FreeClientInternal)context;
2323 silc_idlist_del_data(i->client);
2324 silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2328 /* Frees client data and notifies about client's signoff. */
2330 void silc_server_free_client_data(SilcServer server,
2331 SilcSocketConnection sock,
2332 SilcClientEntry client,
2334 const char *signoff)
2336 FreeClientInternal i = silc_calloc(1, sizeof(*i));
2338 /* If there is pending outgoing data for the client then purge it
2339 to the network before removing the client entry. */
2340 silc_server_packet_queue_purge(server, sock);
2345 /* Send SIGNOFF notify to routers. */
2346 if (notify && !server->standalone && server->router)
2347 silc_server_send_notify_signoff(server, server->router->connection,
2348 server->server_type == SILC_SERVER ?
2349 FALSE : TRUE, client->id, signoff);
2351 /* Remove client from all channels */
2353 silc_server_remove_from_channels(server, NULL, client,
2354 TRUE, (char *)signoff, TRUE);
2356 silc_server_remove_from_channels(server, NULL, client,
2357 FALSE, NULL, FALSE);
2359 /* Update statistics */
2360 server->stat.my_clients--;
2361 server->stat.clients--;
2362 if (server->server_type == SILC_ROUTER)
2363 server->stat.cell_clients--;
2364 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2365 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2367 /* We will not delete the client entry right away. We will take it
2368 into history (for WHOWAS command) for 5 minutes */
2371 silc_schedule_task_add(server->schedule, 0,
2372 silc_server_free_client_data_timeout,
2374 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2375 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2376 client->router = NULL;
2377 client->connection = NULL;
2381 /* Frees user_data pointer from socket connection object. This also sends
2382 appropriate notify packets to the network to inform about leaving
2385 void silc_server_free_sock_user_data(SilcServer server,
2386 SilcSocketConnection sock,
2387 const char *signoff_message)
2389 SILC_LOG_DEBUG(("Start"));
2391 switch (sock->type) {
2392 case SILC_SOCKET_TYPE_CLIENT:
2394 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2395 silc_server_free_client_data(server, sock, user_data, TRUE,
2399 case SILC_SOCKET_TYPE_SERVER:
2400 case SILC_SOCKET_TYPE_ROUTER:
2402 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2403 SilcServerEntry backup_router = NULL;
2406 backup_router = silc_server_backup_get(server, user_data->id);
2408 /* If this was our primary router connection then we're lost to
2409 the outside world. */
2410 if (server->router == user_data) {
2411 /* Check whether we have a backup router connection */
2412 if (!backup_router || backup_router == user_data) {
2413 silc_schedule_task_add(server->schedule, 0,
2414 silc_server_connect_to_router,
2417 SILC_TASK_PRI_NORMAL);
2419 server->id_entry->router = NULL;
2420 server->router = NULL;
2421 server->standalone = TRUE;
2422 backup_router = NULL;
2424 SILC_LOG_INFO(("New primary router is backup router %s",
2425 backup_router->server_name));
2426 SILC_LOG_DEBUG(("New primary router is backup router %s",
2427 backup_router->server_name));
2428 server->id_entry->router = backup_router;
2429 server->router = backup_router;
2430 server->router_connect = time(0);
2431 server->backup_primary = TRUE;
2432 if (server->server_type == SILC_BACKUP_ROUTER) {
2433 server->server_type = SILC_ROUTER;
2435 /* We'll need to constantly try to reconnect to the primary
2436 router so that we'll see when it comes back online. */
2437 silc_server_backup_reconnect(server, sock->ip, sock->port,
2438 silc_server_backup_connected,
2442 /* Mark this connection as replaced */
2443 silc_server_backup_replaced_add(server, user_data->id,
2446 } else if (backup_router) {
2447 SILC_LOG_INFO(("Enabling the use of backup router %s",
2448 backup_router->server_name));
2449 SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2450 backup_router->server_name));
2452 /* Mark this connection as replaced */
2453 silc_server_backup_replaced_add(server, user_data->id,
2457 if (!backup_router) {
2458 /* Free all client entries that this server owns as they will
2459 become invalid now as well. */
2461 silc_server_remove_clients_by_server(server, user_data, TRUE);
2462 if (server->server_type == SILC_SERVER)
2463 silc_server_remove_channels_by_server(server, user_data);
2465 /* Update the client entries of this server to the new backup
2466 router. This also removes the clients that *really* was owned
2467 by the primary router and went down with the router. */
2468 silc_server_update_clients_by_server(server, user_data, backup_router,
2470 silc_server_update_servers_by_server(server, user_data, backup_router);
2471 if (server->server_type == SILC_SERVER)
2472 silc_server_update_channels_by_server(server, user_data,
2476 /* Free the server entry */
2477 silc_server_backup_del(server, user_data);
2478 silc_server_backup_replaced_del(server, user_data);
2479 silc_idlist_del_data(user_data);
2480 if (!silc_idlist_del_server(server->local_list, user_data))
2481 silc_idlist_del_server(server->global_list, user_data);
2482 server->stat.my_servers--;
2483 server->stat.servers--;
2484 if (server->server_type == SILC_ROUTER)
2485 server->stat.cell_servers--;
2487 if (backup_router) {
2488 /* Announce all of our stuff that was created about 5 minutes ago.
2489 The backup router knows all the other stuff already. */
2490 if (server->server_type == SILC_ROUTER)
2491 silc_server_announce_servers(server, FALSE, time(0) - 300,
2492 backup_router->connection);
2494 /* Announce our clients and channels to the router */
2495 silc_server_announce_clients(server, time(0) - 300,
2496 backup_router->connection);
2497 silc_server_announce_channels(server, time(0) - 300,
2498 backup_router->connection);
2504 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2506 silc_idlist_del_data(user_data);
2507 silc_free(user_data);
2512 /* If any protocol is active cancel its execution */
2513 if (sock->protocol) {
2514 silc_protocol_cancel(sock->protocol, server->schedule);
2515 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2516 silc_protocol_execute_final(sock->protocol, server->schedule);
2517 sock->protocol = NULL;
2520 sock->user_data = NULL;
2523 /* Removes client from all channels it has joined. This is used when client
2524 connection is disconnected. If the client on a channel is last, the
2525 channel is removed as well. This sends the SIGNOFF notify types. */
2527 void silc_server_remove_from_channels(SilcServer server,
2528 SilcSocketConnection sock,
2529 SilcClientEntry client,
2531 char *signoff_message,
2534 SilcChannelEntry channel;
2535 SilcChannelClientEntry chl;
2536 SilcHashTableList htl;
2539 SILC_LOG_DEBUG(("Start"));
2541 if (!client || !client->id)
2544 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2546 /* Remove the client from all channels. The client is removed from
2547 the channels' user list. */
2548 silc_hash_table_list(client->channels, &htl);
2549 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2550 channel = chl->channel;
2552 /* Remove channel from client's channel list */
2553 silc_hash_table_del(client->channels, channel);
2555 /* Remove channel if there is no users anymore */
2556 if (server->server_type == SILC_ROUTER &&
2557 silc_hash_table_count(channel->user_list) < 2) {
2559 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2560 if (silc_idlist_del_channel(server->local_list, channel))
2561 server->stat.my_channels--;
2563 silc_idlist_del_channel(server->global_list, channel);
2567 /* Remove client from channel's client list */
2568 silc_hash_table_del(channel->user_list, chl->client);
2570 /* If there is no global users on the channel anymore mark the channel
2571 as local channel. Do not check if the removed client is local client. */
2572 if (server->server_type != SILC_ROUTER && channel->global_users &&
2573 chl->client->router && !silc_server_channel_has_global(channel))
2574 channel->global_users = FALSE;
2577 server->stat.my_chanclients--;
2579 /* If there is not at least one local user on the channel then we don't
2580 need the channel entry anymore, we can remove it safely. */
2581 if (server->server_type != SILC_ROUTER &&
2582 !silc_server_channel_has_local(channel)) {
2583 /* Notify about leaving client if this channel has global users. */
2584 if (notify && channel->global_users)
2585 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2586 SILC_NOTIFY_TYPE_SIGNOFF,
2587 signoff_message ? 2 : 1,
2588 clidp->data, clidp->len,
2589 signoff_message, signoff_message ?
2590 strlen(signoff_message) : 0);
2593 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2595 if (channel->founder_key) {
2596 /* The founder auth data exists, do not remove the channel entry */
2597 SilcChannelClientEntry chl2;
2598 SilcHashTableList htl2;
2600 channel->disabled = TRUE;
2602 silc_hash_table_list(channel->user_list, &htl2);
2603 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2604 silc_hash_table_del(chl2->client->channels, channel);
2605 silc_hash_table_del(channel->user_list, chl2->client);
2608 silc_hash_table_list_reset(&htl2);
2612 /* Remove the channel entry */
2613 if (silc_idlist_del_channel(server->local_list, channel))
2614 server->stat.my_channels--;
2616 silc_idlist_del_channel(server->global_list, channel);
2620 /* Send notify to channel about client leaving SILC and thus
2621 the entire channel. */
2623 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2624 SILC_NOTIFY_TYPE_SIGNOFF,
2625 signoff_message ? 2 : 1,
2626 clidp->data, clidp->len,
2627 signoff_message, signoff_message ?
2628 strlen(signoff_message) : 0);
2630 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2631 /* Re-generate channel key */
2632 if (!silc_server_create_channel_key(server, channel, 0))
2635 /* Send the channel key to the channel. The key of course is not sent
2636 to the client who was removed from the channel. */
2637 silc_server_send_channel_key(server, client->connection, channel,
2638 server->server_type == SILC_ROUTER ?
2639 FALSE : !server->standalone);
2644 silc_hash_table_list_reset(&htl);
2645 silc_buffer_free(clidp);
2648 /* Removes client from one channel. This is used for example when client
2649 calls LEAVE command to remove itself from the channel. Returns TRUE
2650 if channel still exists and FALSE if the channel is removed when
2651 last client leaves the channel. If `notify' is FALSE notify messages
2654 int silc_server_remove_from_one_channel(SilcServer server,
2655 SilcSocketConnection sock,
2656 SilcChannelEntry channel,
2657 SilcClientEntry client,
2660 SilcChannelClientEntry chl;
2663 SILC_LOG_DEBUG(("Start"));
2665 /* Get the entry to the channel, if this client is not on the channel
2667 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2670 /* Remove the client from the channel. The client is removed from
2671 the channel's user list. */
2673 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2675 /* Remove channel from client's channel list */
2676 silc_hash_table_del(client->channels, chl->channel);
2678 /* Remove channel if there is no users anymore */
2679 if (server->server_type == SILC_ROUTER &&
2680 silc_hash_table_count(channel->user_list) < 2) {
2682 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2683 if (silc_idlist_del_channel(server->local_list, channel))
2684 server->stat.my_channels--;
2686 silc_idlist_del_channel(server->global_list, channel);
2687 silc_buffer_free(clidp);
2691 /* Remove client from channel's client list */
2692 silc_hash_table_del(channel->user_list, chl->client);
2694 /* If there is no global users on the channel anymore mark the channel
2695 as local channel. Do not check if the client is local client. */
2696 if (server->server_type != SILC_ROUTER && channel->global_users &&
2697 chl->client->router && !silc_server_channel_has_global(channel))
2698 channel->global_users = FALSE;
2701 server->stat.my_chanclients--;
2703 /* If there is not at least one local user on the channel then we don't
2704 need the channel entry anymore, we can remove it safely. */
2705 if (server->server_type != SILC_ROUTER &&
2706 !silc_server_channel_has_local(channel)) {
2707 /* Notify about leaving client if this channel has global users. */
2708 if (notify && channel->global_users)
2709 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2710 SILC_NOTIFY_TYPE_LEAVE, 1,
2711 clidp->data, clidp->len);
2713 silc_buffer_free(clidp);
2716 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2718 if (channel->founder_key) {
2719 /* The founder auth data exists, do not remove the channel entry */
2720 SilcChannelClientEntry chl2;
2721 SilcHashTableList htl2;
2723 channel->disabled = TRUE;
2725 silc_hash_table_list(channel->user_list, &htl2);
2726 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2727 silc_hash_table_del(chl2->client->channels, channel);
2728 silc_hash_table_del(channel->user_list, chl2->client);
2731 silc_hash_table_list_reset(&htl2);
2735 /* Remove the channel entry */
2736 if (silc_idlist_del_channel(server->local_list, channel))
2737 server->stat.my_channels--;
2739 silc_idlist_del_channel(server->global_list, channel);
2743 /* Send notify to channel about client leaving the channel */
2745 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2746 SILC_NOTIFY_TYPE_LEAVE, 1,
2747 clidp->data, clidp->len);
2749 silc_buffer_free(clidp);
2753 /* Timeout callback. This is called if connection is idle or for some
2754 other reason is not responding within some period of time. This
2755 disconnects the remote end. */
2757 SILC_TASK_CALLBACK(silc_server_timeout_remote)
2759 SilcServer server = (SilcServer)context;
2760 SilcSocketConnection sock = server->sockets[fd];
2762 SILC_LOG_DEBUG(("Start"));
2767 /* If we have protocol active we must assure that we call the protocol's
2768 final callback so that all the memory is freed. */
2769 if (sock->protocol) {
2770 silc_protocol_cancel(sock->protocol, server->schedule);
2771 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2772 silc_protocol_execute_final(sock->protocol, server->schedule);
2773 sock->protocol = NULL;
2777 if (sock->user_data)
2778 silc_server_free_sock_user_data(server, sock, NULL);
2780 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2781 "Connection timeout");
2784 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
2785 function may be used only by router. In real SILC network all channels
2786 are created by routers thus this function is never used by normal
2789 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
2790 SilcServerID *router_id,
2796 SilcChannelID *channel_id;
2797 SilcChannelEntry entry;
2801 SILC_LOG_DEBUG(("Creating new channel"));
2804 cipher = SILC_DEFAULT_CIPHER;
2806 hmac = SILC_DEFAULT_HMAC;
2808 /* Allocate cipher */
2809 if (!silc_cipher_alloc(cipher, &key))
2813 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2814 silc_cipher_free(key);
2818 channel_name = strdup(channel_name);
2820 /* Create the channel ID */
2821 if (!silc_id_create_channel_id(server, router_id, server->rng,
2823 silc_free(channel_name);
2824 silc_cipher_free(key);
2825 silc_hmac_free(newhmac);
2829 /* Create the channel */
2830 entry = silc_idlist_add_channel(server->local_list, channel_name,
2831 SILC_CHANNEL_MODE_NONE, channel_id,
2832 NULL, key, newhmac, 0);
2834 silc_free(channel_name);
2835 silc_cipher_free(key);
2836 silc_hmac_free(newhmac);
2837 silc_free(channel_id);
2841 entry->cipher = strdup(cipher);
2842 entry->hmac_name = strdup(hmac);
2844 /* Now create the actual key material */
2845 if (!silc_server_create_channel_key(server, entry,
2846 silc_cipher_get_key_len(key) / 8)) {
2847 silc_idlist_del_channel(server->local_list, entry);
2851 /* Notify other routers about the new channel. We send the packet
2852 to our primary route. */
2853 if (broadcast && server->standalone == FALSE)
2854 silc_server_send_new_channel(server, server->router->connection, TRUE,
2855 channel_name, entry->id,
2856 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2859 server->stat.my_channels++;
2864 /* Same as above but creates the channel with Channel ID `channel_id. */
2867 silc_server_create_new_channel_with_id(SilcServer server,
2871 SilcChannelID *channel_id,
2874 SilcChannelEntry entry;
2878 SILC_LOG_DEBUG(("Creating new channel"));
2881 cipher = SILC_DEFAULT_CIPHER;
2883 hmac = SILC_DEFAULT_HMAC;
2885 /* Allocate cipher */
2886 if (!silc_cipher_alloc(cipher, &key))
2890 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2891 silc_cipher_free(key);
2895 channel_name = strdup(channel_name);
2897 /* Create the channel */
2898 entry = silc_idlist_add_channel(server->local_list, channel_name,
2899 SILC_CHANNEL_MODE_NONE, channel_id,
2900 NULL, key, newhmac, 0);
2902 silc_cipher_free(key);
2903 silc_hmac_free(newhmac);
2904 silc_free(channel_name);
2908 /* Now create the actual key material */
2909 if (!silc_server_create_channel_key(server, entry,
2910 silc_cipher_get_key_len(key) / 8)) {
2911 silc_idlist_del_channel(server->local_list, entry);
2915 /* Notify other routers about the new channel. We send the packet
2916 to our primary route. */
2917 if (broadcast && server->standalone == FALSE)
2918 silc_server_send_new_channel(server, server->router->connection, TRUE,
2919 channel_name, entry->id,
2920 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2923 server->stat.my_channels++;
2928 /* Channel's key re-key timeout callback. */
2930 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
2932 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
2933 SilcServer server = (SilcServer)rekey->context;
2937 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
2940 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
2943 /* Generates new channel key. This is used to create the initial channel key
2944 but also to re-generate new key for channel. If `key_len' is provided
2945 it is the bytes of the key length. */
2947 bool silc_server_create_channel_key(SilcServer server,
2948 SilcChannelEntry channel,
2952 unsigned char channel_key[32], hash[32];
2955 SILC_LOG_DEBUG(("Generating channel key"));
2957 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2958 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
2962 if (!channel->channel_key)
2963 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
2964 channel->channel_key = NULL;
2970 else if (channel->key_len)
2971 len = channel->key_len / 8;
2973 len = silc_cipher_get_key_len(channel->channel_key) / 8;
2975 /* Create channel key */
2976 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
2979 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
2981 /* Remove old key if exists */
2983 memset(channel->key, 0, channel->key_len / 8);
2984 silc_free(channel->key);
2988 channel->key_len = len * 8;
2989 channel->key = silc_calloc(len, sizeof(*channel->key));
2990 memcpy(channel->key, channel_key, len);
2991 memset(channel_key, 0, sizeof(channel_key));
2993 /* Generate HMAC key from the channel key data and set it */
2995 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
2996 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
2997 silc_hmac_set_key(channel->hmac, hash,
2998 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
2999 memset(hash, 0, sizeof(hash));
3001 if (server->server_type == SILC_ROUTER) {
3002 if (!channel->rekey)
3003 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3004 channel->rekey->context = (void *)server;
3005 channel->rekey->channel = channel;
3006 channel->rekey->key_len = key_len;
3007 if (channel->rekey->task)
3008 silc_schedule_task_del(server->schedule, channel->rekey->task);
3010 channel->rekey->task =
3011 silc_schedule_task_add(server->schedule, 0,
3012 silc_server_channel_key_rekey,
3013 (void *)channel->rekey, 3600, 0,
3015 SILC_TASK_PRI_NORMAL);
3021 /* Saves the channel key found in the encoded `key_payload' buffer. This
3022 function is used when we receive Channel Key Payload and also when we're
3023 processing JOIN command reply. Returns entry to the channel. */
3025 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3026 SilcBuffer key_payload,
3027 SilcChannelEntry channel)
3029 SilcChannelKeyPayload payload = NULL;
3030 SilcChannelID *id = NULL;
3031 unsigned char *tmp, hash[32];
3035 SILC_LOG_DEBUG(("Start"));
3037 /* Decode channel key payload */
3038 payload = silc_channel_key_payload_parse(key_payload->data,
3041 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3046 /* Get the channel entry */
3049 /* Get channel ID */
3050 tmp = silc_channel_key_get_id(payload, &tmp_len);
3051 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
3057 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
3059 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
3061 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3062 silc_id_render(id, SILC_ID_CHANNEL)));
3068 tmp = silc_channel_key_get_key(payload, &tmp_len);
3074 cipher = silc_channel_key_get_cipher(payload, NULL);
3080 /* Remove old key if exists */
3082 memset(channel->key, 0, channel->key_len / 8);
3083 silc_free(channel->key);
3084 silc_cipher_free(channel->channel_key);
3087 /* Create new cipher */
3088 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3089 channel->channel_key = NULL;
3094 if (channel->cipher)
3095 silc_free(channel->cipher);
3096 channel->cipher = strdup(cipher);
3099 channel->key_len = tmp_len * 8;
3100 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
3101 memcpy(channel->key, tmp, tmp_len);
3102 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3104 /* Generate HMAC key from the channel key data and set it */
3106 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3107 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3108 silc_hmac_set_key(channel->hmac, hash,
3109 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3111 memset(hash, 0, sizeof(hash));
3112 memset(tmp, 0, tmp_len);
3114 if (server->server_type == SILC_ROUTER) {
3115 if (!channel->rekey)
3116 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3117 channel->rekey->context = (void *)server;
3118 channel->rekey->channel = channel;
3119 if (channel->rekey->task)
3120 silc_schedule_task_del(server->schedule, channel->rekey->task);
3122 channel->rekey->task =
3123 silc_schedule_task_add(server->schedule, 0,
3124 silc_server_channel_key_rekey,
3125 (void *)channel->rekey, 3600, 0,
3127 SILC_TASK_PRI_NORMAL);
3133 silc_channel_key_payload_free(payload);
3138 /* Heartbeat callback. This function is set as argument for the
3139 silc_socket_set_heartbeat function. The library will call this function
3140 at the set time interval. */
3142 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3145 SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3147 SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
3149 /* Send the heartbeat */
3150 silc_server_send_heartbeat(hb->server, sock);
3153 /* Returns assembled of all servers in the given ID list. The packet's
3154 form is dictated by the New ID payload. */
3156 static void silc_server_announce_get_servers(SilcServer server,
3157 SilcServerEntry remote,
3159 SilcBuffer *servers,
3160 unsigned long creation_time)
3162 SilcIDCacheList list;
3163 SilcIDCacheEntry id_cache;
3164 SilcServerEntry entry;
3167 /* Go through all clients in the list */
3168 if (silc_idcache_get_all(id_list->servers, &list)) {
3169 if (silc_idcache_list_first(list, &id_cache)) {
3171 entry = (SilcServerEntry)id_cache->context;
3173 /* Do not announce the one we've sending our announcements and
3174 do not announce ourself. Also check the creation time if it's
3176 if ((entry == remote) || (entry == server->id_entry) ||
3177 (creation_time && entry->data.created < creation_time)) {
3178 if (!silc_idcache_list_next(list, &id_cache))
3183 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3185 *servers = silc_buffer_realloc(*servers,
3187 (*servers)->truelen + idp->len :
3189 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3190 silc_buffer_put(*servers, idp->data, idp->len);
3191 silc_buffer_pull(*servers, idp->len);
3192 silc_buffer_free(idp);
3194 if (!silc_idcache_list_next(list, &id_cache))
3199 silc_idcache_list_free(list);
3204 silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
3210 p = silc_notify_payload_encode(notify, argc, ap);
3216 /* This function is used by router to announce existing servers to our
3217 primary router when we've connected to it. If `creation_time' is non-zero
3218 then only the servers that has been created after the `creation_time'
3219 will be announced. */
3221 void silc_server_announce_servers(SilcServer server, bool global,
3222 unsigned long creation_time,
3223 SilcSocketConnection remote)
3225 SilcBuffer servers = NULL;
3227 SILC_LOG_DEBUG(("Announcing servers"));
3229 /* Get servers in local list */
3230 silc_server_announce_get_servers(server, remote->user_data,
3231 server->local_list, &servers,
3235 /* Get servers in global list */
3236 silc_server_announce_get_servers(server, remote->user_data,
3237 server->global_list, &servers,
3241 silc_buffer_push(servers, servers->data - servers->head);
3242 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3244 /* Send the packet */
3245 silc_server_packet_send(server, remote,
3246 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3247 servers->data, servers->len, TRUE);
3249 silc_buffer_free(servers);
3253 /* Returns assembled packet of all clients in the given ID list. The
3254 packet's form is dictated by the New ID Payload. */
3256 static void silc_server_announce_get_clients(SilcServer server,
3258 SilcBuffer *clients,
3260 unsigned long creation_time)
3262 SilcIDCacheList list;
3263 SilcIDCacheEntry id_cache;
3264 SilcClientEntry client;
3267 unsigned char mode[4];
3269 /* Go through all clients in the list */
3270 if (silc_idcache_get_all(id_list->clients, &list)) {
3271 if (silc_idcache_list_first(list, &id_cache)) {
3273 client = (SilcClientEntry)id_cache->context;
3275 if (creation_time && client->data.created < creation_time) {
3276 if (!silc_idcache_list_next(list, &id_cache))
3281 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3283 *clients = silc_buffer_realloc(*clients,
3285 (*clients)->truelen + idp->len :
3287 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3288 silc_buffer_put(*clients, idp->data, idp->len);
3289 silc_buffer_pull(*clients, idp->len);
3291 SILC_PUT32_MSB(client->mode, mode);
3292 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3293 2, idp->data, idp->len,
3295 *umodes = silc_buffer_realloc(*umodes,
3297 (*umodes)->truelen + tmp->len :
3299 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3300 silc_buffer_put(*umodes, tmp->data, tmp->len);
3301 silc_buffer_pull(*umodes, tmp->len);
3302 silc_buffer_free(tmp);
3304 silc_buffer_free(idp);
3306 if (!silc_idcache_list_next(list, &id_cache))
3311 silc_idcache_list_free(list);
3315 /* This function is used to announce our existing clients to our router
3316 when we've connected to it. If `creation_time' is non-zero then only
3317 the clients that has been created after the `creation_time' will be
3320 void silc_server_announce_clients(SilcServer server,
3321 unsigned long creation_time,
3322 SilcSocketConnection remote)
3324 SilcBuffer clients = NULL;
3325 SilcBuffer umodes = NULL;
3327 SILC_LOG_DEBUG(("Announcing clients"));
3329 /* Get clients in local list */
3330 silc_server_announce_get_clients(server, server->local_list,
3331 &clients, &umodes, creation_time);
3333 /* As router we announce our global list as well */
3334 if (server->server_type == SILC_ROUTER)
3335 silc_server_announce_get_clients(server, server->global_list,
3336 &clients, &umodes, creation_time);
3339 silc_buffer_push(clients, clients->data - clients->head);
3340 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3342 /* Send the packet */
3343 silc_server_packet_send(server, remote,
3344 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3345 clients->data, clients->len, TRUE);
3347 silc_buffer_free(clients);
3351 silc_buffer_push(umodes, umodes->data - umodes->head);
3352 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
3354 /* Send the packet */
3355 silc_server_packet_send(server, remote,
3356 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3357 umodes->data, umodes->len, TRUE);
3359 silc_buffer_free(umodes);
3363 /* Returns channel's topic for announcing it */
3365 void silc_server_announce_get_channel_topic(SilcServer server,
3366 SilcChannelEntry channel,
3371 if (channel->topic) {
3372 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3373 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3374 chidp->data, chidp->len,
3376 strlen(channel->topic));
3377 silc_buffer_free(chidp);
3381 /* Returns assembled packets for channel users of the `channel'. */
3383 void silc_server_announce_get_channel_users(SilcServer server,
3384 SilcChannelEntry channel,
3385 SilcBuffer *channel_users,
3386 SilcBuffer *channel_users_modes)
3388 SilcChannelClientEntry chl;
3389 SilcHashTableList htl;
3390 SilcBuffer chidp, clidp;
3393 unsigned char mode[4];
3395 SILC_LOG_DEBUG(("Start"));
3397 /* Now find all users on the channel */
3398 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3399 silc_hash_table_list(channel->user_list, &htl);
3400 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3401 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3404 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
3405 clidp->data, clidp->len,
3406 chidp->data, chidp->len);
3409 silc_buffer_realloc(*channel_users,
3411 (*channel_users)->truelen + len : len));
3412 silc_buffer_pull_tail(*channel_users,
3413 ((*channel_users)->end -
3414 (*channel_users)->data));
3416 silc_buffer_put(*channel_users, tmp->data, tmp->len);
3417 silc_buffer_pull(*channel_users, len);
3418 silc_buffer_free(tmp);
3420 /* CUMODE notify for mode change on the channel */
3421 SILC_PUT32_MSB(chl->mode, mode);
3422 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
3423 3, clidp->data, clidp->len,
3425 clidp->data, clidp->len);
3427 *channel_users_modes =
3428 silc_buffer_realloc(*channel_users_modes,
3429 (*channel_users_modes ?
3430 (*channel_users_modes)->truelen + len : len));
3431 silc_buffer_pull_tail(*channel_users_modes,
3432 ((*channel_users_modes)->end -
3433 (*channel_users_modes)->data));
3435 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3436 silc_buffer_pull(*channel_users_modes, len);
3437 silc_buffer_free(tmp);
3439 silc_buffer_free(clidp);
3441 silc_hash_table_list_reset(&htl);
3442 silc_buffer_free(chidp);
3445 /* Returns assembled packets for all channels and users on those channels
3446 from the given ID List. The packets are in the form dictated by the
3447 New Channel and New Channel User payloads. */
3449 void silc_server_announce_get_channels(SilcServer server,
3451 SilcBuffer *channels,
3452 SilcBuffer *channel_users,
3453 SilcBuffer **channel_users_modes,
3454 uint32 *channel_users_modes_c,
3455 SilcBuffer **channel_topics,
3456 SilcChannelID ***channel_ids,
3457 unsigned long creation_time)
3459 SilcIDCacheList list;
3460 SilcIDCacheEntry id_cache;
3461 SilcChannelEntry channel;
3466 int i = *channel_users_modes_c;
3469 SILC_LOG_DEBUG(("Start"));
3471 /* Go through all channels in the list */
3472 if (silc_idcache_get_all(id_list->channels, &list)) {
3473 if (silc_idcache_list_first(list, &id_cache)) {
3475 channel = (SilcChannelEntry)id_cache->context;
3477 if (creation_time && channel->created < creation_time)
3482 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3483 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3484 name_len = strlen(channel->channel_name);
3487 len = 4 + name_len + id_len + 4;
3489 silc_buffer_realloc(*channels,
3490 (*channels ? (*channels)->truelen +
3492 silc_buffer_pull_tail(*channels,
3493 ((*channels)->end - (*channels)->data));
3494 silc_buffer_format(*channels,
3495 SILC_STR_UI_SHORT(name_len),
3496 SILC_STR_UI_XNSTRING(channel->channel_name,
3498 SILC_STR_UI_SHORT(id_len),
3499 SILC_STR_UI_XNSTRING(cid, id_len),
3500 SILC_STR_UI_INT(channel->mode),
3502 silc_buffer_pull(*channels, len);
3505 /* Channel user modes */
3506 *channel_users_modes = silc_realloc(*channel_users_modes,
3507 sizeof(**channel_users_modes) *
3509 (*channel_users_modes)[i] = NULL;
3510 *channel_ids = silc_realloc(*channel_ids,
3511 sizeof(**channel_ids) * (i + 1));
3512 (*channel_ids)[i] = NULL;
3513 silc_server_announce_get_channel_users(server, channel,
3515 &(*channel_users_modes)[i]);
3516 (*channel_ids)[i] = channel->id;
3518 /* Channel's topic */
3519 *channel_topics = silc_realloc(*channel_topics,
3520 sizeof(**channel_topics) * (i + 1));
3521 (*channel_topics)[i] = NULL;
3522 silc_server_announce_get_channel_topic(server, channel,
3523 &(*channel_topics)[i]);
3526 if (!silc_idcache_list_next(list, &id_cache))
3530 *channel_users_modes_c += i;
3533 silc_idcache_list_free(list);
3537 /* This function is used to announce our existing channels to our router
3538 when we've connected to it. This also announces the users on the
3539 channels to the router. If the `creation_time' is non-zero only the
3540 channels that was created after the `creation_time' are announced.
3541 Note that the channel users are still announced even if the `creation_time'
3544 void silc_server_announce_channels(SilcServer server,
3545 unsigned long creation_time,
3546 SilcSocketConnection remote)
3548 SilcBuffer channels = NULL, channel_users = NULL;
3549 SilcBuffer *channel_users_modes = NULL;
3550 SilcBuffer *channel_topics = NULL;
3551 uint32 channel_users_modes_c = 0;
3552 SilcChannelID **channel_ids = NULL;
3554 SILC_LOG_DEBUG(("Announcing channels and channel users"));
3556 /* Get channels and channel users in local list */
3557 silc_server_announce_get_channels(server, server->local_list,
3558 &channels, &channel_users,
3559 &channel_users_modes,
3560 &channel_users_modes_c,
3562 &channel_ids, creation_time);
3564 /* Get channels and channel users in global list */
3565 if (server->server_type != SILC_SERVER)
3566 silc_server_announce_get_channels(server, server->global_list,
3567 &channels, &channel_users,
3568 &channel_users_modes,
3569 &channel_users_modes_c,
3571 &channel_ids, creation_time);
3574 silc_buffer_push(channels, channels->data - channels->head);
3575 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3577 /* Send the packet */
3578 silc_server_packet_send(server, remote,
3579 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3580 channels->data, channels->len,
3583 silc_buffer_free(channels);
3586 if (channel_users) {
3587 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3588 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
3589 channel_users->len);
3591 /* Send the packet */
3592 silc_server_packet_send(server, remote,
3593 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3594 channel_users->data, channel_users->len,
3597 silc_buffer_free(channel_users);
3600 if (channel_users_modes) {
3603 for (i = 0; i < channel_users_modes_c; i++) {
3604 if (!channel_users_modes[i])
3606 silc_buffer_push(channel_users_modes[i],
3607 channel_users_modes[i]->data -
3608 channel_users_modes[i]->head);
3609 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
3610 channel_users_modes[i]->len);
3611 silc_server_packet_send_dest(server, remote,
3612 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3613 channel_ids[i], SILC_ID_CHANNEL,
3614 channel_users_modes[i]->data,
3615 channel_users_modes[i]->len,
3617 silc_buffer_free(channel_users_modes[i]);
3619 silc_free(channel_users_modes);
3622 if (channel_topics) {
3625 for (i = 0; i < channel_users_modes_c; i++) {
3626 if (!channel_topics[i])
3629 silc_buffer_push(channel_topics[i],
3630 channel_topics[i]->data -
3631 channel_topics[i]->head);
3632 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
3633 channel_topics[i]->len);
3634 silc_server_packet_send_dest(server, remote,
3635 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3636 channel_ids[i], SILC_ID_CHANNEL,
3637 channel_topics[i]->data,
3638 channel_topics[i]->len,
3640 silc_buffer_free(channel_topics[i]);
3642 silc_free(channel_topics);
3645 silc_free(channel_ids);
3648 /* Failure timeout callback. If this is called then we will immediately
3649 process the received failure. We always process the failure with timeout
3650 since we do not want to blindly trust to received failure packets.
3651 This won't be called (the timeout is cancelled) if the failure was
3652 bogus (it is bogus if remote does not close the connection after sending
3655 SILC_TASK_CALLBACK(silc_server_failure_callback)
3657 SilcServerFailureContext f = (SilcServerFailureContext)context;
3659 if (f->sock->protocol) {
3660 f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
3661 silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
3667 /* Assembles user list and users mode list from the `channel'. */
3669 void silc_server_get_users_on_channel(SilcServer server,
3670 SilcChannelEntry channel,
3671 SilcBuffer *user_list,
3672 SilcBuffer *mode_list,
3675 SilcChannelClientEntry chl;
3676 SilcHashTableList htl;
3677 SilcBuffer client_id_list;
3678 SilcBuffer client_mode_list;
3680 uint32 list_count = 0, len = 0;
3682 silc_hash_table_list(channel->user_list, &htl);
3683 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
3684 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
3685 silc_hash_table_list_reset(&htl);
3687 client_id_list = silc_buffer_alloc(len);
3689 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
3690 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
3691 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
3693 silc_hash_table_list(channel->user_list, &htl);
3694 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3696 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3697 silc_buffer_put(client_id_list, idp->data, idp->len);
3698 silc_buffer_pull(client_id_list, idp->len);
3699 silc_buffer_free(idp);
3701 /* Client's mode on channel */
3702 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
3703 silc_buffer_pull(client_mode_list, 4);
3707 silc_hash_table_list_reset(&htl);
3708 silc_buffer_push(client_id_list,
3709 client_id_list->data - client_id_list->head);
3710 silc_buffer_push(client_mode_list,
3711 client_mode_list->data - client_mode_list->head);
3713 *user_list = client_id_list;
3714 *mode_list = client_mode_list;
3715 *user_count = list_count;
3718 /* Saves users and their modes to the `channel'. */
3720 void silc_server_save_users_on_channel(SilcServer server,
3721 SilcSocketConnection sock,
3722 SilcChannelEntry channel,
3723 SilcClientID *noadd,
3724 SilcBuffer user_list,
3725 SilcBuffer mode_list,
3731 SilcClientID *client_id;
3732 SilcClientEntry client;
3733 SilcIDCacheEntry cache;
3736 SILC_LOG_DEBUG(("Start"));
3738 for (i = 0; i < user_count; i++) {
3740 SILC_GET16_MSB(idp_len, user_list->data + 2);
3742 client_id = silc_id_payload_parse_id(user_list->data, idp_len);
3743 silc_buffer_pull(user_list, idp_len);
3748 SILC_GET32_MSB(mode, mode_list->data);
3749 silc_buffer_pull(mode_list, 4);
3751 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
3752 silc_free(client_id);
3758 /* Check if we have this client cached already. */
3759 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3760 server->server_type, &cache);
3762 client = silc_idlist_find_client_by_id(server->global_list,
3763 client_id, server->server_type,
3768 /* If router did not find such Client ID in its lists then this must
3769 be bogus client or some router in the net is buggy. */
3770 if (server->server_type == SILC_ROUTER) {
3771 silc_free(client_id);
3775 /* We don't have that client anywhere, add it. The client is added
3776 to global list since server didn't have it in the lists so it must be
3778 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
3779 silc_id_dup(client_id, SILC_ID_CLIENT),
3780 sock->user_data, NULL, 0);
3782 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
3783 silc_free(client_id);
3787 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3789 /* Found, if it is from global list we'll assure that we won't
3790 expire it now that the entry is on channel. */
3795 silc_free(client_id);
3797 if (!silc_server_client_on_channel(client, channel)) {
3798 /* Client was not on the channel, add it. */
3799 SilcChannelClientEntry chl = silc_calloc(1, sizeof(*chl));
3800 chl->client = client;
3802 chl->channel = channel;
3803 silc_hash_table_add(channel->user_list, chl->client, chl);
3804 silc_hash_table_add(client->channels, chl->channel, chl);
3809 /* Lookups route to the client indicated by the `id_data'. The connection
3810 object and internal data object is returned. Returns NULL if route
3811 could not be found to the client. If the `client_id' is specified then
3812 it is used and the `id_data' is ignored. */
3814 SilcSocketConnection silc_server_get_client_route(SilcServer server,
3815 unsigned char *id_data,
3817 SilcClientID *client_id,
3818 SilcIDListData *idata)
3821 SilcClientEntry client;
3823 SILC_LOG_DEBUG(("Start"));
3825 /* Decode destination Client ID */
3827 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
3829 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
3833 id = silc_id_dup(client_id, SILC_ID_CLIENT);
3836 /* If the destination belongs to our server we don't have to route
3837 the packet anywhere but to send it to the local destination. */
3838 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
3842 /* If we are router and the client has router then the client is in
3843 our cell but not directly connected to us. */
3844 if (server->server_type == SILC_ROUTER && client->router) {
3845 /* We are of course in this case the client's router thus the route
3846 to the client is the server who owns the client. So, we will send
3847 the packet to that server. */
3849 *idata = (SilcIDListData)client->router;
3850 return client->router->connection;
3853 /* Seems that client really is directly connected to us */
3855 *idata = (SilcIDListData)client;
3856 return client->connection;
3859 /* Destination belongs to someone not in this server. If we are normal
3860 server our action is to send the packet to our router. */
3861 if (server->server_type != SILC_ROUTER && !server->standalone) {
3864 *idata = (SilcIDListData)server->router;
3865 return server->router->connection;
3868 /* We are router and we will perform route lookup for the destination
3869 and send the packet to fastest route. */
3870 if (server->server_type == SILC_ROUTER && !server->standalone) {
3871 /* Check first that the ID is valid */
3872 client = silc_idlist_find_client_by_id(server->global_list, id,
3875 SilcSocketConnection dst_sock;
3877 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
3881 *idata = (SilcIDListData)dst_sock->user_data;
3890 /* Encodes and returns channel list of channels the `client' has joined.
3891 Secret channels are not put to the list. */
3893 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
3894 SilcClientEntry client)
3896 SilcBuffer buffer = NULL;
3897 SilcChannelEntry channel;
3898 SilcChannelClientEntry chl;
3899 SilcHashTableList htl;
3905 silc_hash_table_list(client->channels, &htl);
3906 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3907 channel = chl->channel;
3909 if (channel->mode & SILC_CHANNEL_MODE_SECRET ||
3910 channel->mode & SILC_CHANNEL_MODE_PRIVATE)
3913 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3914 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3915 name_len = strlen(channel->channel_name);
3917 len = 4 + name_len + id_len + 4;
3918 buffer = silc_buffer_realloc(buffer,
3919 (buffer ? (buffer)->truelen + len : len));
3920 silc_buffer_pull_tail(buffer, ((buffer)->end - (buffer)->data));
3921 silc_buffer_format(buffer,
3922 SILC_STR_UI_SHORT(name_len),
3923 SILC_STR_UI_XNSTRING(channel->channel_name,
3925 SILC_STR_UI_SHORT(id_len),
3926 SILC_STR_UI_XNSTRING(cid, id_len),
3927 SILC_STR_UI_INT(chl->mode), /* Client's mode */
3929 silc_buffer_pull(buffer, len);
3932 silc_hash_table_list_reset(&htl);
3935 silc_buffer_push(buffer, buffer->data - buffer->head);
3940 /* Finds client entry by Client ID and if it is not found then resolves
3941 it using WHOIS command. */
3943 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
3944 SilcClientID *client_id,
3947 SilcClientEntry client;
3952 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3955 client = silc_idlist_find_client_by_id(server->global_list,
3956 client_id, TRUE, NULL);
3957 if (!client && server->server_type == SILC_ROUTER)
3961 if (!client && server->standalone)
3964 if (!client || !client->nickname || !client->username) {
3965 SilcBuffer buffer, idp;
3967 client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
3968 client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
3969 client->resolve_cmd_ident = ++server->cmd_ident;
3971 idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3972 buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
3973 server->cmd_ident, 1,
3974 3, idp->data, idp->len);
3975 silc_server_packet_send(server, client ? client->router->connection :
3976 server->router->connection,
3977 SILC_PACKET_COMMAND, 0,
3978 buffer->data, buffer->len, FALSE);
3979 silc_buffer_free(idp);
3980 silc_buffer_free(buffer);
3991 /* A timeout callback for the re-key. We will be the initiator of the
3994 SILC_TASK_CALLBACK(silc_server_rekey_callback)
3996 SilcSocketConnection sock = (SilcSocketConnection)context;
3997 SilcIDListData idata = (SilcIDListData)sock->user_data;
3998 SilcServer server = (SilcServer)idata->rekey->context;
3999 SilcProtocol protocol;
4000 SilcServerRekeyInternalContext *proto_ctx;
4002 SILC_LOG_DEBUG(("Start"));
4004 /* Allocate internal protocol context. This is sent as context
4006 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
4007 proto_ctx->server = (void *)server;
4008 proto_ctx->sock = sock;
4009 proto_ctx->responder = FALSE;
4010 proto_ctx->pfs = idata->rekey->pfs;
4012 /* Perform rekey protocol. Will call the final callback after the
4013 protocol is over. */
4014 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
4015 &protocol, proto_ctx, silc_server_rekey_final);
4016 sock->protocol = protocol;
4018 /* Run the protocol */
4019 silc_protocol_execute(protocol, server->schedule, 0, 0);
4021 /* Re-register re-key timeout */
4022 silc_schedule_task_add(server->schedule, sock->sock,
4023 silc_server_rekey_callback,
4024 context, idata->rekey->timeout, 0,
4025 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
4028 /* The final callback for the REKEY protocol. This will actually take the
4029 new key material into use. */
4031 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
4033 SilcProtocol protocol = (SilcProtocol)context;
4034 SilcServerRekeyInternalContext *ctx =
4035 (SilcServerRekeyInternalContext *)protocol->context;
4036 SilcServer server = (SilcServer)ctx->server;
4037 SilcSocketConnection sock = ctx->sock;
4039 SILC_LOG_DEBUG(("Start"));
4041 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
4042 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
4043 /* Error occured during protocol */
4044 SILC_LOG_ERROR(("Error occurred during rekey protocol"));
4045 silc_protocol_cancel(protocol, server->schedule);
4046 silc_protocol_free(protocol);
4047 sock->protocol = NULL;
4049 silc_packet_context_free(ctx->packet);
4051 silc_ske_free(ctx->ske);
4056 /* Purge the outgoing data queue to assure that all rekey packets really
4057 go to the network before we quit the protocol. */
4058 silc_server_packet_queue_purge(server, sock);
4061 silc_protocol_free(protocol);
4062 sock->protocol = NULL;
4064 silc_packet_context_free(ctx->packet);
4066 silc_ske_free(ctx->ske);