5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2001 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 silc_free(server->params);
98 if (server->pending_commands)
99 silc_dlist_uninit(server->pending_commands);
105 /* Initializes the entire SILC server. This is called always before running
106 the server. This is called only once at the initialization of the program.
107 This binds the server to its listenning port. After this function returns
108 one should call silc_server_run to start the server. This returns TRUE
109 when everything is ok to run the server. Configuration file must be
110 read and parsed before calling this. */
112 int silc_server_init(SilcServer server)
114 int *sock = NULL, sock_count, i;
116 SilcServerEntry id_entry;
117 SilcIDListPurge purge;
119 SILC_LOG_DEBUG(("Initializing server"));
121 assert(server->config);
123 /* Set public and private keys */
124 if (!server->config->server_info ||
125 !server->config->server_info->public_key ||
126 !server->config->server_info->private_key) {
127 SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
130 server->public_key = server->config->server_info->public_key;
131 server->private_key = server->config->server_info->private_key;
133 /* XXX After server is made as Silc Server Library this can be given
134 as argument, for now this is hard coded */
135 server->params = silc_calloc(1, sizeof(*server->params));
136 server->params->retry_count = SILC_SERVER_RETRY_COUNT;
137 server->params->retry_interval_min = SILC_SERVER_RETRY_INTERVAL_MIN;
138 server->params->retry_interval_max = SILC_SERVER_RETRY_INTERVAL_MAX;
139 server->params->retry_keep_trying = FALSE;
140 server->params->protocol_timeout = 60;
141 server->params->require_reverse_mapping = FALSE;
143 /* Register all configured ciphers, PKCS and hash functions. */
144 if (!silc_server_config_register_ciphers(server))
145 silc_cipher_register_default();
146 if (!silc_server_config_register_pkcs(server))
147 silc_pkcs_register_default();
148 if (!silc_server_config_register_hashfuncs(server))
149 silc_hash_register_default();
150 if (!silc_server_config_register_hmacs(server))
151 silc_hmac_register_default();
153 /* Initialize random number generator for the server. */
154 server->rng = silc_rng_alloc();
155 silc_rng_init(server->rng);
156 silc_rng_global_init(server->rng);
158 /* Initialize hash functions for server to use */
159 silc_hash_alloc("md5", &server->md5hash);
160 silc_hash_alloc("sha1", &server->sha1hash);
162 /* Allocate PKCS context for local public and private keys */
163 silc_pkcs_alloc(server->public_key->name, &server->pkcs);
164 silc_pkcs_public_key_set(server->pkcs, server->public_key);
165 silc_pkcs_private_key_set(server->pkcs, server->private_key);
167 /* Create a listening server. Note that our server can listen on multiple
168 ports. All listeners are created here and now. */
173 tmp = silc_net_create_server(server->config->server_info->port,
174 server->config->server_info->server_ip);
177 SILC_LOG_ERROR(("Could not create server listener: %s on %hd",
178 server->config->server_info->server_ip,
179 server->config->server_info->port));
183 sock = silc_realloc(sock, sizeof(*sock) * (sock_count + 1));
184 sock[sock_count] = tmp;
189 /* Initialize ID caches */
190 server->local_list->clients =
191 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
192 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
193 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
195 /* These are allocated for normal server as well as these hold some
196 global information that the server has fetched from its router. For
197 router these are used as they are supposed to be used on router. */
198 server->global_list->clients =
199 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
200 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
201 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
203 /* Allocate the entire socket list that is used in server. Eventually
204 all connections will have entry in this table (it is a table of
205 pointers to the actual object that is allocated individually
207 server->sockets = silc_calloc(SILC_SERVER_MAX_CONNECTIONS,
208 sizeof(*server->sockets));
210 for (i = 0; i < sock_count; i++) {
211 SilcSocketConnection newsocket = NULL;
213 /* Set socket to non-blocking mode */
214 silc_net_set_socket_nonblock(sock[i]);
215 server->sock = sock[i];
217 /* Add ourselves also to the socket table. The entry allocated above
218 is sent as argument for fast referencing in the future. */
219 silc_socket_alloc(sock[i], SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
220 server->sockets[sock[i]] = newsocket;
222 /* Perform name and address lookups to resolve the listenning address
224 if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname,
226 if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
228 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
229 newsocket->hostname ? newsocket->hostname :
230 newsocket->ip ? newsocket->ip : ""));
231 server->stat.conn_failures++;
234 if (!newsocket->hostname)
235 newsocket->hostname = strdup(newsocket->ip);
237 newsocket->port = silc_net_get_local_port(sock[i]);
239 /* Create a Server ID for the server. */
240 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
245 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
246 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
247 server->id_type = SILC_ID_SERVER;
248 server->server_name = server->config->server_info->server_name;
250 /* Add ourselves to the server list. We don't have a router yet
251 beacuse we haven't established a route yet. It will be done later.
252 For now, NULL is sent as router. This allocates new entry to
255 silc_idlist_add_server(server->local_list,
256 server->config->server_info->server_name,
257 server->server_type, server->id, NULL, NULL);
259 SILC_LOG_ERROR(("Could not add ourselves to cache"));
262 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
264 /* Put the allocated socket pointer also to the entry allocated above
265 for fast back-referencing to the socket list. */
266 newsocket->user_data = (void *)id_entry;
267 id_entry->connection = (void *)newsocket;
268 server->id_entry = id_entry;
271 /* Register protocols */
272 silc_server_protocols_register();
274 /* Initialize the scheduler. */
275 server->schedule = silc_schedule_init(SILC_SERVER_MAX_CONNECTIONS);
276 if (!server->schedule)
279 /* Add the first task to the scheduler. This is task that is executed by
280 timeout. It expires as soon as the caller calls silc_server_run. This
281 task performs authentication protocol and key exchange with our
283 silc_schedule_task_add(server->schedule, sock[0],
284 silc_server_connect_to_router,
285 (void *)server, 0, 1,
287 SILC_TASK_PRI_NORMAL);
289 /* Add listener task to the scheduler. This task receives new connections
290 to the server. This task remains on the queue until the end of the
292 silc_schedule_task_add(server->schedule, sock[0],
293 silc_server_accept_new_connection,
294 (void *)server, 0, 0,
296 SILC_TASK_PRI_NORMAL);
297 server->listenning = TRUE;
299 /* Send log file configuration */
300 silc_server_config_setlogfiles(server);
302 /* If server connections has been configured then we must be router as
303 normal server cannot have server connections, only router connections. */
304 if (server->config->servers) {
305 SilcServerConfigSectionServer *ptr = server->config->servers;
307 server->server_type = SILC_ROUTER;
309 if (ptr->backup_router) {
310 server->server_type = SILC_BACKUP_ROUTER;
311 server->backup_router = TRUE;
312 server->id_entry->server_type = SILC_BACKUP_ROUTER;
319 /* Register the ID Cache purge task. This periodically purges the ID cache
320 and removes the expired cache entries. */
322 /* Clients local list */
323 purge = silc_calloc(1, sizeof(*purge));
324 purge->cache = server->local_list->clients;
325 purge->schedule = server->schedule;
326 purge->timeout = 600;
327 silc_schedule_task_add(purge->schedule, 0,
329 (void *)purge, purge->timeout, 0,
330 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
332 /* Clients global list */
333 purge = silc_calloc(1, sizeof(*purge));
334 purge->cache = server->global_list->clients;
335 purge->schedule = server->schedule;
336 purge->timeout = 300;
337 silc_schedule_task_add(purge->schedule, 0,
339 (void *)purge, purge->timeout, 0,
340 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
342 SILC_LOG_DEBUG(("Server initialized"));
344 /* We are done here, return succesfully */
348 for (i = 0; i < sock_count; i++)
349 silc_net_close_server(sock[i]);
354 /* Fork server to background */
356 void silc_server_daemonise(SilcServer server)
360 SILC_LOG_DEBUG(("Forking SILC server to background"));
365 SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
370 SILC_LOG_DEBUG(("Server started as user"));
372 SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
378 /* Drop root privligies. If this cannot be done, die. */
380 void silc_server_drop(SilcServer server)
382 /* Are we executing silcd as root or a regular user? */
388 if (!server->config->server_info->user || !server->config->server_info->group) {
389 fprintf(stderr, "Error:"
390 "\tSILC server must not be run as root. For the security of your\n"
391 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
392 "\tuser account. Modify the [Identity] configuration section to run\n"
393 "\tthe server as non-root user.\n");
397 /* Get the values given for user and group in configuration file */
398 user=server->config->server_info->user;
399 group=server->config->server_info->group;
401 /* Check whether the user/group information is text */
402 if (atoi(user)!=0 || atoi(group)!=0) {
403 SILC_LOG_DEBUG(("Invalid user and/or group information"));
404 SILC_LOG_DEBUG(("User and/or group given as number"));
405 fprintf(stderr, "Invalid user and/or group information\n");
406 fprintf(stderr, "Please assign them as names, not numbers\n");
410 /* Catch the nasty incident of string "0" returning 0 from atoi */
411 if (strcmp("0", user)==0 || strcmp("0", group)==0) {
412 SILC_LOG_DEBUG(("User and/or group configured to 0. Unacceptable"));
413 fprintf(stderr, "User and/or group configured to 0. Exiting\n");
417 if (!(pw=getpwnam(user))) {
418 fprintf(stderr, "No such user %s found\n", user);
422 if (!(gr=getgrnam(group))) {
423 fprintf(stderr, "No such group %s found\n", group);
427 /* Check whether user and/or group is set to root. If yes, exit
428 immediately. Otherwise, setgid and setuid server to user.group */
429 if (gr->gr_gid==0 || pw->pw_uid==0) {
430 fprintf(stderr, "Error:"
431 "\tSILC server must not be run as root. For the security of your\n"
432 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
433 "\tuser account. Modify the [Identity] configuration section to run\n"
434 "\tthe server as non-root user.\n");
437 SILC_LOG_DEBUG(("Changing to group %s", group));
438 if (setgid(gr->gr_gid)==0) {
439 SILC_LOG_DEBUG(("Setgid to %s", group));
441 SILC_LOG_DEBUG(("Setgid to %s failed", group));
442 fprintf(stderr, "Tried to setgid %s but no such group. Exiting\n",
446 #if defined HAVE_SETGROUPS && defined HAVE_INITGROUPS
447 if (setgroups(0, NULL)!=0) {
448 SILC_LOG_DEBUG(("Setgroups to NULL failed"));
449 fprintf(stderr, "Tried to setgroups NULL but failed. Exiting\n");
452 if (initgroups(user, gr->gr_gid)!=0) {
453 SILC_LOG_DEBUG(("Initgroups to user %s (gid=%d) failed", user, gr->gr_gid));
454 fprintf(stderr, "Tried to initgroups %s (gid=%d) but no such user. Exiting\n",
459 SILC_LOG_DEBUG(("Changing to user %s", user));
460 if (setuid(pw->pw_uid)==0) {
461 SILC_LOG_DEBUG(("Setuid to %s", user));
463 SILC_LOG_DEBUG(("Setuid to %s failed", user));
464 fprintf(stderr, "Tried to setuid %s but no such user. Exiting\n",
472 /* The heart of the server. This runs the scheduler thus runs the server.
473 When this returns the server has been stopped and the program will
476 void silc_server_run(SilcServer server)
478 SILC_LOG_DEBUG(("Running server"));
480 SILC_LOG_INFO(("SILC Server started"));
482 /* Start the scheduler, the heart of the SILC server. When this returns
483 the program will be terminated. */
484 silc_schedule(server->schedule);
487 /* Stops the SILC server. This function is used to shutdown the server.
488 This is usually called after the scheduler has returned. After stopping
489 the server one should call silc_server_free. */
491 void silc_server_stop(SilcServer server)
493 SILC_LOG_DEBUG(("Stopping server"));
495 if (server->schedule) {
496 silc_schedule_stop(server->schedule);
497 silc_schedule_uninit(server->schedule);
498 server->schedule = NULL;
501 silc_server_protocols_unregister();
503 SILC_LOG_DEBUG(("Server stopped"));
506 /* Function that is called when the network connection to a router has
507 been established. This will continue with the key exchange protocol
508 with the remote router. */
510 void silc_server_start_key_exchange(SilcServer server,
511 SilcServerConnection sconn,
514 SilcSocketConnection newsocket;
515 SilcProtocol protocol;
516 SilcServerKEInternalContext *proto_ctx;
519 /* Cancel any possible retry timeouts */
520 silc_schedule_task_del_by_callback(server->schedule,
521 silc_server_connect_router);
523 /* Set socket options */
524 silc_net_set_socket_nonblock(sock);
525 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
527 /* Create socket connection for the connection. Even though we
528 know that we are connecting to a router we will mark the socket
529 to be unknown connection until we have executed authentication
531 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
532 server->sockets[sock] = newsocket;
533 newsocket->hostname = strdup(sconn->remote_host);
534 newsocket->ip = strdup(sconn->remote_host);
535 newsocket->port = sconn->remote_port;
536 sconn->sock = newsocket;
538 /* Allocate internal protocol context. This is sent as context
540 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
541 proto_ctx->server = (void *)server;
542 proto_ctx->context = (void *)sconn;
543 proto_ctx->sock = newsocket;
544 proto_ctx->rng = server->rng;
545 proto_ctx->responder = FALSE;
547 /* Perform key exchange protocol. silc_server_connect_to_router_second
548 will be called after the protocol is finished. */
549 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
550 &protocol, proto_ctx,
551 silc_server_connect_to_router_second);
552 newsocket->protocol = protocol;
554 /* Register a timeout task that will be executed if the protocol
555 is not executed within set limit. */
556 proto_ctx->timeout_task =
557 silc_schedule_task_add(server->schedule, sock,
558 silc_server_timeout_remote,
559 server, server->params->protocol_timeout,
560 server->params->protocol_timeout_usec,
564 /* Register the connection for network input and output. This sets
565 that scheduler will listen for incoming packets for this connection
566 and sets that outgoing packets may be sent to this connection as
567 well. However, this doesn't set the scheduler for outgoing traffic,
568 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
569 later when outgoing data is available. */
570 context = (void *)server;
571 SILC_REGISTER_CONNECTION_FOR_IO(sock);
573 /* Run the protocol */
574 silc_protocol_execute(protocol, server->schedule, 0, 0);
577 /* Timeout callback that will be called to retry connecting to remote
578 router. This is used by both normal and router server. This will wait
579 before retrying the connecting. The timeout is generated by exponential
580 backoff algorithm. */
582 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
584 SilcServerConnection sconn = (SilcServerConnection)context;
585 SilcServer server = sconn->server;
587 SILC_LOG_INFO(("Retrying connecting to a router"));
589 /* Calculate next timeout */
590 if (sconn->retry_count >= 1) {
591 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
592 if (sconn->retry_timeout > SILC_SERVER_RETRY_INTERVAL_MAX)
593 sconn->retry_timeout = SILC_SERVER_RETRY_INTERVAL_MAX;
595 sconn->retry_timeout = server->params->retry_interval_min;
597 sconn->retry_count++;
598 sconn->retry_timeout = sconn->retry_timeout +
599 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
601 /* If we've reached max retry count, give up. */
602 if (sconn->retry_count > server->params->retry_count &&
603 server->params->retry_keep_trying == FALSE) {
604 SILC_LOG_ERROR(("Could not connect to router, giving up"));
605 silc_free(sconn->remote_host);
610 /* Wait one before retrying */
611 silc_schedule_task_add(server->schedule, fd, silc_server_connect_router,
612 context, sconn->retry_timeout,
613 server->params->retry_interval_min_usec,
614 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
617 /* Generic routine to use connect to a router. */
619 SILC_TASK_CALLBACK(silc_server_connect_router)
621 SilcServerConnection sconn = (SilcServerConnection)context;
622 SilcServer server = sconn->server;
625 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
626 (sconn->backup ? "backup router" : "router"),
627 sconn->remote_host, sconn->remote_port));
629 server->router_connect = time(0);
631 /* Connect to remote host */
632 sock = silc_net_create_connection(server->config->server_info->server_ip,
636 SILC_LOG_ERROR(("Could not connect to router %s:%d",
637 sconn->remote_host, sconn->remote_port));
638 if (!sconn->no_reconnect)
639 silc_schedule_task_add(server->schedule, fd,
640 silc_server_connect_to_router_retry,
641 context, 0, 1, SILC_TASK_TIMEOUT,
642 SILC_TASK_PRI_NORMAL);
646 /* Continue with key exchange protocol */
647 silc_server_start_key_exchange(server, sconn, sock);
650 /* This function connects to our primary router or if we are a router this
651 establishes all our primary routes. This is called at the start of the
652 server to do authentication and key exchange with our router - called
655 SILC_TASK_CALLBACK(silc_server_connect_to_router)
657 SilcServer server = (SilcServer)context;
658 SilcServerConnection sconn;
659 SilcServerConfigSectionRouter *ptr;
661 SILC_LOG_DEBUG(("Connecting to router(s)"));
663 if (server->server_type == SILC_SERVER) {
664 SILC_LOG_DEBUG(("We are normal server"));
665 } else if (server->server_type == SILC_ROUTER) {
666 SILC_LOG_DEBUG(("We are router"));
668 SILC_LOG_DEBUG(("We are backup router/normal server"));
671 /* Create the connections to all our routes */
672 ptr = server->config->routers;
675 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
676 ptr->backup_router ? "Backup router" : "Router",
677 ptr->initiator ? "Initiator" : "Responder",
678 ptr->host, ptr->port));
680 if (ptr->initiator) {
681 /* Allocate connection object for hold connection specific stuff. */
682 sconn = silc_calloc(1, sizeof(*sconn));
683 sconn->server = server;
684 sconn->remote_host = strdup(ptr->host);
685 sconn->remote_port = ptr->port;
686 sconn->backup = ptr->backup_router;
688 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
689 sconn->backup_replace_port = ptr->backup_replace_port;
692 if (!server->router_conn && !sconn->backup)
693 server->router_conn = sconn;
695 silc_schedule_task_add(server->schedule, fd,
696 silc_server_connect_router,
697 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
698 SILC_TASK_PRI_NORMAL);
707 SILC_LOG_DEBUG(("No router(s), server will be standalone"));
709 /* There wasn't a configured router, we will continue but we don't
710 have a connection to outside world. We will be standalone server. */
711 server->standalone = TRUE;
714 /* Second part of connecting to router(s). Key exchange protocol has been
715 executed and now we will execute authentication protocol. */
717 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
719 SilcProtocol protocol = (SilcProtocol)context;
720 SilcServerKEInternalContext *ctx =
721 (SilcServerKEInternalContext *)protocol->context;
722 SilcServer server = (SilcServer)ctx->server;
723 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
724 SilcSocketConnection sock = ctx->sock;
725 SilcServerConnAuthInternalContext *proto_ctx;
726 SilcServerConfigSectionRouter *conn = NULL;
728 SILC_LOG_DEBUG(("Start"));
730 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
731 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
732 /* Error occured during protocol */
733 silc_protocol_free(protocol);
734 sock->protocol = NULL;
735 silc_ske_free_key_material(ctx->keymat);
737 silc_packet_context_free(ctx->packet);
739 silc_ske_free(ctx->ske);
740 silc_free(ctx->dest_id);
742 silc_schedule_task_del_by_callback(server->schedule,
743 silc_server_failure_callback);
744 silc_server_disconnect_remote(server, sock, "Server closed connection: "
745 "Key exchange failed");
749 /* We now have the key material as the result of the key exchange
750 protocol. Take the key material into use. Free the raw key material
751 as soon as we've set them into use. */
752 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
753 ctx->sock, ctx->keymat,
754 ctx->ske->prop->cipher,
755 ctx->ske->prop->pkcs,
756 ctx->ske->prop->hash,
757 ctx->ske->prop->hmac,
758 ctx->ske->prop->group,
760 silc_protocol_free(protocol);
761 sock->protocol = NULL;
762 silc_ske_free_key_material(ctx->keymat);
764 silc_packet_context_free(ctx->packet);
766 silc_ske_free(ctx->ske);
767 silc_free(ctx->dest_id);
769 silc_schedule_task_del_by_callback(server->schedule,
770 silc_server_failure_callback);
771 silc_server_disconnect_remote(server, sock, "Server closed connection: "
772 "Key exchange failed");
775 silc_ske_free_key_material(ctx->keymat);
777 /* Allocate internal context for the authentication protocol. This
778 is sent as context for the protocol. */
779 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
780 proto_ctx->server = (void *)server;
781 proto_ctx->context = (void *)sconn;
782 proto_ctx->sock = sock;
783 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
784 proto_ctx->dest_id_type = ctx->dest_id_type;
785 proto_ctx->dest_id = ctx->dest_id;
787 /* Resolve the authentication method used in this connection. Check if
788 we find a match from user configured connections */
789 conn = silc_server_config_find_router_conn(server, sock->hostname,
792 /* Match found. Use the configured authentication method */
793 if (conn->passphrase) {
794 if (conn->publickey && !server->config->prefer_passphrase_auth) {
795 proto_ctx->auth_data = conn->publickey;
796 proto_ctx->auth_data_len = 0;
797 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
799 proto_ctx->auth_data = strdup(conn->passphrase);
800 proto_ctx->auth_data_len = strlen(conn->passphrase);
801 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
803 } else if (conn->publickey) {
804 proto_ctx->auth_data = conn->publickey;
805 proto_ctx->auth_data_len = 0;
806 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
808 proto_ctx->auth_meth = SILC_AUTH_NONE;
811 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
812 sock->hostname, sock->ip, sock->port));
813 silc_protocol_free(protocol);
814 sock->protocol = NULL;
816 silc_packet_context_free(ctx->packet);
818 silc_ske_free(ctx->ske);
819 silc_free(ctx->dest_id);
821 silc_schedule_task_del_by_callback(server->schedule,
822 silc_server_failure_callback);
823 silc_server_disconnect_remote(server, sock, "Server closed connection: "
824 "Key exchange failed");
828 /* Free old protocol as it is finished now */
829 silc_protocol_free(protocol);
831 silc_packet_context_free(ctx->packet);
833 sock->protocol = NULL;
835 /* Allocate the authentication protocol. This is allocated here
836 but we won't start it yet. We will be receiving party of this
837 protocol thus we will wait that connecting party will make
839 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
840 &sock->protocol, proto_ctx,
841 silc_server_connect_to_router_final);
843 /* Register timeout task. If the protocol is not executed inside
844 this timelimit the connection will be terminated. Currently
845 this is 15 seconds and is hard coded limit (XXX). */
846 proto_ctx->timeout_task =
847 silc_schedule_task_add(server->schedule, sock->sock,
848 silc_server_timeout_remote,
849 (void *)server, 15, 0,
853 /* Run the protocol */
854 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
857 /* Finalizes the connection to router. Registers a server task to the
858 queue so that we can accept new connections. */
860 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
862 SilcProtocol protocol = (SilcProtocol)context;
863 SilcServerConnAuthInternalContext *ctx =
864 (SilcServerConnAuthInternalContext *)protocol->context;
865 SilcServer server = (SilcServer)ctx->server;
866 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
867 SilcSocketConnection sock = ctx->sock;
868 SilcServerEntry id_entry;
870 SilcServerHBContext hb_context;
871 unsigned char *id_string;
873 SilcIDListData idata;
875 SILC_LOG_DEBUG(("Start"));
877 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
878 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
879 /* Error occured during protocol */
880 silc_free(ctx->dest_id);
881 silc_server_disconnect_remote(server, sock, "Server closed connection: "
882 "Authentication failed");
886 /* Add a task to the queue. This task receives new connections to the
887 server. This task remains on the queue until the end of the program. */
888 if (!server->listenning && !sconn->backup) {
889 silc_schedule_task_add(server->schedule, server->sock,
890 silc_server_accept_new_connection,
891 (void *)server, 0, 0,
893 SILC_TASK_PRI_NORMAL);
894 server->listenning = TRUE;
897 /* Send NEW_SERVER packet to the router. We will become registered
898 to the SILC network after sending this packet. */
899 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
900 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
901 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
902 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
903 silc_buffer_format(packet,
904 SILC_STR_UI_SHORT(id_len),
905 SILC_STR_UI_XNSTRING(id_string, id_len),
906 SILC_STR_UI_SHORT(strlen(server->server_name)),
907 SILC_STR_UI_XNSTRING(server->server_name,
908 strlen(server->server_name)),
911 /* Send the packet */
912 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
913 packet->data, packet->len, TRUE);
914 silc_buffer_free(packet);
915 silc_free(id_string);
917 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
919 /* Check that we do not have this ID already */
920 id_entry = silc_idlist_find_server_by_id(server->local_list,
921 ctx->dest_id, TRUE, NULL);
923 silc_idcache_del_by_context(server->local_list->servers, id_entry);
925 id_entry = silc_idlist_find_server_by_id(server->global_list,
926 ctx->dest_id, TRUE, NULL);
928 silc_idcache_del_by_context(server->global_list->servers, id_entry);
931 SILC_LOG_DEBUG(("New server id(%s)",
932 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
934 /* Add the connected router to global server list */
935 id_entry = silc_idlist_add_server(server->global_list,
936 strdup(sock->hostname),
937 SILC_ROUTER, ctx->dest_id, NULL, sock);
939 silc_free(ctx->dest_id);
940 silc_server_disconnect_remote(server, sock, "Server closed connection: "
941 "Authentication failed");
945 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
946 silc_free(sock->user_data);
947 sock->user_data = (void *)id_entry;
948 sock->type = SILC_SOCKET_TYPE_ROUTER;
949 idata = (SilcIDListData)sock->user_data;
950 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
952 /* Perform keepalive. The `hb_context' will be freed automatically
953 when finally calling the silc_socket_free function. XXX hardcoded
955 hb_context = silc_calloc(1, sizeof(*hb_context));
956 hb_context->server = server;
957 silc_socket_set_heartbeat(sock, 300, hb_context,
958 silc_server_perform_heartbeat,
961 /* Register re-key timeout */
962 idata->rekey->timeout = 3600; /* XXX hardcoded */
963 idata->rekey->context = (void *)server;
964 silc_schedule_task_add(server->schedule, sock->sock,
965 silc_server_rekey_callback,
966 (void *)sock, idata->rekey->timeout, 0,
967 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
969 if (!sconn->backup) {
970 /* Mark this router our primary router if we're still standalone */
971 if (server->standalone) {
972 server->id_entry->router = id_entry;
973 server->router = id_entry;
974 server->standalone = FALSE;
976 /* If we are router then announce our possible servers. */
977 if (server->server_type == SILC_ROUTER)
978 silc_server_announce_servers(server, FALSE, 0,
979 server->router->connection);
981 /* Announce our clients and channels to the router */
982 silc_server_announce_clients(server, 0, server->router->connection);
983 silc_server_announce_channels(server, 0, server->router->connection);
986 /* Add this server to be our backup router */
987 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
988 sconn->backup_replace_port, FALSE);
991 sock->protocol = NULL;
993 /* Call the completion callback to indicate that we've connected to
996 (*sconn->callback)(server, id_entry, sconn->callback_context);
999 /* Free the temporary connection data context */
1001 silc_free(sconn->remote_host);
1002 silc_free(sconn->backup_replace_ip);
1005 if (sconn == server->router_conn)
1006 server->router_conn = NULL;
1008 /* Free the protocol object */
1009 if (sock->protocol == protocol)
1010 sock->protocol = NULL;
1011 silc_protocol_free(protocol);
1013 silc_packet_context_free(ctx->packet);
1015 silc_ske_free(ctx->ske);
1016 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1017 silc_free(ctx->auth_data);
1021 /* Host lookup callbcak that is called after the incoming connection's
1022 IP and FQDN lookup is performed. This will actually check the acceptance
1023 of the incoming connection and will register the key exchange protocol
1024 for this connection. */
1027 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1030 SilcServer server = (SilcServer)context;
1031 SilcServerKEInternalContext *proto_ctx;
1032 void *cconfig, *sconfig, *rconfig;
1033 SilcServerConfigSectionDeny *deny;
1036 SILC_LOG_DEBUG(("Start"));
1038 /* Check whether we could resolve both IP and FQDN. */
1039 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1040 server->params->require_reverse_mapping)) {
1041 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1042 sock->hostname ? sock->hostname :
1043 sock->ip ? sock->ip : ""));
1044 server->stat.conn_failures++;
1045 silc_server_disconnect_remote(server, sock,
1046 "Server closed connection: Unknown host");
1050 /* Register the connection for network input and output. This sets
1051 that scheduler will listen for incoming packets for this connection
1052 and sets that outgoing packets may be sent to this connection as well.
1053 However, this doesn't set the scheduler for outgoing traffic, it
1054 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1055 later when outgoing data is available. */
1056 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1058 SILC_LOG_INFO(("Incoming connection from %s (%s)", sock->hostname,
1061 port = server->sockets[server->sock]->port; /* Listenning port */
1063 /* Check whether this connection is denied to connect to us. */
1064 deny = silc_server_config_find_denied(server, sock->ip, port);
1066 deny = silc_server_config_find_denied(server, sock->hostname, port);
1068 /* The connection is denied */
1069 SILC_LOG_INFO(("Connection %s (%s) is denied",
1070 sock->hostname, sock->ip));
1071 silc_server_disconnect_remote(server, sock, deny->reason ?
1073 "Server closed connection: "
1074 "Connection refused");
1075 server->stat.conn_failures++;
1079 /* Check whether we have configred this sort of connection at all. We
1080 have to check all configurations since we don't know what type of
1081 connection this is. */
1082 if (!(cconfig = silc_server_config_find_client(server, sock->ip, port)))
1083 cconfig = silc_server_config_find_client(server, sock->hostname, port);
1084 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1085 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1086 if (!(rconfig = silc_server_config_find_router_conn(server, sock->ip, port)))
1087 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1089 if (!cconfig && !sconfig && !rconfig) {
1090 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1092 silc_server_disconnect_remote(server, sock,
1093 "Server closed connection: "
1094 "Connection refused");
1095 server->stat.conn_failures++;
1099 /* The connection is allowed */
1101 /* Allocate internal context for key exchange protocol. This is
1102 sent as context for the protocol. */
1103 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1104 proto_ctx->server = context;
1105 proto_ctx->sock = sock;
1106 proto_ctx->rng = server->rng;
1107 proto_ctx->responder = TRUE;
1108 proto_ctx->cconfig = cconfig;
1109 proto_ctx->sconfig = sconfig;
1110 proto_ctx->rconfig = rconfig;
1112 /* Prepare the connection for key exchange protocol. We allocate the
1113 protocol but will not start it yet. The connector will be the
1114 initiator of the protocol thus we will wait for initiation from
1115 there before we start the protocol. */
1116 server->stat.auth_attempts++;
1117 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1118 &sock->protocol, proto_ctx,
1119 silc_server_accept_new_connection_second);
1121 /* Register a timeout task that will be executed if the connector
1122 will not start the key exchange protocol within 60 seconds. For
1123 now, this is a hard coded limit. After 60 secs the connection will
1124 be closed if the key exchange protocol has not been started. */
1125 proto_ctx->timeout_task =
1126 silc_schedule_task_add(server->schedule, sock->sock,
1127 silc_server_timeout_remote,
1133 /* Accepts new connections to the server. Accepting new connections are
1134 done in three parts to make it async. */
1136 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1138 SilcServer server = (SilcServer)context;
1139 SilcSocketConnection newsocket;
1142 SILC_LOG_DEBUG(("Accepting new connection"));
1144 server->stat.conn_attempts++;
1146 sock = silc_net_accept_connection(server->sock);
1148 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1149 server->stat.conn_failures++;
1153 /* Check max connections */
1154 if (sock > SILC_SERVER_MAX_CONNECTIONS) {
1155 SILC_LOG_ERROR(("Refusing connection, server is full"));
1156 server->stat.conn_failures++;
1160 /* Set socket options */
1161 silc_net_set_socket_nonblock(sock);
1162 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1164 /* We don't create a ID yet, since we don't know what type of connection
1165 this is yet. But, we do add the connection to the socket table. */
1166 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1167 server->sockets[sock] = newsocket;
1169 /* Perform asynchronous host lookup. This will lookup the IP and the
1170 FQDN of the remote connection. After the lookup is done the connection
1171 is accepted further. */
1172 silc_socket_host_lookup(newsocket, TRUE,
1173 silc_server_accept_new_connection_lookup, context,
1177 /* Second part of accepting new connection. Key exchange protocol has been
1178 performed and now it is time to do little connection authentication
1179 protocol to figure out whether this connection is client or server
1180 and whether it has right to access this server (especially server
1181 connections needs to be authenticated). */
1183 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1185 SilcProtocol protocol = (SilcProtocol)context;
1186 SilcServerKEInternalContext *ctx =
1187 (SilcServerKEInternalContext *)protocol->context;
1188 SilcServer server = (SilcServer)ctx->server;
1189 SilcSocketConnection sock = ctx->sock;
1190 SilcServerConnAuthInternalContext *proto_ctx;
1192 SILC_LOG_DEBUG(("Start"));
1194 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1195 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1196 /* Error occured during protocol */
1197 silc_protocol_free(protocol);
1198 sock->protocol = NULL;
1199 silc_ske_free_key_material(ctx->keymat);
1201 silc_packet_context_free(ctx->packet);
1203 silc_ske_free(ctx->ske);
1204 silc_free(ctx->dest_id);
1206 silc_schedule_task_del_by_callback(server->schedule,
1207 silc_server_failure_callback);
1208 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1209 "Key exchange failed");
1210 server->stat.auth_failures++;
1214 /* We now have the key material as the result of the key exchange
1215 protocol. Take the key material into use. Free the raw key material
1216 as soon as we've set them into use. */
1217 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1218 ctx->sock, ctx->keymat,
1219 ctx->ske->prop->cipher,
1220 ctx->ske->prop->pkcs,
1221 ctx->ske->prop->hash,
1222 ctx->ske->prop->hmac,
1223 ctx->ske->prop->group,
1225 silc_protocol_free(protocol);
1226 sock->protocol = NULL;
1227 silc_ske_free_key_material(ctx->keymat);
1229 silc_packet_context_free(ctx->packet);
1231 silc_ske_free(ctx->ske);
1232 silc_free(ctx->dest_id);
1234 silc_schedule_task_del_by_callback(server->schedule,
1235 silc_server_failure_callback);
1236 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1237 "Key exchange failed");
1238 server->stat.auth_failures++;
1241 silc_ske_free_key_material(ctx->keymat);
1243 /* Allocate internal context for the authentication protocol. This
1244 is sent as context for the protocol. */
1245 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1246 proto_ctx->server = (void *)server;
1247 proto_ctx->sock = sock;
1248 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1249 proto_ctx->responder = TRUE;
1250 proto_ctx->dest_id_type = ctx->dest_id_type;
1251 proto_ctx->dest_id = ctx->dest_id;
1252 proto_ctx->cconfig = ctx->cconfig;
1253 proto_ctx->sconfig = ctx->sconfig;
1254 proto_ctx->rconfig = ctx->rconfig;
1256 /* Free old protocol as it is finished now */
1257 silc_protocol_free(protocol);
1259 silc_packet_context_free(ctx->packet);
1261 sock->protocol = NULL;
1263 /* Allocate the authentication protocol. This is allocated here
1264 but we won't start it yet. We will be receiving party of this
1265 protocol thus we will wait that connecting party will make
1266 their first move. */
1267 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1268 &sock->protocol, proto_ctx,
1269 silc_server_accept_new_connection_final);
1271 /* Register timeout task. If the protocol is not executed inside
1272 this timelimit the connection will be terminated. Currently
1273 this is 60 seconds and is hard coded limit (XXX). */
1274 proto_ctx->timeout_task =
1275 silc_schedule_task_add(server->schedule, sock->sock,
1276 silc_server_timeout_remote,
1277 (void *)server, 60, 0,
1282 /* Final part of accepting new connection. The connection has now
1283 been authenticated and keys has been exchanged. We also know whether
1284 this is client or server connection. */
1286 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1288 SilcProtocol protocol = (SilcProtocol)context;
1289 SilcServerConnAuthInternalContext *ctx =
1290 (SilcServerConnAuthInternalContext *)protocol->context;
1291 SilcServer server = (SilcServer)ctx->server;
1292 SilcSocketConnection sock = ctx->sock;
1293 SilcServerHBContext hb_context;
1294 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1297 SILC_LOG_DEBUG(("Start"));
1299 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1300 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1301 /* Error occured during protocol */
1302 silc_protocol_free(protocol);
1303 sock->protocol = NULL;
1305 silc_packet_context_free(ctx->packet);
1307 silc_ske_free(ctx->ske);
1308 silc_free(ctx->dest_id);
1310 silc_schedule_task_del_by_callback(server->schedule,
1311 silc_server_failure_callback);
1312 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1313 "Authentication failed");
1314 server->stat.auth_failures++;
1318 entry->data.last_receive = time(NULL);
1320 switch (ctx->conn_type) {
1321 case SILC_SOCKET_TYPE_CLIENT:
1323 SilcClientEntry client;
1325 SILC_LOG_DEBUG(("Remote host is client"));
1326 SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname,
1329 /* Add the client to the client ID cache. The nickname and Client ID
1330 and other information is created after we have received NEW_CLIENT
1331 packet from client. */
1332 client = silc_idlist_add_client(server->local_list,
1333 NULL, NULL, NULL, NULL, NULL, sock, 0);
1335 SILC_LOG_ERROR(("Could not add new client to cache"));
1336 silc_free(sock->user_data);
1337 silc_server_disconnect_remote(server, sock,
1338 "Server closed connection: "
1339 "Authentication failed");
1340 server->stat.auth_failures++;
1345 server->stat.my_clients++;
1346 server->stat.clients++;
1347 if (server->server_type == SILC_ROUTER)
1348 server->stat.cell_clients++;
1350 id_entry = (void *)client;
1353 case SILC_SOCKET_TYPE_SERVER:
1354 case SILC_SOCKET_TYPE_ROUTER:
1356 SilcServerEntry new_server;
1357 /* XXX FIXME: Now server and router has different table, so this is probably broken. */
1358 SilcServerConfigSectionRouter *conn =
1359 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1360 ctx->sconfig : ctx->rconfig;
1362 SILC_LOG_DEBUG(("Remote host is %s",
1363 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1364 "server" : (conn->backup_router ?
1365 "backup router" : "router")));
1366 SILC_LOG_INFO(("Connection from %s (%s) is %s", sock->hostname,
1367 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1368 "server" : (conn->backup_router ?
1369 "backup router" : "router")));
1371 /* Add the server into server cache. The server name and Server ID
1372 is updated after we have received NEW_SERVER packet from the
1373 server. We mark ourselves as router for this server if we really
1376 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1377 server->local_list : (conn->backup_router ?
1378 server->local_list :
1379 server->global_list)),
1381 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1382 SILC_SERVER : SILC_ROUTER),
1384 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1385 server->id_entry : (conn->backup_router ?
1386 server->id_entry : NULL)),
1389 SILC_LOG_ERROR(("Could not add new server to cache"));
1390 silc_free(sock->user_data);
1391 silc_server_disconnect_remote(server, sock,
1392 "Server closed connection: "
1393 "Authentication failed");
1394 server->stat.auth_failures++;
1399 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER)
1400 server->stat.my_servers++;
1402 server->stat.my_routers++;
1403 server->stat.servers++;
1405 id_entry = (void *)new_server;
1407 /* If the incoming connection is router and marked as backup router
1408 then add it to be one of our backups */
1409 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && conn->backup_router) {
1410 silc_server_backup_add(server, new_server, conn->backup_replace_ip,
1411 conn->backup_replace_port, conn->backup_local);
1413 /* Change it back to SERVER type since that's what it really is. */
1414 if (conn->backup_local)
1415 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1417 new_server->server_type = SILC_BACKUP_ROUTER;
1420 /* Check whether this connection is to be our primary router connection
1421 if we do not already have the primary route. */
1422 if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1423 if (silc_server_config_is_primary_route(server) &&
1427 SILC_LOG_DEBUG(("We are not standalone server anymore"));
1428 server->standalone = FALSE;
1429 if (!server->id_entry->router) {
1430 server->id_entry->router = id_entry;
1431 server->router = id_entry;
1442 sock->type = ctx->conn_type;
1444 /* Add the common data structure to the ID entry. */
1445 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1447 /* Add to sockets internal pointer for fast referencing */
1448 silc_free(sock->user_data);
1449 sock->user_data = id_entry;
1451 /* Connection has been fully established now. Everything is ok. */
1452 SILC_LOG_DEBUG(("New connection authenticated"));
1454 /* Perform keepalive. The `hb_context' will be freed automatically
1455 when finally calling the silc_socket_free function. XXX hardcoded
1457 hb_context = silc_calloc(1, sizeof(*hb_context));
1458 hb_context->server = server;
1459 silc_socket_set_heartbeat(sock, 400, hb_context,
1460 silc_server_perform_heartbeat,
1464 silc_schedule_task_del_by_callback(server->schedule,
1465 silc_server_failure_callback);
1466 silc_protocol_free(protocol);
1468 silc_packet_context_free(ctx->packet);
1470 silc_ske_free(ctx->ske);
1471 silc_free(ctx->dest_id);
1473 sock->protocol = NULL;
1476 /* This function is used to read packets from network and send packets to
1477 network. This is usually a generic task. */
1479 SILC_TASK_CALLBACK(silc_server_packet_process)
1481 SilcServer server = (SilcServer)context;
1482 SilcSocketConnection sock = server->sockets[fd];
1483 SilcIDListData idata;
1484 SilcCipher cipher = NULL;
1485 SilcHmac hmac = NULL;
1486 uint32 sequence = 0;
1492 SILC_LOG_DEBUG(("Processing packet"));
1494 /* Packet sending */
1496 if (type == SILC_TASK_WRITE) {
1497 /* Do not send data to disconnected connection */
1498 if (SILC_IS_DISCONNECTED(sock))
1501 server->stat.packets_sent++;
1503 if (sock->outbuf->data - sock->outbuf->head)
1504 silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
1506 /* Send the packet */
1507 ret = silc_packet_send(sock, TRUE);
1509 /* If returned -2 could not write to connection now, will do
1515 SILC_LOG_ERROR(("Error sending packet to connection "
1516 "%s:%d [%s]", sock->hostname, sock->port,
1517 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1518 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1519 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1524 /* The packet has been sent and now it is time to set the connection
1525 back to only for input. When there is again some outgoing data
1526 available for this connection it will be set for output as well.
1527 This call clears the output setting and sets it only for input. */
1528 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1529 SILC_UNSET_OUTBUF_PENDING(sock);
1531 silc_buffer_clear(sock->outbuf);
1535 /* Packet receiving */
1537 /* Read some data from connection */
1538 ret = silc_packet_receive(sock);
1542 SILC_LOG_ERROR(("Error receiving packet from connection "
1543 "%s:%d [%s] %s", sock->hostname, sock->port,
1544 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1545 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1546 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1547 "Router"), strerror(errno)));
1553 SILC_LOG_DEBUG(("Read EOF"));
1555 /* If connection is disconnecting already we will finally
1556 close the connection */
1557 if (SILC_IS_DISCONNECTING(sock)) {
1558 if (sock->user_data)
1559 silc_server_free_sock_user_data(server, sock, NULL);
1560 silc_server_close_connection(server, sock);
1564 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1565 SILC_SET_DISCONNECTING(sock);
1567 if (sock->user_data) {
1569 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
1570 silc_server_free_sock_user_data(server, sock, tmp);
1572 silc_server_free_sock_user_data(server, sock, NULL);
1573 } else if (server->router_conn && server->router_conn->sock == sock &&
1574 !server->router && server->standalone)
1575 silc_schedule_task_add(server->schedule, 0,
1576 silc_server_connect_to_router,
1579 SILC_TASK_PRI_NORMAL);
1581 silc_server_close_connection(server, sock);
1585 /* If connection is disconnecting or disconnected we will ignore
1587 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1588 SILC_LOG_DEBUG(("Ignoring read data from disonnected connection"));
1592 server->stat.packets_received++;
1594 /* Get keys and stuff from ID entry */
1595 idata = (SilcIDListData)sock->user_data;
1597 cipher = idata->receive_key;
1598 hmac = idata->hmac_receive;
1599 sequence = idata->psn_receive;
1602 /* Process the packet. This will call the parser that will then
1603 decrypt and parse the packet. */
1604 ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1605 TRUE : FALSE, cipher, hmac, sequence,
1606 silc_server_packet_parse, server);
1608 /* If this socket connection is not authenticated yet and the packet
1609 processing failed we will drop the connection since it can be
1610 a malicious flooder. */
1611 if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
1612 (!sock->protocol || sock->protocol->protocol->type ==
1613 SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
1614 SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
1615 SILC_SET_DISCONNECTING(sock);
1617 if (sock->user_data)
1618 silc_server_free_sock_user_data(server, sock, NULL);
1619 silc_server_close_connection(server, sock);
1623 /* Parses whole packet, received earlier. */
1625 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1627 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1628 SilcServer server = (SilcServer)parse_ctx->context;
1629 SilcSocketConnection sock = parse_ctx->sock;
1630 SilcPacketContext *packet = parse_ctx->packet;
1631 SilcIDListData idata = (SilcIDListData)sock->user_data;
1634 SILC_LOG_DEBUG(("Start"));
1636 /* Parse the packet */
1637 if (parse_ctx->normal)
1638 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1640 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1642 /* If entry is disabled ignore what we got. */
1643 if (ret != SILC_PACKET_RESUME_ROUTER &&
1644 idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1645 SILC_LOG_DEBUG(("Connection is disabled"));
1649 if (ret == SILC_PACKET_NONE)
1652 /* Check that the the current client ID is same as in the client's packet. */
1653 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1654 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1655 if (client && client->id) {
1656 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1657 packet->src_id_type);
1658 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1666 if (server->server_type == SILC_ROUTER) {
1667 /* Route the packet if it is not destined to us. Other ID types but
1668 server are handled separately after processing them. */
1669 if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1670 packet->dst_id_type == SILC_ID_SERVER &&
1671 sock->type != SILC_SOCKET_TYPE_CLIENT &&
1672 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1674 /* Route the packet to fastest route for the destination ID */
1675 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1676 packet->dst_id_type);
1679 silc_server_packet_route(server,
1680 silc_server_route_get(server, id,
1681 packet->dst_id_type),
1688 /* Parse the incoming packet type */
1689 silc_server_packet_parse_type(server, sock, packet);
1691 if (server->server_type == SILC_ROUTER) {
1692 /* Broadcast packet if it is marked as broadcast packet and it is
1693 originated from router and we are router. */
1694 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1695 packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1696 !server->standalone) {
1697 /* Broadcast to our primary route */
1698 silc_server_packet_broadcast(server, server->router->connection, packet);
1700 /* If we have backup routers then we need to feed all broadcast
1701 data to those servers. */
1702 silc_server_backup_broadcast(server, sock, packet);
1707 silc_packet_context_free(packet);
1708 silc_free(parse_ctx);
1711 /* Parser callback called by silc_packet_receive_process. This merely
1712 registers timeout that will handle the actual parsing when appropriate. */
1714 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1717 SilcServer server = (SilcServer)context;
1718 SilcSocketConnection sock = parser_context->sock;
1719 SilcIDListData idata = (SilcIDListData)sock->user_data;
1722 idata->psn_receive = parser_context->packet->sequence + 1;
1724 /* If protocol for this connection is key exchange or rekey then we'll
1725 process all packets synchronously, since there might be packets in
1726 queue that we are not able to decrypt without first processing the
1727 packets before them. */
1728 if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1729 parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1730 (sock->protocol && sock->protocol->protocol &&
1731 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1732 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1733 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1736 /* Reprocess data since we'll return FALSE here. This is because
1737 the idata->receive_key might have become valid in the last packet
1738 and we want to call this processor with valid cipher. */
1740 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1741 TRUE : FALSE, idata->receive_key,
1742 idata->hmac_receive, idata->psn_receive,
1743 silc_server_packet_parse, server);
1745 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1746 TRUE : FALSE, NULL, NULL, 0,
1747 silc_server_packet_parse, server);
1751 switch (sock->type) {
1752 case SILC_SOCKET_TYPE_UNKNOWN:
1753 case SILC_SOCKET_TYPE_CLIENT:
1754 /* Parse the packet with timeout */
1755 silc_schedule_task_add(server->schedule, sock->sock,
1756 silc_server_packet_parse_real,
1757 (void *)parser_context, 0, 100000,
1759 SILC_TASK_PRI_NORMAL);
1761 case SILC_SOCKET_TYPE_SERVER:
1762 case SILC_SOCKET_TYPE_ROUTER:
1763 /* Packets from servers are parsed immediately */
1764 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1774 /* Parses the packet type and calls what ever routines the packet type
1775 requires. This is done for all incoming packets. */
1777 void silc_server_packet_parse_type(SilcServer server,
1778 SilcSocketConnection sock,
1779 SilcPacketContext *packet)
1781 SilcPacketType type = packet->type;
1782 SilcIDListData idata = (SilcIDListData)sock->user_data;
1784 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1786 /* Parse the packet type */
1788 case SILC_PACKET_DISCONNECT:
1789 SILC_LOG_DEBUG(("Disconnect packet"));
1790 if (packet->flags & SILC_PACKET_FLAG_LIST)
1794 case SILC_PACKET_SUCCESS:
1796 * Success received for something. For now we can have only
1797 * one protocol for connection executing at once hence this
1798 * success message is for whatever protocol is executing currently.
1800 SILC_LOG_DEBUG(("Success packet"));
1801 if (packet->flags & SILC_PACKET_FLAG_LIST)
1804 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1807 case SILC_PACKET_FAILURE:
1809 * Failure received for something. For now we can have only
1810 * one protocol for connection executing at once hence this
1811 * failure message is for whatever protocol is executing currently.
1813 SILC_LOG_DEBUG(("Failure packet"));
1814 if (packet->flags & SILC_PACKET_FLAG_LIST)
1816 if (sock->protocol) {
1817 SilcServerFailureContext f;
1818 f = silc_calloc(1, sizeof(*f));
1822 /* We will wait 5 seconds to process this failure packet */
1823 silc_schedule_task_add(server->schedule, sock->sock,
1824 silc_server_failure_callback, (void *)f, 5, 0,
1825 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1829 case SILC_PACKET_REJECT:
1830 SILC_LOG_DEBUG(("Reject packet"));
1831 if (packet->flags & SILC_PACKET_FLAG_LIST)
1836 case SILC_PACKET_NOTIFY:
1838 * Received notify packet. Server can receive notify packets from
1839 * router. Server then relays the notify messages to clients if needed.
1841 SILC_LOG_DEBUG(("Notify packet"));
1842 if (packet->flags & SILC_PACKET_FLAG_LIST)
1843 silc_server_notify_list(server, sock, packet);
1845 silc_server_notify(server, sock, packet);
1851 case SILC_PACKET_CHANNEL_MESSAGE:
1853 * Received channel message. Channel messages are special packets
1854 * (although probably most common ones) thus they are handled
1857 SILC_LOG_DEBUG(("Channel Message packet"));
1858 if (packet->flags & SILC_PACKET_FLAG_LIST)
1860 idata->last_receive = time(NULL);
1861 silc_server_channel_message(server, sock, packet);
1864 case SILC_PACKET_CHANNEL_KEY:
1866 * Received key for channel. As channels are created by the router
1867 * the keys are as well. We will distribute the key to all of our
1868 * locally connected clients on the particular channel. Router
1869 * never receives this channel and thus is ignored.
1871 SILC_LOG_DEBUG(("Channel Key packet"));
1872 if (packet->flags & SILC_PACKET_FLAG_LIST)
1874 silc_server_channel_key(server, sock, packet);
1880 case SILC_PACKET_COMMAND:
1882 * Recived command. Processes the command request and allocates the
1883 * command context and calls the command.
1885 SILC_LOG_DEBUG(("Command packet"));
1886 if (packet->flags & SILC_PACKET_FLAG_LIST)
1888 silc_server_command_process(server, sock, packet);
1891 case SILC_PACKET_COMMAND_REPLY:
1893 * Received command reply packet. Received command reply to command. It
1894 * may be reply to command sent by us or reply to command sent by client
1895 * that we've routed further.
1897 SILC_LOG_DEBUG(("Command Reply packet"));
1898 if (packet->flags & SILC_PACKET_FLAG_LIST)
1900 silc_server_command_reply(server, sock, packet);
1904 * Private Message packets
1906 case SILC_PACKET_PRIVATE_MESSAGE:
1908 * Received private message packet. The packet is coming from either
1911 SILC_LOG_DEBUG(("Private Message packet"));
1912 if (packet->flags & SILC_PACKET_FLAG_LIST)
1914 idata->last_receive = time(NULL);
1915 silc_server_private_message(server, sock, packet);
1918 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1920 * Private message key packet.
1922 if (packet->flags & SILC_PACKET_FLAG_LIST)
1924 silc_server_private_message_key(server, sock, packet);
1928 * Key Exchange protocol packets
1930 case SILC_PACKET_KEY_EXCHANGE:
1931 SILC_LOG_DEBUG(("KE packet"));
1932 if (packet->flags & SILC_PACKET_FLAG_LIST)
1935 if (sock->protocol && sock->protocol->protocol &&
1936 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
1938 SilcServerKEInternalContext *proto_ctx =
1939 (SilcServerKEInternalContext *)sock->protocol->context;
1941 proto_ctx->packet = silc_packet_context_dup(packet);
1943 /* Let the protocol handle the packet */
1944 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
1946 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1947 "protocol active, packet dropped."));
1951 case SILC_PACKET_KEY_EXCHANGE_1:
1952 SILC_LOG_DEBUG(("KE 1 packet"));
1953 if (packet->flags & SILC_PACKET_FLAG_LIST)
1956 if (sock->protocol && sock->protocol->protocol &&
1957 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1958 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
1960 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
1961 SilcServerRekeyInternalContext *proto_ctx =
1962 (SilcServerRekeyInternalContext *)sock->protocol->context;
1964 if (proto_ctx->packet)
1965 silc_packet_context_free(proto_ctx->packet);
1967 proto_ctx->packet = silc_packet_context_dup(packet);
1969 /* Let the protocol handle the packet */
1970 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1972 SilcServerKEInternalContext *proto_ctx =
1973 (SilcServerKEInternalContext *)sock->protocol->context;
1975 if (proto_ctx->packet)
1976 silc_packet_context_free(proto_ctx->packet);
1978 proto_ctx->packet = silc_packet_context_dup(packet);
1979 proto_ctx->dest_id_type = packet->src_id_type;
1980 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1981 packet->src_id_type);
1982 if (!proto_ctx->dest_id)
1985 /* Let the protocol handle the packet */
1986 silc_protocol_execute(sock->protocol, server->schedule,
1990 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1991 "protocol active, packet dropped."));
1995 case SILC_PACKET_KEY_EXCHANGE_2:
1996 SILC_LOG_DEBUG(("KE 2 packet"));
1997 if (packet->flags & SILC_PACKET_FLAG_LIST)
2000 if (sock->protocol && sock->protocol->protocol &&
2001 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2002 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2004 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2005 SilcServerRekeyInternalContext *proto_ctx =
2006 (SilcServerRekeyInternalContext *)sock->protocol->context;
2008 if (proto_ctx->packet)
2009 silc_packet_context_free(proto_ctx->packet);
2011 proto_ctx->packet = silc_packet_context_dup(packet);
2013 /* Let the protocol handle the packet */
2014 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2016 SilcServerKEInternalContext *proto_ctx =
2017 (SilcServerKEInternalContext *)sock->protocol->context;
2019 if (proto_ctx->packet)
2020 silc_packet_context_free(proto_ctx->packet);
2022 proto_ctx->packet = silc_packet_context_dup(packet);
2023 proto_ctx->dest_id_type = packet->src_id_type;
2024 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2025 packet->src_id_type);
2026 if (!proto_ctx->dest_id)
2029 /* Let the protocol handle the packet */
2030 silc_protocol_execute(sock->protocol, server->schedule,
2034 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2035 "protocol active, packet dropped."));
2039 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2041 * Connection authentication request packet. When we receive this packet
2042 * we will send to the other end information about our mandatory
2043 * authentication method for the connection. This packet maybe received
2046 SILC_LOG_DEBUG(("Connection authentication request packet"));
2047 if (packet->flags & SILC_PACKET_FLAG_LIST)
2049 silc_server_connection_auth_request(server, sock, packet);
2053 * Connection Authentication protocol packets
2055 case SILC_PACKET_CONNECTION_AUTH:
2056 /* Start of the authentication protocol. We receive here the
2057 authentication data and will verify it. */
2058 SILC_LOG_DEBUG(("Connection auth packet"));
2059 if (packet->flags & SILC_PACKET_FLAG_LIST)
2062 if (sock->protocol && sock->protocol->protocol->type
2063 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2065 SilcServerConnAuthInternalContext *proto_ctx =
2066 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2068 proto_ctx->packet = silc_packet_context_dup(packet);
2070 /* Let the protocol handle the packet */
2071 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2073 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2074 "protocol active, packet dropped."));
2078 case SILC_PACKET_NEW_ID:
2080 * Received New ID packet. This includes some new ID that has been
2081 * created. It may be for client, server or channel. This is the way
2082 * to distribute information about new registered entities in the
2085 SILC_LOG_DEBUG(("New ID packet"));
2086 if (packet->flags & SILC_PACKET_FLAG_LIST)
2087 silc_server_new_id_list(server, sock, packet);
2089 silc_server_new_id(server, sock, packet);
2092 case SILC_PACKET_NEW_CLIENT:
2094 * Received new client packet. This includes client information that
2095 * we will use to create initial client ID. After creating new
2096 * ID we will send it to the client.
2098 SILC_LOG_DEBUG(("New Client packet"));
2099 if (packet->flags & SILC_PACKET_FLAG_LIST)
2101 silc_server_new_client(server, sock, packet);
2104 case SILC_PACKET_NEW_SERVER:
2106 * Received new server packet. This includes Server ID and some other
2107 * information that we may save. This is received after server has
2110 SILC_LOG_DEBUG(("New Server packet"));
2111 if (packet->flags & SILC_PACKET_FLAG_LIST)
2113 silc_server_new_server(server, sock, packet);
2116 case SILC_PACKET_NEW_CHANNEL:
2118 * Received new channel packet. Information about new channel in the
2119 * network are distributed using this packet.
2121 SILC_LOG_DEBUG(("New Channel packet"));
2122 if (packet->flags & SILC_PACKET_FLAG_LIST)
2123 silc_server_new_channel_list(server, sock, packet);
2125 silc_server_new_channel(server, sock, packet);
2128 case SILC_PACKET_HEARTBEAT:
2130 * Received heartbeat.
2132 SILC_LOG_DEBUG(("Heartbeat packet"));
2133 if (packet->flags & SILC_PACKET_FLAG_LIST)
2137 case SILC_PACKET_KEY_AGREEMENT:
2139 * Received heartbeat.
2141 SILC_LOG_DEBUG(("Key agreement packet"));
2142 if (packet->flags & SILC_PACKET_FLAG_LIST)
2144 silc_server_key_agreement(server, sock, packet);
2147 case SILC_PACKET_REKEY:
2149 * Received re-key packet. The sender wants to regenerate the session
2152 SILC_LOG_DEBUG(("Re-key packet"));
2153 if (packet->flags & SILC_PACKET_FLAG_LIST)
2155 silc_server_rekey(server, sock, packet);
2158 case SILC_PACKET_REKEY_DONE:
2160 * The re-key is done.
2162 SILC_LOG_DEBUG(("Re-key done packet"));
2163 if (packet->flags & SILC_PACKET_FLAG_LIST)
2166 if (sock->protocol && sock->protocol->protocol &&
2167 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2169 SilcServerRekeyInternalContext *proto_ctx =
2170 (SilcServerRekeyInternalContext *)sock->protocol->context;
2172 if (proto_ctx->packet)
2173 silc_packet_context_free(proto_ctx->packet);
2175 proto_ctx->packet = silc_packet_context_dup(packet);
2177 /* Let the protocol handle the packet */
2178 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2180 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2181 "protocol active, packet dropped."));
2185 case SILC_PACKET_FTP:
2187 SILC_LOG_DEBUG(("FTP packet"));
2188 if (packet->flags & SILC_PACKET_FLAG_LIST)
2190 silc_server_ftp(server, sock, packet);
2193 case SILC_PACKET_RESUME_ROUTER:
2194 /* Resume router packet received. This packet is received for backup
2195 router resuming protocol. */
2196 SILC_LOG_DEBUG(("Resume router packet"));
2197 if (packet->flags & SILC_PACKET_FLAG_LIST)
2199 silc_server_backup_resume_router(server, sock, packet);
2203 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2209 /* Creates connection to a remote router. */
2211 void silc_server_create_connection(SilcServer server,
2212 const char *remote_host, uint32 port)
2214 SilcServerConnection sconn;
2216 /* Allocate connection object for hold connection specific stuff. */
2217 sconn = silc_calloc(1, sizeof(*sconn));
2218 sconn->server = server;
2219 sconn->remote_host = strdup(remote_host);
2220 sconn->remote_port = port;
2221 sconn->no_reconnect = TRUE;
2223 silc_schedule_task_add(server->schedule, 0,
2224 silc_server_connect_router,
2225 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
2226 SILC_TASK_PRI_NORMAL);
2229 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2231 silc_socket_free((SilcSocketConnection)context);
2234 /* Closes connection to socket connection */
2236 void silc_server_close_connection(SilcServer server,
2237 SilcSocketConnection sock)
2239 if (!server->sockets[sock->sock])
2242 SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2244 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2245 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2246 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2249 /* We won't listen for this connection anymore */
2250 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2252 /* Unregister all tasks */
2253 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2255 /* Close the actual connection */
2256 silc_net_close_connection(sock->sock);
2257 server->sockets[sock->sock] = NULL;
2259 /* If sock->user_data is NULL then we'll check for active protocols
2260 here since the silc_server_free_sock_user_data has not been called
2261 for this connection. */
2262 if (!sock->user_data) {
2263 /* If any protocol is active cancel its execution. It will call
2264 the final callback which will finalize the disconnection. */
2265 if (sock->protocol) {
2266 silc_protocol_cancel(sock->protocol, server->schedule);
2267 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2268 silc_protocol_execute_final(sock->protocol, server->schedule);
2269 sock->protocol = NULL;
2274 silc_schedule_task_add(server->schedule, 0,
2275 silc_server_close_connection_final,
2276 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
2277 SILC_TASK_PRI_NORMAL);
2280 /* Sends disconnect message to remote connection and disconnects the
2283 void silc_server_disconnect_remote(SilcServer server,
2284 SilcSocketConnection sock,
2285 const char *fmt, ...)
2288 unsigned char buf[4096];
2293 memset(buf, 0, sizeof(buf));
2295 vsprintf(buf, fmt, ap);
2298 SILC_LOG_DEBUG(("Disconnecting remote host"));
2300 /* Notify remote end that the conversation is over. The notify message
2301 is tried to be sent immediately. */
2302 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
2303 buf, strlen(buf), TRUE);
2305 /* Mark the connection to be disconnected */
2306 SILC_SET_DISCONNECTED(sock);
2307 silc_server_close_connection(server, sock);
2312 SilcClientEntry client;
2313 } *FreeClientInternal;
2315 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2317 FreeClientInternal i = (FreeClientInternal)context;
2319 silc_idlist_del_data(i->client);
2320 silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2324 /* Frees client data and notifies about client's signoff. */
2326 void silc_server_free_client_data(SilcServer server,
2327 SilcSocketConnection sock,
2328 SilcClientEntry client,
2330 const char *signoff)
2332 FreeClientInternal i = silc_calloc(1, sizeof(*i));
2334 /* If there is pending outgoing data for the client then purge it
2335 to the network before removing the client entry. */
2336 silc_server_packet_queue_purge(server, sock);
2341 /* Send SIGNOFF notify to routers. */
2342 if (notify && !server->standalone && server->router)
2343 silc_server_send_notify_signoff(server, server->router->connection,
2344 server->server_type == SILC_SERVER ?
2345 FALSE : TRUE, client->id, signoff);
2347 /* Remove client from all channels */
2349 silc_server_remove_from_channels(server, NULL, client,
2350 TRUE, (char *)signoff, TRUE);
2352 silc_server_remove_from_channels(server, NULL, client,
2353 FALSE, NULL, FALSE);
2355 /* Update statistics */
2356 server->stat.my_clients--;
2357 server->stat.clients--;
2358 if (server->server_type == SILC_ROUTER)
2359 server->stat.cell_clients--;
2360 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2361 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2363 /* We will not delete the client entry right away. We will take it
2364 into history (for WHOWAS command) for 5 minutes */
2367 silc_schedule_task_add(server->schedule, 0,
2368 silc_server_free_client_data_timeout,
2370 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2371 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2372 client->router = NULL;
2373 client->connection = NULL;
2377 /* Frees user_data pointer from socket connection object. This also sends
2378 appropriate notify packets to the network to inform about leaving
2381 void silc_server_free_sock_user_data(SilcServer server,
2382 SilcSocketConnection sock,
2383 const char *signoff_message)
2385 SILC_LOG_DEBUG(("Start"));
2387 switch (sock->type) {
2388 case SILC_SOCKET_TYPE_CLIENT:
2390 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2391 silc_server_free_client_data(server, sock, user_data, TRUE,
2395 case SILC_SOCKET_TYPE_SERVER:
2396 case SILC_SOCKET_TYPE_ROUTER:
2398 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2399 SilcServerEntry backup_router = NULL;
2402 backup_router = silc_server_backup_get(server, user_data->id);
2404 /* If this was our primary router connection then we're lost to
2405 the outside world. */
2406 if (server->router == user_data) {
2407 /* Check whether we have a backup router connection */
2408 if (!backup_router || backup_router == user_data) {
2409 silc_schedule_task_add(server->schedule, 0,
2410 silc_server_connect_to_router,
2413 SILC_TASK_PRI_NORMAL);
2415 server->id_entry->router = NULL;
2416 server->router = NULL;
2417 server->standalone = TRUE;
2418 backup_router = NULL;
2420 SILC_LOG_INFO(("New primary router is backup router %s",
2421 backup_router->server_name));
2422 SILC_LOG_DEBUG(("New primary router is backup router %s",
2423 backup_router->server_name));
2424 server->id_entry->router = backup_router;
2425 server->router = backup_router;
2426 server->router_connect = time(0);
2427 server->backup_primary = TRUE;
2428 if (server->server_type == SILC_BACKUP_ROUTER) {
2429 server->server_type = SILC_ROUTER;
2431 /* We'll need to constantly try to reconnect to the primary
2432 router so that we'll see when it comes back online. */
2433 silc_server_backup_reconnect(server, sock->ip, sock->port,
2434 silc_server_backup_connected,
2438 /* Mark this connection as replaced */
2439 silc_server_backup_replaced_add(server, user_data->id,
2442 } else if (backup_router) {
2443 SILC_LOG_INFO(("Enabling the use of backup router %s",
2444 backup_router->server_name));
2445 SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2446 backup_router->server_name));
2448 /* Mark this connection as replaced */
2449 silc_server_backup_replaced_add(server, user_data->id,
2453 if (!backup_router) {
2454 /* Free all client entries that this server owns as they will
2455 become invalid now as well. */
2457 silc_server_remove_clients_by_server(server, user_data, TRUE);
2458 if (server->server_type == SILC_SERVER)
2459 silc_server_remove_channels_by_server(server, user_data);
2461 /* Update the client entries of this server to the new backup
2462 router. This also removes the clients that *really* was owned
2463 by the primary router and went down with the router. */
2464 silc_server_update_clients_by_server(server, user_data, backup_router,
2466 silc_server_update_servers_by_server(server, user_data, backup_router);
2467 if (server->server_type == SILC_SERVER)
2468 silc_server_update_channels_by_server(server, user_data,
2472 /* Free the server entry */
2473 silc_server_backup_del(server, user_data);
2474 silc_server_backup_replaced_del(server, user_data);
2475 silc_idlist_del_data(user_data);
2476 if (!silc_idlist_del_server(server->local_list, user_data))
2477 silc_idlist_del_server(server->global_list, user_data);
2478 server->stat.my_servers--;
2479 server->stat.servers--;
2480 if (server->server_type == SILC_ROUTER)
2481 server->stat.cell_servers--;
2483 if (backup_router) {
2484 /* Announce all of our stuff that was created about 5 minutes ago.
2485 The backup router knows all the other stuff already. */
2486 if (server->server_type == SILC_ROUTER)
2487 silc_server_announce_servers(server, FALSE, time(0) - 300,
2488 backup_router->connection);
2490 /* Announce our clients and channels to the router */
2491 silc_server_announce_clients(server, time(0) - 300,
2492 backup_router->connection);
2493 silc_server_announce_channels(server, time(0) - 300,
2494 backup_router->connection);
2500 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2502 silc_idlist_del_data(user_data);
2503 silc_free(user_data);
2508 /* If any protocol is active cancel its execution */
2509 if (sock->protocol) {
2510 silc_protocol_cancel(sock->protocol, server->schedule);
2511 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2512 silc_protocol_execute_final(sock->protocol, server->schedule);
2513 sock->protocol = NULL;
2516 sock->user_data = NULL;
2519 /* Removes client from all channels it has joined. This is used when client
2520 connection is disconnected. If the client on a channel is last, the
2521 channel is removed as well. This sends the SIGNOFF notify types. */
2523 void silc_server_remove_from_channels(SilcServer server,
2524 SilcSocketConnection sock,
2525 SilcClientEntry client,
2527 char *signoff_message,
2530 SilcChannelEntry channel;
2531 SilcChannelClientEntry chl;
2532 SilcHashTableList htl;
2535 SILC_LOG_DEBUG(("Start"));
2537 if (!client || !client->id)
2540 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2542 /* Remove the client from all channels. The client is removed from
2543 the channels' user list. */
2544 silc_hash_table_list(client->channels, &htl);
2545 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2546 channel = chl->channel;
2548 /* Remove channel from client's channel list */
2549 silc_hash_table_del(client->channels, channel);
2551 /* Remove channel if there is no users anymore */
2552 if (server->server_type == SILC_ROUTER &&
2553 silc_hash_table_count(channel->user_list) < 2) {
2555 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2556 if (silc_idlist_del_channel(server->local_list, channel))
2557 server->stat.my_channels--;
2559 silc_idlist_del_channel(server->global_list, channel);
2563 /* Remove client from channel's client list */
2564 silc_hash_table_del(channel->user_list, chl->client);
2566 /* If there is no global users on the channel anymore mark the channel
2567 as local channel. Do not check if the removed client is local client. */
2568 if (server->server_type != SILC_ROUTER && channel->global_users &&
2569 chl->client->router && !silc_server_channel_has_global(channel))
2570 channel->global_users = FALSE;
2573 server->stat.my_chanclients--;
2575 /* If there is not at least one local user on the channel then we don't
2576 need the channel entry anymore, we can remove it safely. */
2577 if (server->server_type != SILC_ROUTER &&
2578 !silc_server_channel_has_local(channel)) {
2579 /* Notify about leaving client if this channel has global users. */
2580 if (notify && channel->global_users)
2581 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2582 SILC_NOTIFY_TYPE_SIGNOFF,
2583 signoff_message ? 2 : 1,
2584 clidp->data, clidp->len,
2585 signoff_message, signoff_message ?
2586 strlen(signoff_message) : 0);
2589 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2591 if (channel->founder_key) {
2592 /* The founder auth data exists, do not remove the channel entry */
2593 SilcChannelClientEntry chl2;
2594 SilcHashTableList htl2;
2596 channel->disabled = TRUE;
2598 silc_hash_table_list(channel->user_list, &htl2);
2599 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2600 silc_hash_table_del(chl2->client->channels, channel);
2601 silc_hash_table_del(channel->user_list, chl2->client);
2604 silc_hash_table_list_reset(&htl2);
2608 /* Remove the channel entry */
2609 if (silc_idlist_del_channel(server->local_list, channel))
2610 server->stat.my_channels--;
2612 silc_idlist_del_channel(server->global_list, channel);
2616 /* Send notify to channel about client leaving SILC and thus
2617 the entire channel. */
2619 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2620 SILC_NOTIFY_TYPE_SIGNOFF,
2621 signoff_message ? 2 : 1,
2622 clidp->data, clidp->len,
2623 signoff_message, signoff_message ?
2624 strlen(signoff_message) : 0);
2626 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2627 /* Re-generate channel key */
2628 if (!silc_server_create_channel_key(server, channel, 0))
2631 /* Send the channel key to the channel. The key of course is not sent
2632 to the client who was removed from the channel. */
2633 silc_server_send_channel_key(server, client->connection, channel,
2634 server->server_type == SILC_ROUTER ?
2635 FALSE : !server->standalone);
2640 silc_hash_table_list_reset(&htl);
2641 silc_buffer_free(clidp);
2644 /* Removes client from one channel. This is used for example when client
2645 calls LEAVE command to remove itself from the channel. Returns TRUE
2646 if channel still exists and FALSE if the channel is removed when
2647 last client leaves the channel. If `notify' is FALSE notify messages
2650 int silc_server_remove_from_one_channel(SilcServer server,
2651 SilcSocketConnection sock,
2652 SilcChannelEntry channel,
2653 SilcClientEntry client,
2656 SilcChannelClientEntry chl;
2659 SILC_LOG_DEBUG(("Start"));
2661 /* Get the entry to the channel, if this client is not on the channel
2663 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2666 /* Remove the client from the channel. The client is removed from
2667 the channel's user list. */
2669 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2671 /* Remove channel from client's channel list */
2672 silc_hash_table_del(client->channels, chl->channel);
2674 /* Remove channel if there is no users anymore */
2675 if (server->server_type == SILC_ROUTER &&
2676 silc_hash_table_count(channel->user_list) < 2) {
2678 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2679 if (silc_idlist_del_channel(server->local_list, channel))
2680 server->stat.my_channels--;
2682 silc_idlist_del_channel(server->global_list, channel);
2683 silc_buffer_free(clidp);
2687 /* Remove client from channel's client list */
2688 silc_hash_table_del(channel->user_list, chl->client);
2690 /* If there is no global users on the channel anymore mark the channel
2691 as local channel. Do not check if the client is local client. */
2692 if (server->server_type != SILC_ROUTER && channel->global_users &&
2693 chl->client->router && !silc_server_channel_has_global(channel))
2694 channel->global_users = FALSE;
2697 server->stat.my_chanclients--;
2699 /* If there is not at least one local user on the channel then we don't
2700 need the channel entry anymore, we can remove it safely. */
2701 if (server->server_type != SILC_ROUTER &&
2702 !silc_server_channel_has_local(channel)) {
2703 /* Notify about leaving client if this channel has global users. */
2704 if (notify && channel->global_users)
2705 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2706 SILC_NOTIFY_TYPE_LEAVE, 1,
2707 clidp->data, clidp->len);
2709 silc_buffer_free(clidp);
2712 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2714 if (channel->founder_key) {
2715 /* The founder auth data exists, do not remove the channel entry */
2716 SilcChannelClientEntry chl2;
2717 SilcHashTableList htl2;
2719 channel->disabled = TRUE;
2721 silc_hash_table_list(channel->user_list, &htl2);
2722 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2723 silc_hash_table_del(chl2->client->channels, channel);
2724 silc_hash_table_del(channel->user_list, chl2->client);
2727 silc_hash_table_list_reset(&htl2);
2731 /* Remove the channel entry */
2732 if (silc_idlist_del_channel(server->local_list, channel))
2733 server->stat.my_channels--;
2735 silc_idlist_del_channel(server->global_list, channel);
2739 /* Send notify to channel about client leaving the channel */
2741 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2742 SILC_NOTIFY_TYPE_LEAVE, 1,
2743 clidp->data, clidp->len);
2745 silc_buffer_free(clidp);
2749 /* Timeout callback. This is called if connection is idle or for some
2750 other reason is not responding within some period of time. This
2751 disconnects the remote end. */
2753 SILC_TASK_CALLBACK(silc_server_timeout_remote)
2755 SilcServer server = (SilcServer)context;
2756 SilcSocketConnection sock = server->sockets[fd];
2758 SILC_LOG_DEBUG(("Start"));
2763 /* If we have protocol active we must assure that we call the protocol's
2764 final callback so that all the memory is freed. */
2765 if (sock->protocol) {
2766 silc_protocol_cancel(sock->protocol, server->schedule);
2767 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2768 silc_protocol_execute_final(sock->protocol, server->schedule);
2769 sock->protocol = NULL;
2773 if (sock->user_data)
2774 silc_server_free_sock_user_data(server, sock, NULL);
2776 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2777 "Connection timeout");
2780 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
2781 function may be used only by router. In real SILC network all channels
2782 are created by routers thus this function is never used by normal
2785 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
2786 SilcServerID *router_id,
2792 SilcChannelID *channel_id;
2793 SilcChannelEntry entry;
2797 SILC_LOG_DEBUG(("Creating new channel"));
2800 cipher = SILC_DEFAULT_CIPHER;
2802 hmac = SILC_DEFAULT_HMAC;
2804 /* Allocate cipher */
2805 if (!silc_cipher_alloc(cipher, &key))
2809 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2810 silc_cipher_free(key);
2814 channel_name = strdup(channel_name);
2816 /* Create the channel ID */
2817 if (!silc_id_create_channel_id(server, router_id, server->rng,
2819 silc_free(channel_name);
2820 silc_cipher_free(key);
2821 silc_hmac_free(newhmac);
2825 /* Create the channel */
2826 entry = silc_idlist_add_channel(server->local_list, channel_name,
2827 SILC_CHANNEL_MODE_NONE, channel_id,
2828 NULL, key, newhmac, 0);
2830 silc_free(channel_name);
2831 silc_cipher_free(key);
2832 silc_hmac_free(newhmac);
2833 silc_free(channel_id);
2837 entry->cipher = strdup(cipher);
2838 entry->hmac_name = strdup(hmac);
2840 /* Now create the actual key material */
2841 if (!silc_server_create_channel_key(server, entry,
2842 silc_cipher_get_key_len(key) / 8)) {
2843 silc_idlist_del_channel(server->local_list, entry);
2847 /* Notify other routers about the new channel. We send the packet
2848 to our primary route. */
2849 if (broadcast && server->standalone == FALSE)
2850 silc_server_send_new_channel(server, server->router->connection, TRUE,
2851 channel_name, entry->id,
2852 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2855 server->stat.my_channels++;
2860 /* Same as above but creates the channel with Channel ID `channel_id. */
2863 silc_server_create_new_channel_with_id(SilcServer server,
2867 SilcChannelID *channel_id,
2870 SilcChannelEntry entry;
2874 SILC_LOG_DEBUG(("Creating new channel"));
2877 cipher = SILC_DEFAULT_CIPHER;
2879 hmac = SILC_DEFAULT_HMAC;
2881 /* Allocate cipher */
2882 if (!silc_cipher_alloc(cipher, &key))
2886 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2887 silc_cipher_free(key);
2891 channel_name = strdup(channel_name);
2893 /* Create the channel */
2894 entry = silc_idlist_add_channel(server->local_list, channel_name,
2895 SILC_CHANNEL_MODE_NONE, channel_id,
2896 NULL, key, newhmac, 0);
2898 silc_cipher_free(key);
2899 silc_hmac_free(newhmac);
2900 silc_free(channel_name);
2904 /* Now create the actual key material */
2905 if (!silc_server_create_channel_key(server, entry,
2906 silc_cipher_get_key_len(key) / 8)) {
2907 silc_idlist_del_channel(server->local_list, entry);
2911 /* Notify other routers about the new channel. We send the packet
2912 to our primary route. */
2913 if (broadcast && server->standalone == FALSE)
2914 silc_server_send_new_channel(server, server->router->connection, TRUE,
2915 channel_name, entry->id,
2916 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2919 server->stat.my_channels++;
2924 /* Channel's key re-key timeout callback. */
2926 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
2928 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
2929 SilcServer server = (SilcServer)rekey->context;
2933 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
2936 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
2939 /* Generates new channel key. This is used to create the initial channel key
2940 but also to re-generate new key for channel. If `key_len' is provided
2941 it is the bytes of the key length. */
2943 bool silc_server_create_channel_key(SilcServer server,
2944 SilcChannelEntry channel,
2948 unsigned char channel_key[32], hash[32];
2951 SILC_LOG_DEBUG(("Generating channel key"));
2953 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2954 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
2958 if (!channel->channel_key)
2959 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
2960 channel->channel_key = NULL;
2966 else if (channel->key_len)
2967 len = channel->key_len / 8;
2969 len = silc_cipher_get_key_len(channel->channel_key) / 8;
2971 /* Create channel key */
2972 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
2975 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
2977 /* Remove old key if exists */
2979 memset(channel->key, 0, channel->key_len / 8);
2980 silc_free(channel->key);
2984 channel->key_len = len * 8;
2985 channel->key = silc_calloc(len, sizeof(*channel->key));
2986 memcpy(channel->key, channel_key, len);
2987 memset(channel_key, 0, sizeof(channel_key));
2989 /* Generate HMAC key from the channel key data and set it */
2991 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
2992 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
2993 silc_hmac_set_key(channel->hmac, hash,
2994 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
2995 memset(hash, 0, sizeof(hash));
2997 if (server->server_type == SILC_ROUTER) {
2998 if (!channel->rekey)
2999 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3000 channel->rekey->context = (void *)server;
3001 channel->rekey->channel = channel;
3002 channel->rekey->key_len = key_len;
3003 if (channel->rekey->task)
3004 silc_schedule_task_del(server->schedule, channel->rekey->task);
3006 channel->rekey->task =
3007 silc_schedule_task_add(server->schedule, 0,
3008 silc_server_channel_key_rekey,
3009 (void *)channel->rekey, 3600, 0,
3011 SILC_TASK_PRI_NORMAL);
3017 /* Saves the channel key found in the encoded `key_payload' buffer. This
3018 function is used when we receive Channel Key Payload and also when we're
3019 processing JOIN command reply. Returns entry to the channel. */
3021 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3022 SilcBuffer key_payload,
3023 SilcChannelEntry channel)
3025 SilcChannelKeyPayload payload = NULL;
3026 SilcChannelID *id = NULL;
3027 unsigned char *tmp, hash[32];
3031 SILC_LOG_DEBUG(("Start"));
3033 /* Decode channel key payload */
3034 payload = silc_channel_key_payload_parse(key_payload->data,
3037 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3042 /* Get the channel entry */
3045 /* Get channel ID */
3046 tmp = silc_channel_key_get_id(payload, &tmp_len);
3047 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
3053 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
3055 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
3057 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3058 silc_id_render(id, SILC_ID_CHANNEL)));
3064 tmp = silc_channel_key_get_key(payload, &tmp_len);
3070 cipher = silc_channel_key_get_cipher(payload, NULL);
3076 /* Remove old key if exists */
3078 memset(channel->key, 0, channel->key_len / 8);
3079 silc_free(channel->key);
3080 silc_cipher_free(channel->channel_key);
3083 /* Create new cipher */
3084 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3085 channel->channel_key = NULL;
3090 if (channel->cipher)
3091 silc_free(channel->cipher);
3092 channel->cipher = strdup(cipher);
3095 channel->key_len = tmp_len * 8;
3096 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
3097 memcpy(channel->key, tmp, tmp_len);
3098 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3100 /* Generate HMAC key from the channel key data and set it */
3102 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3103 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3104 silc_hmac_set_key(channel->hmac, hash,
3105 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3107 memset(hash, 0, sizeof(hash));
3108 memset(tmp, 0, tmp_len);
3110 if (server->server_type == SILC_ROUTER) {
3111 if (!channel->rekey)
3112 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3113 channel->rekey->context = (void *)server;
3114 channel->rekey->channel = channel;
3115 if (channel->rekey->task)
3116 silc_schedule_task_del(server->schedule, channel->rekey->task);
3118 channel->rekey->task =
3119 silc_schedule_task_add(server->schedule, 0,
3120 silc_server_channel_key_rekey,
3121 (void *)channel->rekey, 3600, 0,
3123 SILC_TASK_PRI_NORMAL);
3129 silc_channel_key_payload_free(payload);
3134 /* Heartbeat callback. This function is set as argument for the
3135 silc_socket_set_heartbeat function. The library will call this function
3136 at the set time interval. */
3138 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3141 SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3143 SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
3145 /* Send the heartbeat */
3146 silc_server_send_heartbeat(hb->server, sock);
3149 /* Returns assembled of all servers in the given ID list. The packet's
3150 form is dictated by the New ID payload. */
3152 static void silc_server_announce_get_servers(SilcServer server,
3153 SilcServerEntry remote,
3155 SilcBuffer *servers,
3156 unsigned long creation_time)
3158 SilcIDCacheList list;
3159 SilcIDCacheEntry id_cache;
3160 SilcServerEntry entry;
3163 /* Go through all clients in the list */
3164 if (silc_idcache_get_all(id_list->servers, &list)) {
3165 if (silc_idcache_list_first(list, &id_cache)) {
3167 entry = (SilcServerEntry)id_cache->context;
3169 /* Do not announce the one we've sending our announcements and
3170 do not announce ourself. Also check the creation time if it's
3172 if ((entry == remote) || (entry == server->id_entry) ||
3173 (creation_time && entry->data.created < creation_time)) {
3174 if (!silc_idcache_list_next(list, &id_cache))
3179 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3181 *servers = silc_buffer_realloc(*servers,
3183 (*servers)->truelen + idp->len :
3185 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3186 silc_buffer_put(*servers, idp->data, idp->len);
3187 silc_buffer_pull(*servers, idp->len);
3188 silc_buffer_free(idp);
3190 if (!silc_idcache_list_next(list, &id_cache))
3195 silc_idcache_list_free(list);
3200 silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
3206 p = silc_notify_payload_encode(notify, argc, ap);
3212 /* This function is used by router to announce existing servers to our
3213 primary router when we've connected to it. If `creation_time' is non-zero
3214 then only the servers that has been created after the `creation_time'
3215 will be announced. */
3217 void silc_server_announce_servers(SilcServer server, bool global,
3218 unsigned long creation_time,
3219 SilcSocketConnection remote)
3221 SilcBuffer servers = NULL;
3223 SILC_LOG_DEBUG(("Announcing servers"));
3225 /* Get servers in local list */
3226 silc_server_announce_get_servers(server, remote->user_data,
3227 server->local_list, &servers,
3231 /* Get servers in global list */
3232 silc_server_announce_get_servers(server, remote->user_data,
3233 server->global_list, &servers,
3237 silc_buffer_push(servers, servers->data - servers->head);
3238 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3240 /* Send the packet */
3241 silc_server_packet_send(server, remote,
3242 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3243 servers->data, servers->len, TRUE);
3245 silc_buffer_free(servers);
3249 /* Returns assembled packet of all clients in the given ID list. The
3250 packet's form is dictated by the New ID Payload. */
3252 static void silc_server_announce_get_clients(SilcServer server,
3254 SilcBuffer *clients,
3256 unsigned long creation_time)
3258 SilcIDCacheList list;
3259 SilcIDCacheEntry id_cache;
3260 SilcClientEntry client;
3263 unsigned char mode[4];
3265 /* Go through all clients in the list */
3266 if (silc_idcache_get_all(id_list->clients, &list)) {
3267 if (silc_idcache_list_first(list, &id_cache)) {
3269 client = (SilcClientEntry)id_cache->context;
3271 if (creation_time && client->data.created < creation_time) {
3272 if (!silc_idcache_list_next(list, &id_cache))
3277 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3279 *clients = silc_buffer_realloc(*clients,
3281 (*clients)->truelen + idp->len :
3283 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3284 silc_buffer_put(*clients, idp->data, idp->len);
3285 silc_buffer_pull(*clients, idp->len);
3287 SILC_PUT32_MSB(client->mode, mode);
3288 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3289 2, idp->data, idp->len,
3291 *umodes = silc_buffer_realloc(*umodes,
3293 (*umodes)->truelen + tmp->len :
3295 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3296 silc_buffer_put(*umodes, tmp->data, tmp->len);
3297 silc_buffer_pull(*umodes, tmp->len);
3298 silc_buffer_free(tmp);
3300 silc_buffer_free(idp);
3302 if (!silc_idcache_list_next(list, &id_cache))
3307 silc_idcache_list_free(list);
3311 /* This function is used to announce our existing clients to our router
3312 when we've connected to it. If `creation_time' is non-zero then only
3313 the clients that has been created after the `creation_time' will be
3316 void silc_server_announce_clients(SilcServer server,
3317 unsigned long creation_time,
3318 SilcSocketConnection remote)
3320 SilcBuffer clients = NULL;
3321 SilcBuffer umodes = NULL;
3323 SILC_LOG_DEBUG(("Announcing clients"));
3325 /* Get clients in local list */
3326 silc_server_announce_get_clients(server, server->local_list,
3327 &clients, &umodes, creation_time);
3329 /* As router we announce our global list as well */
3330 if (server->server_type == SILC_ROUTER)
3331 silc_server_announce_get_clients(server, server->global_list,
3332 &clients, &umodes, creation_time);
3335 silc_buffer_push(clients, clients->data - clients->head);
3336 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3338 /* Send the packet */
3339 silc_server_packet_send(server, remote,
3340 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3341 clients->data, clients->len, TRUE);
3343 silc_buffer_free(clients);
3347 silc_buffer_push(umodes, umodes->data - umodes->head);
3348 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
3350 /* Send the packet */
3351 silc_server_packet_send(server, remote,
3352 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3353 umodes->data, umodes->len, TRUE);
3355 silc_buffer_free(umodes);
3359 /* Returns channel's topic for announcing it */
3361 void silc_server_announce_get_channel_topic(SilcServer server,
3362 SilcChannelEntry channel,
3367 if (channel->topic) {
3368 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3369 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3370 chidp->data, chidp->len,
3372 strlen(channel->topic));
3373 silc_buffer_free(chidp);
3377 /* Returns assembled packets for channel users of the `channel'. */
3379 void silc_server_announce_get_channel_users(SilcServer server,
3380 SilcChannelEntry channel,
3381 SilcBuffer *channel_users,
3382 SilcBuffer *channel_users_modes)
3384 SilcChannelClientEntry chl;
3385 SilcHashTableList htl;
3386 SilcBuffer chidp, clidp;
3389 unsigned char mode[4];
3391 SILC_LOG_DEBUG(("Start"));
3393 /* Now find all users on the channel */
3394 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3395 silc_hash_table_list(channel->user_list, &htl);
3396 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3397 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3400 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
3401 clidp->data, clidp->len,
3402 chidp->data, chidp->len);
3405 silc_buffer_realloc(*channel_users,
3407 (*channel_users)->truelen + len : len));
3408 silc_buffer_pull_tail(*channel_users,
3409 ((*channel_users)->end -
3410 (*channel_users)->data));
3412 silc_buffer_put(*channel_users, tmp->data, tmp->len);
3413 silc_buffer_pull(*channel_users, len);
3414 silc_buffer_free(tmp);
3416 /* CUMODE notify for mode change on the channel */
3417 SILC_PUT32_MSB(chl->mode, mode);
3418 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
3419 3, clidp->data, clidp->len,
3421 clidp->data, clidp->len);
3423 *channel_users_modes =
3424 silc_buffer_realloc(*channel_users_modes,
3425 (*channel_users_modes ?
3426 (*channel_users_modes)->truelen + len : len));
3427 silc_buffer_pull_tail(*channel_users_modes,
3428 ((*channel_users_modes)->end -
3429 (*channel_users_modes)->data));
3431 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3432 silc_buffer_pull(*channel_users_modes, len);
3433 silc_buffer_free(tmp);
3435 silc_buffer_free(clidp);
3437 silc_hash_table_list_reset(&htl);
3438 silc_buffer_free(chidp);
3441 /* Returns assembled packets for all channels and users on those channels
3442 from the given ID List. The packets are in the form dictated by the
3443 New Channel and New Channel User payloads. */
3445 void silc_server_announce_get_channels(SilcServer server,
3447 SilcBuffer *channels,
3448 SilcBuffer *channel_users,
3449 SilcBuffer **channel_users_modes,
3450 uint32 *channel_users_modes_c,
3451 SilcBuffer **channel_topics,
3452 SilcChannelID ***channel_ids,
3453 unsigned long creation_time)
3455 SilcIDCacheList list;
3456 SilcIDCacheEntry id_cache;
3457 SilcChannelEntry channel;
3462 int i = *channel_users_modes_c;
3465 SILC_LOG_DEBUG(("Start"));
3467 /* Go through all channels in the list */
3468 if (silc_idcache_get_all(id_list->channels, &list)) {
3469 if (silc_idcache_list_first(list, &id_cache)) {
3471 channel = (SilcChannelEntry)id_cache->context;
3473 if (creation_time && channel->created < creation_time)
3478 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3479 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3480 name_len = strlen(channel->channel_name);
3483 len = 4 + name_len + id_len + 4;
3485 silc_buffer_realloc(*channels,
3486 (*channels ? (*channels)->truelen +
3488 silc_buffer_pull_tail(*channels,
3489 ((*channels)->end - (*channels)->data));
3490 silc_buffer_format(*channels,
3491 SILC_STR_UI_SHORT(name_len),
3492 SILC_STR_UI_XNSTRING(channel->channel_name,
3494 SILC_STR_UI_SHORT(id_len),
3495 SILC_STR_UI_XNSTRING(cid, id_len),
3496 SILC_STR_UI_INT(channel->mode),
3498 silc_buffer_pull(*channels, len);
3501 /* Channel user modes */
3502 *channel_users_modes = silc_realloc(*channel_users_modes,
3503 sizeof(**channel_users_modes) *
3505 (*channel_users_modes)[i] = NULL;
3506 *channel_ids = silc_realloc(*channel_ids,
3507 sizeof(**channel_ids) * (i + 1));
3508 (*channel_ids)[i] = NULL;
3509 silc_server_announce_get_channel_users(server, channel,
3511 &(*channel_users_modes)[i]);
3512 (*channel_ids)[i] = channel->id;
3514 /* Channel's topic */
3515 *channel_topics = silc_realloc(*channel_topics,
3516 sizeof(**channel_topics) * (i + 1));
3517 (*channel_topics)[i] = NULL;
3518 silc_server_announce_get_channel_topic(server, channel,
3519 &(*channel_topics)[i]);
3522 if (!silc_idcache_list_next(list, &id_cache))
3526 *channel_users_modes_c += i;
3529 silc_idcache_list_free(list);
3533 /* This function is used to announce our existing channels to our router
3534 when we've connected to it. This also announces the users on the
3535 channels to the router. If the `creation_time' is non-zero only the
3536 channels that was created after the `creation_time' are announced.
3537 Note that the channel users are still announced even if the `creation_time'
3540 void silc_server_announce_channels(SilcServer server,
3541 unsigned long creation_time,
3542 SilcSocketConnection remote)
3544 SilcBuffer channels = NULL, channel_users = NULL;
3545 SilcBuffer *channel_users_modes = NULL;
3546 SilcBuffer *channel_topics = NULL;
3547 uint32 channel_users_modes_c = 0;
3548 SilcChannelID **channel_ids = NULL;
3550 SILC_LOG_DEBUG(("Announcing channels and channel users"));
3552 /* Get channels and channel users in local list */
3553 silc_server_announce_get_channels(server, server->local_list,
3554 &channels, &channel_users,
3555 &channel_users_modes,
3556 &channel_users_modes_c,
3558 &channel_ids, creation_time);
3560 /* Get channels and channel users in global list */
3561 if (server->server_type != SILC_SERVER)
3562 silc_server_announce_get_channels(server, server->global_list,
3563 &channels, &channel_users,
3564 &channel_users_modes,
3565 &channel_users_modes_c,
3567 &channel_ids, creation_time);
3570 silc_buffer_push(channels, channels->data - channels->head);
3571 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3573 /* Send the packet */
3574 silc_server_packet_send(server, remote,
3575 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3576 channels->data, channels->len,
3579 silc_buffer_free(channels);
3582 if (channel_users) {
3583 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3584 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
3585 channel_users->len);
3587 /* Send the packet */
3588 silc_server_packet_send(server, remote,
3589 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3590 channel_users->data, channel_users->len,
3593 silc_buffer_free(channel_users);
3596 if (channel_users_modes) {
3599 for (i = 0; i < channel_users_modes_c; i++) {
3600 if (!channel_users_modes[i])
3602 silc_buffer_push(channel_users_modes[i],
3603 channel_users_modes[i]->data -
3604 channel_users_modes[i]->head);
3605 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
3606 channel_users_modes[i]->len);
3607 silc_server_packet_send_dest(server, remote,
3608 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3609 channel_ids[i], SILC_ID_CHANNEL,
3610 channel_users_modes[i]->data,
3611 channel_users_modes[i]->len,
3613 silc_buffer_free(channel_users_modes[i]);
3615 silc_free(channel_users_modes);
3618 if (channel_topics) {
3621 for (i = 0; i < channel_users_modes_c; i++) {
3622 if (!channel_topics[i])
3625 silc_buffer_push(channel_topics[i],
3626 channel_topics[i]->data -
3627 channel_topics[i]->head);
3628 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
3629 channel_topics[i]->len);
3630 silc_server_packet_send_dest(server, remote,
3631 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3632 channel_ids[i], SILC_ID_CHANNEL,
3633 channel_topics[i]->data,
3634 channel_topics[i]->len,
3636 silc_buffer_free(channel_topics[i]);
3638 silc_free(channel_topics);
3641 silc_free(channel_ids);
3644 /* Failure timeout callback. If this is called then we will immediately
3645 process the received failure. We always process the failure with timeout
3646 since we do not want to blindly trust to received failure packets.
3647 This won't be called (the timeout is cancelled) if the failure was
3648 bogus (it is bogus if remote does not close the connection after sending
3651 SILC_TASK_CALLBACK(silc_server_failure_callback)
3653 SilcServerFailureContext f = (SilcServerFailureContext)context;
3655 if (f->sock->protocol) {
3656 f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
3657 silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
3663 /* Assembles user list and users mode list from the `channel'. */
3665 void silc_server_get_users_on_channel(SilcServer server,
3666 SilcChannelEntry channel,
3667 SilcBuffer *user_list,
3668 SilcBuffer *mode_list,
3671 SilcChannelClientEntry chl;
3672 SilcHashTableList htl;
3673 SilcBuffer client_id_list;
3674 SilcBuffer client_mode_list;
3676 uint32 list_count = 0, len = 0;
3678 silc_hash_table_list(channel->user_list, &htl);
3679 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
3680 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
3681 silc_hash_table_list_reset(&htl);
3683 client_id_list = silc_buffer_alloc(len);
3685 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
3686 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
3687 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
3689 silc_hash_table_list(channel->user_list, &htl);
3690 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3692 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3693 silc_buffer_put(client_id_list, idp->data, idp->len);
3694 silc_buffer_pull(client_id_list, idp->len);
3695 silc_buffer_free(idp);
3697 /* Client's mode on channel */
3698 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
3699 silc_buffer_pull(client_mode_list, 4);
3703 silc_hash_table_list_reset(&htl);
3704 silc_buffer_push(client_id_list,
3705 client_id_list->data - client_id_list->head);
3706 silc_buffer_push(client_mode_list,
3707 client_mode_list->data - client_mode_list->head);
3709 *user_list = client_id_list;
3710 *mode_list = client_mode_list;
3711 *user_count = list_count;
3714 /* Saves users and their modes to the `channel'. */
3716 void silc_server_save_users_on_channel(SilcServer server,
3717 SilcSocketConnection sock,
3718 SilcChannelEntry channel,
3719 SilcClientID *noadd,
3720 SilcBuffer user_list,
3721 SilcBuffer mode_list,
3727 SilcClientID *client_id;
3728 SilcClientEntry client;
3729 SilcIDCacheEntry cache;
3732 SILC_LOG_DEBUG(("Start"));
3734 for (i = 0; i < user_count; i++) {
3736 SILC_GET16_MSB(idp_len, user_list->data + 2);
3738 client_id = silc_id_payload_parse_id(user_list->data, idp_len);
3739 silc_buffer_pull(user_list, idp_len);
3744 SILC_GET32_MSB(mode, mode_list->data);
3745 silc_buffer_pull(mode_list, 4);
3747 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
3748 silc_free(client_id);
3754 /* Check if we have this client cached already. */
3755 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3756 server->server_type, &cache);
3758 client = silc_idlist_find_client_by_id(server->global_list,
3759 client_id, server->server_type,
3764 /* If router did not find such Client ID in its lists then this must
3765 be bogus client or some router in the net is buggy. */
3766 if (server->server_type == SILC_ROUTER) {
3767 silc_free(client_id);
3771 /* We don't have that client anywhere, add it. The client is added
3772 to global list since server didn't have it in the lists so it must be
3774 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
3775 silc_id_dup(client_id, SILC_ID_CLIENT),
3776 sock->user_data, NULL, 0);
3778 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
3779 silc_free(client_id);
3783 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3785 /* Found, if it is from global list we'll assure that we won't
3786 expire it now that the entry is on channel. */
3791 silc_free(client_id);
3793 if (!silc_server_client_on_channel(client, channel)) {
3794 /* Client was not on the channel, add it. */
3795 SilcChannelClientEntry chl = silc_calloc(1, sizeof(*chl));
3796 chl->client = client;
3798 chl->channel = channel;
3799 silc_hash_table_add(channel->user_list, chl->client, chl);
3800 silc_hash_table_add(client->channels, chl->channel, chl);
3805 /* Lookups route to the client indicated by the `id_data'. The connection
3806 object and internal data object is returned. Returns NULL if route
3807 could not be found to the client. If the `client_id' is specified then
3808 it is used and the `id_data' is ignored. */
3810 SilcSocketConnection silc_server_get_client_route(SilcServer server,
3811 unsigned char *id_data,
3813 SilcClientID *client_id,
3814 SilcIDListData *idata)
3817 SilcClientEntry client;
3819 SILC_LOG_DEBUG(("Start"));
3821 /* Decode destination Client ID */
3823 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
3825 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
3829 id = silc_id_dup(client_id, SILC_ID_CLIENT);
3832 /* If the destination belongs to our server we don't have to route
3833 the packet anywhere but to send it to the local destination. */
3834 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
3838 /* If we are router and the client has router then the client is in
3839 our cell but not directly connected to us. */
3840 if (server->server_type == SILC_ROUTER && client->router) {
3841 /* We are of course in this case the client's router thus the route
3842 to the client is the server who owns the client. So, we will send
3843 the packet to that server. */
3845 *idata = (SilcIDListData)client->router;
3846 return client->router->connection;
3849 /* Seems that client really is directly connected to us */
3851 *idata = (SilcIDListData)client;
3852 return client->connection;
3855 /* Destination belongs to someone not in this server. If we are normal
3856 server our action is to send the packet to our router. */
3857 if (server->server_type != SILC_ROUTER && !server->standalone) {
3860 *idata = (SilcIDListData)server->router;
3861 return server->router->connection;
3864 /* We are router and we will perform route lookup for the destination
3865 and send the packet to fastest route. */
3866 if (server->server_type == SILC_ROUTER && !server->standalone) {
3867 /* Check first that the ID is valid */
3868 client = silc_idlist_find_client_by_id(server->global_list, id,
3871 SilcSocketConnection dst_sock;
3873 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
3877 *idata = (SilcIDListData)dst_sock->user_data;
3886 /* Encodes and returns channel list of channels the `client' has joined.
3887 Secret channels are not put to the list. */
3889 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
3890 SilcClientEntry client)
3892 SilcBuffer buffer = NULL;
3893 SilcChannelEntry channel;
3894 SilcChannelClientEntry chl;
3895 SilcHashTableList htl;
3901 silc_hash_table_list(client->channels, &htl);
3902 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3903 channel = chl->channel;
3905 if (channel->mode & SILC_CHANNEL_MODE_SECRET ||
3906 channel->mode & SILC_CHANNEL_MODE_PRIVATE)
3909 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3910 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3911 name_len = strlen(channel->channel_name);
3913 len = 4 + name_len + id_len + 4;
3914 buffer = silc_buffer_realloc(buffer,
3915 (buffer ? (buffer)->truelen + len : len));
3916 silc_buffer_pull_tail(buffer, ((buffer)->end - (buffer)->data));
3917 silc_buffer_format(buffer,
3918 SILC_STR_UI_SHORT(name_len),
3919 SILC_STR_UI_XNSTRING(channel->channel_name,
3921 SILC_STR_UI_SHORT(id_len),
3922 SILC_STR_UI_XNSTRING(cid, id_len),
3923 SILC_STR_UI_INT(chl->mode), /* Client's mode */
3925 silc_buffer_pull(buffer, len);
3928 silc_hash_table_list_reset(&htl);
3931 silc_buffer_push(buffer, buffer->data - buffer->head);
3936 /* Finds client entry by Client ID and if it is not found then resolves
3937 it using WHOIS command. */
3939 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
3940 SilcClientID *client_id,
3943 SilcClientEntry client;
3948 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3951 client = silc_idlist_find_client_by_id(server->global_list,
3952 client_id, TRUE, NULL);
3953 if (!client && server->server_type == SILC_ROUTER)
3957 if (!client && server->standalone)
3960 if (!client || !client->nickname || !client->username) {
3961 SilcBuffer buffer, idp;
3963 client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
3964 client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
3965 client->resolve_cmd_ident = ++server->cmd_ident;
3967 idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3968 buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
3969 server->cmd_ident, 1,
3970 3, idp->data, idp->len);
3971 silc_server_packet_send(server, client ? client->router->connection :
3972 server->router->connection,
3973 SILC_PACKET_COMMAND, 0,
3974 buffer->data, buffer->len, FALSE);
3975 silc_buffer_free(idp);
3976 silc_buffer_free(buffer);
3987 /* A timeout callback for the re-key. We will be the initiator of the
3990 SILC_TASK_CALLBACK(silc_server_rekey_callback)
3992 SilcSocketConnection sock = (SilcSocketConnection)context;
3993 SilcIDListData idata = (SilcIDListData)sock->user_data;
3994 SilcServer server = (SilcServer)idata->rekey->context;
3995 SilcProtocol protocol;
3996 SilcServerRekeyInternalContext *proto_ctx;
3998 SILC_LOG_DEBUG(("Start"));
4000 /* Allocate internal protocol context. This is sent as context
4002 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
4003 proto_ctx->server = (void *)server;
4004 proto_ctx->sock = sock;
4005 proto_ctx->responder = FALSE;
4006 proto_ctx->pfs = idata->rekey->pfs;
4008 /* Perform rekey protocol. Will call the final callback after the
4009 protocol is over. */
4010 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
4011 &protocol, proto_ctx, silc_server_rekey_final);
4012 sock->protocol = protocol;
4014 /* Run the protocol */
4015 silc_protocol_execute(protocol, server->schedule, 0, 0);
4017 /* Re-register re-key timeout */
4018 silc_schedule_task_add(server->schedule, sock->sock,
4019 silc_server_rekey_callback,
4020 context, idata->rekey->timeout, 0,
4021 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
4024 /* The final callback for the REKEY protocol. This will actually take the
4025 new key material into use. */
4027 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
4029 SilcProtocol protocol = (SilcProtocol)context;
4030 SilcServerRekeyInternalContext *ctx =
4031 (SilcServerRekeyInternalContext *)protocol->context;
4032 SilcServer server = (SilcServer)ctx->server;
4033 SilcSocketConnection sock = ctx->sock;
4035 SILC_LOG_DEBUG(("Start"));
4037 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
4038 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
4039 /* Error occured during protocol */
4040 SILC_LOG_ERROR(("Error occurred during rekey protocol"));
4041 silc_protocol_cancel(protocol, server->schedule);
4042 silc_protocol_free(protocol);
4043 sock->protocol = NULL;
4045 silc_packet_context_free(ctx->packet);
4047 silc_ske_free(ctx->ske);
4052 /* Purge the outgoing data queue to assure that all rekey packets really
4053 go to the network before we quit the protocol. */
4054 silc_server_packet_queue_purge(server, sock);
4057 silc_protocol_free(protocol);
4058 sock->protocol = NULL;
4060 silc_packet_context_free(ctx->packet);
4062 silc_ske_free(ctx->ske);