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 if (server->pending_commands)
97 silc_dlist_uninit(server->pending_commands);
103 /* Initializes the entire SILC server. This is called always before running
104 the server. This is called only once at the initialization of the program.
105 This binds the server to its listenning port. After this function returns
106 one should call silc_server_run to start the server. This returns TRUE
107 when everything is ok to run the server. Configuration file must be
108 read and parsed before calling this. */
110 int silc_server_init(SilcServer server)
112 int *sock = NULL, sock_count, i;
114 SilcServerEntry id_entry;
115 SilcIDListPurge purge;
117 SILC_LOG_DEBUG(("Initializing server"));
119 assert(server->config);
121 /* Set public and private keys */
122 if (!server->config->server_info ||
123 !server->config->server_info->public_key ||
124 !server->config->server_info->private_key) {
125 SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
128 server->public_key = server->config->server_info->public_key;
129 server->private_key = server->config->server_info->private_key;
131 /* Set default to configuration parameters */
132 silc_server_config_set_defaults(server);
134 /* Register all configured ciphers, PKCS and hash functions. */
135 if (!silc_server_config_register_ciphers(server))
136 silc_cipher_register_default();
137 if (!silc_server_config_register_pkcs(server))
138 silc_pkcs_register_default();
139 if (!silc_server_config_register_hashfuncs(server))
140 silc_hash_register_default();
141 if (!silc_server_config_register_hmacs(server))
142 silc_hmac_register_default();
144 /* Initialize random number generator for the server. */
145 server->rng = silc_rng_alloc();
146 silc_rng_init(server->rng);
147 silc_rng_global_init(server->rng);
149 /* Initialize hash functions for server to use */
150 silc_hash_alloc("md5", &server->md5hash);
151 silc_hash_alloc("sha1", &server->sha1hash);
153 /* Allocate PKCS context for local public and private keys */
154 silc_pkcs_alloc(server->public_key->name, &server->pkcs);
155 silc_pkcs_public_key_set(server->pkcs, server->public_key);
156 silc_pkcs_private_key_set(server->pkcs, server->private_key);
158 /* Create a listening server. Note that our server can listen on multiple
159 ports. All listeners are created here and now. */
164 tmp = silc_net_create_server(server->config->server_info->port,
165 server->config->server_info->server_ip);
168 SILC_LOG_ERROR(("Could not create server listener: %s on %hd",
169 server->config->server_info->server_ip,
170 server->config->server_info->port));
174 sock = silc_realloc(sock, sizeof(*sock) * (sock_count + 1));
175 sock[sock_count] = tmp;
180 /* Initialize ID caches */
181 server->local_list->clients =
182 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
183 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
184 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
186 /* These are allocated for normal server as well as these hold some
187 global information that the server has fetched from its router. For
188 router these are used as they are supposed to be used on router. */
189 server->global_list->clients =
190 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
191 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
192 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
194 /* Allocate the entire socket list that is used in server. Eventually
195 all connections will have entry in this table (it is a table of
196 pointers to the actual object that is allocated individually
198 server->sockets = silc_calloc(SILC_SERVER_MAX_CONNECTIONS,
199 sizeof(*server->sockets));
201 for (i = 0; i < sock_count; i++) {
202 SilcSocketConnection newsocket = NULL;
204 /* Set socket to non-blocking mode */
205 silc_net_set_socket_nonblock(sock[i]);
206 server->sock = sock[i];
208 /* Add ourselves also to the socket table. The entry allocated above
209 is sent as argument for fast referencing in the future. */
210 silc_socket_alloc(sock[i], SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
211 server->sockets[sock[i]] = newsocket;
213 /* Perform name and address lookups to resolve the listenning address
215 if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname,
217 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
219 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
220 newsocket->hostname ? newsocket->hostname :
221 newsocket->ip ? newsocket->ip : ""));
222 server->stat.conn_failures++;
225 if (!newsocket->hostname)
226 newsocket->hostname = strdup(newsocket->ip);
228 newsocket->port = silc_net_get_local_port(sock[i]);
230 /* Create a Server ID for the server. */
231 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
236 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
237 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
238 server->id_type = SILC_ID_SERVER;
239 server->server_name = server->config->server_info->server_name;
241 /* Add ourselves to the server list. We don't have a router yet
242 beacuse we haven't established a route yet. It will be done later.
243 For now, NULL is sent as router. This allocates new entry to
246 silc_idlist_add_server(server->local_list,
247 server->config->server_info->server_name,
248 server->server_type, server->id, NULL, NULL);
250 SILC_LOG_ERROR(("Could not add ourselves to cache"));
253 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
255 /* Put the allocated socket pointer also to the entry allocated above
256 for fast back-referencing to the socket list. */
257 newsocket->user_data = (void *)id_entry;
258 id_entry->connection = (void *)newsocket;
259 server->id_entry = id_entry;
262 /* Register protocols */
263 silc_server_protocols_register();
265 /* Initialize the scheduler. */
266 server->schedule = silc_schedule_init(SILC_SERVER_MAX_CONNECTIONS);
267 if (!server->schedule)
270 /* Add the first task to the scheduler. This is task that is executed by
271 timeout. It expires as soon as the caller calls silc_server_run. This
272 task performs authentication protocol and key exchange with our
274 silc_schedule_task_add(server->schedule, sock[0],
275 silc_server_connect_to_router,
276 (void *)server, 0, 1,
278 SILC_TASK_PRI_NORMAL);
280 /* Add listener task to the scheduler. This task receives new connections
281 to the server. This task remains on the queue until the end of the
283 silc_schedule_task_add(server->schedule, sock[0],
284 silc_server_accept_new_connection,
285 (void *)server, 0, 0,
287 SILC_TASK_PRI_NORMAL);
288 server->listenning = TRUE;
290 /* Send log file configuration */
291 silc_server_config_setlogfiles(server);
293 /* If server connections has been configured then we must be router as
294 normal server cannot have server connections, only router connections. */
295 if (server->config->servers) {
296 SilcServerConfigSectionServer *ptr = server->config->servers;
298 server->server_type = SILC_ROUTER;
300 if (ptr->backup_router) {
301 server->server_type = SILC_BACKUP_ROUTER;
302 server->backup_router = TRUE;
303 server->id_entry->server_type = SILC_BACKUP_ROUTER;
310 /* Register the ID Cache purge task. This periodically purges the ID cache
311 and removes the expired cache entries. */
313 /* Clients local list */
314 purge = silc_calloc(1, sizeof(*purge));
315 purge->cache = server->local_list->clients;
316 purge->schedule = server->schedule;
317 purge->timeout = 600;
318 silc_schedule_task_add(purge->schedule, 0,
320 (void *)purge, purge->timeout, 0,
321 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
323 /* Clients global list */
324 purge = silc_calloc(1, sizeof(*purge));
325 purge->cache = server->global_list->clients;
326 purge->schedule = server->schedule;
327 purge->timeout = 300;
328 silc_schedule_task_add(purge->schedule, 0,
330 (void *)purge, purge->timeout, 0,
331 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
333 SILC_LOG_DEBUG(("Server initialized"));
335 /* We are done here, return succesfully */
339 for (i = 0; i < sock_count; i++)
340 silc_net_close_server(sock[i]);
345 /* Fork server to background */
347 void silc_server_daemonise(SilcServer server)
351 SILC_LOG_DEBUG(("Forking SILC server to background"));
356 SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
361 SILC_LOG_DEBUG(("Server started as user"));
363 SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
369 /* Drop root privligies. If this cannot be done, die. */
371 void silc_server_drop(SilcServer server)
373 /* Are we executing silcd as root or a regular user? */
379 if (!server->config->server_info->user || !server->config->server_info->group) {
380 fprintf(stderr, "Error:"
381 "\tSILC server must not be run as root. For the security of your\n"
382 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
383 "\tuser account. Modify the [Identity] configuration section to run\n"
384 "\tthe server as non-root user.\n");
388 /* Get the values given for user and group in configuration file */
389 user=server->config->server_info->user;
390 group=server->config->server_info->group;
392 /* Check whether the user/group information is text */
393 if (atoi(user)!=0 || atoi(group)!=0) {
394 SILC_LOG_DEBUG(("Invalid user and/or group information"));
395 SILC_LOG_DEBUG(("User and/or group given as number"));
396 fprintf(stderr, "Invalid user and/or group information\n");
397 fprintf(stderr, "Please assign them as names, not numbers\n");
401 /* Catch the nasty incident of string "0" returning 0 from atoi */
402 if (strcmp("0", user)==0 || strcmp("0", group)==0) {
403 SILC_LOG_DEBUG(("User and/or group configured to 0. Unacceptable"));
404 fprintf(stderr, "User and/or group configured to 0. Exiting\n");
408 if (!(pw=getpwnam(user))) {
409 fprintf(stderr, "No such user %s found\n", user);
413 if (!(gr=getgrnam(group))) {
414 fprintf(stderr, "No such group %s found\n", group);
418 /* Check whether user and/or group is set to root. If yes, exit
419 immediately. Otherwise, setgid and setuid server to user.group */
420 if (gr->gr_gid==0 || pw->pw_uid==0) {
421 fprintf(stderr, "Error:"
422 "\tSILC server must not be run as root. For the security of your\n"
423 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
424 "\tuser account. Modify the [Identity] configuration section to run\n"
425 "\tthe server as non-root user.\n");
428 SILC_LOG_DEBUG(("Changing to group %s", group));
429 if (setgid(gr->gr_gid)==0) {
430 SILC_LOG_DEBUG(("Setgid to %s", group));
432 SILC_LOG_DEBUG(("Setgid to %s failed", group));
433 fprintf(stderr, "Tried to setgid %s but no such group. Exiting\n",
437 #if defined HAVE_SETGROUPS && defined HAVE_INITGROUPS
438 if (setgroups(0, NULL)!=0) {
439 SILC_LOG_DEBUG(("Setgroups to NULL failed"));
440 fprintf(stderr, "Tried to setgroups NULL but failed. Exiting\n");
443 if (initgroups(user, gr->gr_gid)!=0) {
444 SILC_LOG_DEBUG(("Initgroups to user %s (gid=%d) failed", user, gr->gr_gid));
445 fprintf(stderr, "Tried to initgroups %s (gid=%d) but no such user. Exiting\n",
450 SILC_LOG_DEBUG(("Changing to user %s", user));
451 if (setuid(pw->pw_uid)==0) {
452 SILC_LOG_DEBUG(("Setuid to %s", user));
454 SILC_LOG_DEBUG(("Setuid to %s failed", user));
455 fprintf(stderr, "Tried to setuid %s but no such user. Exiting\n",
463 /* The heart of the server. This runs the scheduler thus runs the server.
464 When this returns the server has been stopped and the program will
467 void silc_server_run(SilcServer server)
469 SILC_LOG_DEBUG(("Running server"));
471 SILC_LOG_INFO(("SILC Server started"));
473 /* Start the scheduler, the heart of the SILC server. When this returns
474 the program will be terminated. */
475 silc_schedule(server->schedule);
478 /* Stops the SILC server. This function is used to shutdown the server.
479 This is usually called after the scheduler has returned. After stopping
480 the server one should call silc_server_free. */
482 void silc_server_stop(SilcServer server)
484 SILC_LOG_DEBUG(("Stopping server"));
486 if (server->schedule) {
487 silc_schedule_stop(server->schedule);
488 silc_schedule_uninit(server->schedule);
489 server->schedule = NULL;
492 silc_server_protocols_unregister();
494 SILC_LOG_DEBUG(("Server stopped"));
497 /* Function that is called when the network connection to a router has
498 been established. This will continue with the key exchange protocol
499 with the remote router. */
501 void silc_server_start_key_exchange(SilcServer server,
502 SilcServerConnection sconn,
505 SilcSocketConnection newsocket;
506 SilcProtocol protocol;
507 SilcServerKEInternalContext *proto_ctx;
510 /* Cancel any possible retry timeouts */
511 silc_schedule_task_del_by_callback(server->schedule,
512 silc_server_connect_router);
514 /* Set socket options */
515 silc_net_set_socket_nonblock(sock);
516 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
518 /* Create socket connection for the connection. Even though we
519 know that we are connecting to a router we will mark the socket
520 to be unknown connection until we have executed authentication
522 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
523 server->sockets[sock] = newsocket;
524 newsocket->hostname = strdup(sconn->remote_host);
525 newsocket->ip = strdup(sconn->remote_host);
526 newsocket->port = sconn->remote_port;
527 sconn->sock = newsocket;
529 /* Allocate internal protocol context. This is sent as context
531 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
532 proto_ctx->server = (void *)server;
533 proto_ctx->context = (void *)sconn;
534 proto_ctx->sock = newsocket;
535 proto_ctx->rng = server->rng;
536 proto_ctx->responder = FALSE;
538 /* Perform key exchange protocol. silc_server_connect_to_router_second
539 will be called after the protocol is finished. */
540 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
541 &protocol, proto_ctx,
542 silc_server_connect_to_router_second);
543 newsocket->protocol = protocol;
545 /* Register a timeout task that will be executed if the protocol
546 is not executed within set limit. */
547 proto_ctx->timeout_task =
548 silc_schedule_task_add(server->schedule, sock,
549 silc_server_timeout_remote,
550 server, 60, 0, /* XXX hardcoded */
554 /* Register the connection for network input and output. This sets
555 that scheduler will listen for incoming packets for this connection
556 and sets that outgoing packets may be sent to this connection as
557 well. However, this doesn't set the scheduler for outgoing traffic,
558 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
559 later when outgoing data is available. */
560 context = (void *)server;
561 SILC_REGISTER_CONNECTION_FOR_IO(sock);
563 /* Run the protocol */
564 silc_protocol_execute(protocol, server->schedule, 0, 0);
567 /* Timeout callback that will be called to retry connecting to remote
568 router. This is used by both normal and router server. This will wait
569 before retrying the connecting. The timeout is generated by exponential
570 backoff algorithm. */
572 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
574 SilcServerConnection sconn = (SilcServerConnection)context;
575 SilcServer server = sconn->server;
576 SilcServerConfigSectionConnectionParam *param;
578 param = (sconn->param ? sconn->param : &server->config->param);
580 SILC_LOG_INFO(("Retrying connecting to a router"));
582 /* Calculate next timeout */
583 if (sconn->retry_count >= 1) {
584 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
585 if (sconn->retry_timeout > param->reconnect_interval_max)
586 sconn->retry_timeout = param->reconnect_interval_max;
588 sconn->retry_timeout = param->reconnect_interval;
590 sconn->retry_count++;
591 sconn->retry_timeout = sconn->retry_timeout +
592 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
594 /* If we've reached max retry count, give up. */
595 if (sconn->retry_count > param->reconnect_count &&
596 param->reconnect_keep_trying == FALSE) {
597 SILC_LOG_ERROR(("Could not connect to router, giving up"));
598 silc_free(sconn->remote_host);
603 /* Wait one before retrying */
604 silc_schedule_task_add(server->schedule, fd, silc_server_connect_router,
605 context, sconn->retry_timeout, 0,
606 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
609 /* Generic routine to use connect to a router. */
611 SILC_TASK_CALLBACK(silc_server_connect_router)
613 SilcServerConnection sconn = (SilcServerConnection)context;
614 SilcServer server = sconn->server;
617 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
618 (sconn->backup ? "backup router" : "router"),
619 sconn->remote_host, sconn->remote_port));
621 server->router_connect = time(NULL);
623 /* Connect to remote host */
624 sock = silc_net_create_connection(server->config->server_info->server_ip,
628 SILC_LOG_ERROR(("Could not connect to router %s:%d",
629 sconn->remote_host, sconn->remote_port));
630 if (!sconn->no_reconnect)
631 silc_schedule_task_add(server->schedule, fd,
632 silc_server_connect_to_router_retry,
633 context, 0, 1, SILC_TASK_TIMEOUT,
634 SILC_TASK_PRI_NORMAL);
638 /* Continue with key exchange protocol */
639 silc_server_start_key_exchange(server, sconn, sock);
642 /* This function connects to our primary router or if we are a router this
643 establishes all our primary routes. This is called at the start of the
644 server to do authentication and key exchange with our router - called
647 SILC_TASK_CALLBACK(silc_server_connect_to_router)
649 SilcServer server = (SilcServer)context;
650 SilcServerConnection sconn;
651 SilcServerConfigSectionRouter *ptr;
653 SILC_LOG_DEBUG(("Connecting to router(s)"));
655 if (server->server_type == SILC_SERVER) {
656 SILC_LOG_DEBUG(("We are normal server"));
657 } else if (server->server_type == SILC_ROUTER) {
658 SILC_LOG_DEBUG(("We are router"));
660 SILC_LOG_DEBUG(("We are backup router/normal server"));
663 /* Create the connections to all our routes */
664 ptr = server->config->routers;
667 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
668 ptr->backup_router ? "Backup router" : "Router",
669 ptr->initiator ? "Initiator" : "Responder",
670 ptr->host, ptr->port));
672 if (ptr->initiator) {
673 /* Allocate connection object for hold connection specific stuff. */
674 sconn = silc_calloc(1, sizeof(*sconn));
675 sconn->server = server;
676 sconn->remote_host = strdup(ptr->host);
677 sconn->remote_port = ptr->port;
678 sconn->backup = ptr->backup_router;
680 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
681 sconn->backup_replace_port = ptr->backup_replace_port;
684 if (!server->router_conn && !sconn->backup)
685 server->router_conn = sconn;
688 sconn->param = ptr->param;
690 silc_schedule_task_add(server->schedule, fd,
691 silc_server_connect_router,
692 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
693 SILC_TASK_PRI_NORMAL);
702 SILC_LOG_DEBUG(("No router(s), server will be standalone"));
704 /* There wasn't a configured router, we will continue but we don't
705 have a connection to outside world. We will be standalone server. */
706 server->standalone = TRUE;
709 /* Second part of connecting to router(s). Key exchange protocol has been
710 executed and now we will execute authentication protocol. */
712 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
714 SilcProtocol protocol = (SilcProtocol)context;
715 SilcServerKEInternalContext *ctx =
716 (SilcServerKEInternalContext *)protocol->context;
717 SilcServer server = (SilcServer)ctx->server;
718 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
719 SilcSocketConnection sock = ctx->sock;
720 SilcServerConnAuthInternalContext *proto_ctx;
721 SilcServerConfigSectionRouter *conn = NULL;
723 SILC_LOG_DEBUG(("Start"));
725 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
726 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
727 /* Error occured during protocol */
728 silc_protocol_free(protocol);
729 sock->protocol = NULL;
730 silc_ske_free_key_material(ctx->keymat);
732 silc_packet_context_free(ctx->packet);
734 silc_ske_free(ctx->ske);
735 silc_free(ctx->dest_id);
737 silc_schedule_task_del_by_callback(server->schedule,
738 silc_server_failure_callback);
739 silc_server_disconnect_remote(server, sock, "Server closed connection: "
740 "Key exchange failed");
744 /* We now have the key material as the result of the key exchange
745 protocol. Take the key material into use. Free the raw key material
746 as soon as we've set them into use. */
747 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
748 ctx->sock, ctx->keymat,
749 ctx->ske->prop->cipher,
750 ctx->ske->prop->pkcs,
751 ctx->ske->prop->hash,
752 ctx->ske->prop->hmac,
753 ctx->ske->prop->group,
755 silc_protocol_free(protocol);
756 sock->protocol = NULL;
757 silc_ske_free_key_material(ctx->keymat);
759 silc_packet_context_free(ctx->packet);
761 silc_ske_free(ctx->ske);
762 silc_free(ctx->dest_id);
764 silc_schedule_task_del_by_callback(server->schedule,
765 silc_server_failure_callback);
766 silc_server_disconnect_remote(server, sock, "Server closed connection: "
767 "Key exchange failed");
770 silc_ske_free_key_material(ctx->keymat);
772 /* Allocate internal context for the authentication protocol. This
773 is sent as context for the protocol. */
774 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
775 proto_ctx->server = (void *)server;
776 proto_ctx->context = (void *)sconn;
777 proto_ctx->sock = sock;
778 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
779 proto_ctx->dest_id_type = ctx->dest_id_type;
780 proto_ctx->dest_id = ctx->dest_id;
782 /* Resolve the authentication method used in this connection. Check if
783 we find a match from user configured connections */
785 conn = silc_server_config_find_router_conn(server, sock->hostname,
791 /* Match found. Use the configured authentication method */
792 if (conn->passphrase) {
793 if (conn->publickey && !server->config->prefer_passphrase_auth) {
794 proto_ctx->auth_data = conn->publickey;
795 proto_ctx->auth_data_len = 0;
796 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
798 proto_ctx->auth_data = strdup(conn->passphrase);
799 proto_ctx->auth_data_len = strlen(conn->passphrase);
800 proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
802 } else if (conn->publickey) {
803 proto_ctx->auth_data = conn->publickey;
804 proto_ctx->auth_data_len = 0;
805 proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
807 proto_ctx->auth_meth = SILC_AUTH_NONE;
810 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
811 sock->hostname, sock->ip, sock->port));
812 silc_protocol_free(protocol);
813 sock->protocol = NULL;
815 silc_packet_context_free(ctx->packet);
817 silc_ske_free(ctx->ske);
818 silc_free(ctx->dest_id);
820 silc_schedule_task_del_by_callback(server->schedule,
821 silc_server_failure_callback);
822 silc_server_disconnect_remote(server, sock, "Server closed connection: "
823 "Key exchange failed");
827 /* Free old protocol as it is finished now */
828 silc_protocol_free(protocol);
830 silc_packet_context_free(ctx->packet);
832 sock->protocol = NULL;
834 /* Allocate the authentication protocol. This is allocated here
835 but we won't start it yet. We will be receiving party of this
836 protocol thus we will wait that connecting party will make
838 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
839 &sock->protocol, proto_ctx,
840 silc_server_connect_to_router_final);
842 /* Register timeout task. If the protocol is not executed inside
843 this timelimit the connection will be terminated. */
844 proto_ctx->timeout_task =
845 silc_schedule_task_add(server->schedule, sock->sock,
846 silc_server_timeout_remote,
847 (void *)server, 15, 0, /* XXX hardcoded */
851 /* Run the protocol */
852 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
855 /* Finalizes the connection to router. Registers a server task to the
856 queue so that we can accept new connections. */
858 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
860 SilcProtocol protocol = (SilcProtocol)context;
861 SilcServerConnAuthInternalContext *ctx =
862 (SilcServerConnAuthInternalContext *)protocol->context;
863 SilcServer server = (SilcServer)ctx->server;
864 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
865 SilcSocketConnection sock = ctx->sock;
866 SilcServerEntry id_entry;
868 SilcServerHBContext hb_context;
869 unsigned char *id_string;
871 SilcIDListData idata;
872 SilcServerConfigSectionConnectionParam *param;
874 SILC_LOG_DEBUG(("Start"));
876 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
877 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
878 /* Error occured during protocol */
879 silc_free(ctx->dest_id);
880 silc_server_disconnect_remote(server, sock, "Server closed connection: "
881 "Authentication failed");
885 /* Add a task to the queue. This task receives new connections to the
886 server. This task remains on the queue until the end of the program. */
887 if (!server->listenning && !sconn->backup) {
888 silc_schedule_task_add(server->schedule, server->sock,
889 silc_server_accept_new_connection,
890 (void *)server, 0, 0,
892 SILC_TASK_PRI_NORMAL);
893 server->listenning = TRUE;
896 /* Send NEW_SERVER packet to the router. We will become registered
897 to the SILC network after sending this packet. */
898 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
899 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
900 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
901 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
902 silc_buffer_format(packet,
903 SILC_STR_UI_SHORT(id_len),
904 SILC_STR_UI_XNSTRING(id_string, id_len),
905 SILC_STR_UI_SHORT(strlen(server->server_name)),
906 SILC_STR_UI_XNSTRING(server->server_name,
907 strlen(server->server_name)),
910 /* Send the packet */
911 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
912 packet->data, packet->len, TRUE);
913 silc_buffer_free(packet);
914 silc_free(id_string);
916 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
918 /* Check that we do not have this ID already */
919 id_entry = silc_idlist_find_server_by_id(server->local_list,
920 ctx->dest_id, TRUE, NULL);
922 silc_idcache_del_by_context(server->local_list->servers, id_entry);
924 id_entry = silc_idlist_find_server_by_id(server->global_list,
925 ctx->dest_id, TRUE, NULL);
927 silc_idcache_del_by_context(server->global_list->servers, id_entry);
930 SILC_LOG_DEBUG(("New server id(%s)",
931 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
933 /* Add the connected router to global server list */
934 id_entry = silc_idlist_add_server(server->global_list,
935 strdup(sock->hostname),
936 SILC_ROUTER, ctx->dest_id, NULL, sock);
938 silc_free(ctx->dest_id);
939 silc_server_disconnect_remote(server, sock, "Server closed connection: "
940 "Authentication failed");
944 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
945 silc_free(sock->user_data);
946 sock->user_data = (void *)id_entry;
947 sock->type = SILC_SOCKET_TYPE_ROUTER;
948 idata = (SilcIDListData)sock->user_data;
949 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
951 param = (sconn->param ? sconn->param : &server->config->param);
953 /* Perform keepalive. The `hb_context' will be freed automatically
954 when finally calling the silc_socket_free function. XXX hardcoded
956 hb_context = silc_calloc(1, sizeof(*hb_context));
957 hb_context->server = server;
958 silc_socket_set_heartbeat(sock, param->keepalive_secs, hb_context,
959 silc_server_perform_heartbeat,
962 /* Register re-key timeout */
963 idata->rekey->timeout = 3600; /* XXX hardcoded */
964 idata->rekey->context = (void *)server;
965 silc_schedule_task_add(server->schedule, sock->sock,
966 silc_server_rekey_callback,
967 (void *)sock, idata->rekey->timeout, 0,
968 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
970 if (!sconn->backup) {
971 /* Mark this router our primary router if we're still standalone */
972 if (server->standalone) {
973 server->id_entry->router = id_entry;
974 server->router = id_entry;
975 server->standalone = FALSE;
977 /* If we are router then announce our possible servers. */
978 if (server->server_type == SILC_ROUTER)
979 silc_server_announce_servers(server, FALSE, 0,
980 server->router->connection);
982 /* Announce our clients and channels to the router */
983 silc_server_announce_clients(server, 0, server->router->connection);
984 silc_server_announce_channels(server, 0, server->router->connection);
987 /* Add this server to be our backup router */
988 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
989 sconn->backup_replace_port, FALSE);
992 sock->protocol = NULL;
994 /* Call the completion callback to indicate that we've connected to
997 (*sconn->callback)(server, id_entry, sconn->callback_context);
1000 /* Free the temporary connection data context */
1002 silc_free(sconn->remote_host);
1003 silc_free(sconn->backup_replace_ip);
1006 if (sconn == server->router_conn)
1007 server->router_conn = NULL;
1009 /* Free the protocol object */
1010 if (sock->protocol == protocol)
1011 sock->protocol = NULL;
1012 silc_protocol_free(protocol);
1014 silc_packet_context_free(ctx->packet);
1016 silc_ske_free(ctx->ske);
1017 if (ctx->auth_meth == SILC_AUTH_PASSWORD)
1018 silc_free(ctx->auth_data);
1022 /* Host lookup callbcak that is called after the incoming connection's
1023 IP and FQDN lookup is performed. This will actually check the acceptance
1024 of the incoming connection and will register the key exchange protocol
1025 for this connection. */
1028 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1031 SilcServer server = (SilcServer)context;
1032 SilcServerKEInternalContext *proto_ctx;
1033 void *cconfig, *sconfig, *rconfig;
1034 SilcServerConfigSectionDeny *deny;
1037 SILC_LOG_DEBUG(("Start"));
1039 /* Check whether we could resolve both IP and FQDN. */
1040 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1041 server->config->require_reverse_lookup)) {
1042 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1043 sock->hostname ? sock->hostname :
1044 sock->ip ? sock->ip : ""));
1045 server->stat.conn_failures++;
1046 silc_server_disconnect_remote(server, sock,
1047 "Server closed connection: Unknown host");
1051 /* Register the connection for network input and output. This sets
1052 that scheduler will listen for incoming packets for this connection
1053 and sets that outgoing packets may be sent to this connection as well.
1054 However, this doesn't set the scheduler for outgoing traffic, it
1055 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1056 later when outgoing data is available. */
1057 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1059 SILC_LOG_INFO(("Incoming connection from %s (%s)", sock->hostname,
1062 port = server->sockets[server->sock]->port; /* Listenning port */
1064 /* Check whether this connection is denied to connect to us. */
1065 deny = silc_server_config_find_denied(server, sock->ip, port);
1067 deny = silc_server_config_find_denied(server, sock->hostname, port);
1069 /* The connection is denied */
1070 SILC_LOG_INFO(("Connection %s (%s) is denied",
1071 sock->hostname, sock->ip));
1072 silc_server_disconnect_remote(server, sock, deny->reason ?
1074 "Server closed connection: "
1075 "Connection refused");
1076 server->stat.conn_failures++;
1080 /* Check whether we have configred this sort of connection at all. We
1081 have to check all configurations since we don't know what type of
1082 connection this is. */
1083 if (!(cconfig = silc_server_config_find_client(server, sock->ip, port)))
1084 cconfig = silc_server_config_find_client(server, sock->hostname, port);
1085 if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
1086 sconfig = silc_server_config_find_server_conn(server, sock->hostname);
1087 if (!(rconfig = silc_server_config_find_router_conn(server, sock->ip, port)))
1088 rconfig = silc_server_config_find_router_conn(server, sock->hostname,
1090 if (!cconfig && !sconfig && !rconfig) {
1091 SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
1093 silc_server_disconnect_remote(server, sock,
1094 "Server closed connection: "
1095 "Connection refused");
1096 server->stat.conn_failures++;
1100 /* The connection is allowed */
1102 /* Allocate internal context for key exchange protocol. This is
1103 sent as context for the protocol. */
1104 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1105 proto_ctx->server = context;
1106 proto_ctx->sock = sock;
1107 proto_ctx->rng = server->rng;
1108 proto_ctx->responder = TRUE;
1109 proto_ctx->cconfig = cconfig;
1110 proto_ctx->sconfig = sconfig;
1111 proto_ctx->rconfig = rconfig;
1113 /* Prepare the connection for key exchange protocol. We allocate the
1114 protocol but will not start it yet. The connector will be the
1115 initiator of the protocol thus we will wait for initiation from
1116 there before we start the protocol. */
1117 server->stat.auth_attempts++;
1118 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1119 &sock->protocol, proto_ctx,
1120 silc_server_accept_new_connection_second);
1122 /* Register a timeout task that will be executed if the connector
1123 will not start the key exchange protocol within 60 seconds. For
1124 now, this is a hard coded limit. After the timeout the connection will
1125 be closed if the key exchange protocol has not been started. */
1126 proto_ctx->timeout_task =
1127 silc_schedule_task_add(server->schedule, sock->sock,
1128 silc_server_timeout_remote,
1129 context, 60, 0, /* XXX hardcoded */
1134 /* Accepts new connections to the server. Accepting new connections are
1135 done in three parts to make it async. */
1137 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1139 SilcServer server = (SilcServer)context;
1140 SilcSocketConnection newsocket;
1143 SILC_LOG_DEBUG(("Accepting new connection"));
1145 server->stat.conn_attempts++;
1147 sock = silc_net_accept_connection(server->sock);
1149 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1150 server->stat.conn_failures++;
1154 /* Check max connections */
1155 if (sock > SILC_SERVER_MAX_CONNECTIONS) {
1156 SILC_LOG_ERROR(("Refusing connection, server is full"));
1157 server->stat.conn_failures++;
1161 /* Set socket options */
1162 silc_net_set_socket_nonblock(sock);
1163 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1165 /* We don't create a ID yet, since we don't know what type of connection
1166 this is yet. But, we do add the connection to the socket table. */
1167 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1168 server->sockets[sock] = newsocket;
1170 /* Perform asynchronous host lookup. This will lookup the IP and the
1171 FQDN of the remote connection. After the lookup is done the connection
1172 is accepted further. */
1173 silc_socket_host_lookup(newsocket, TRUE,
1174 silc_server_accept_new_connection_lookup, context,
1178 /* Second part of accepting new connection. Key exchange protocol has been
1179 performed and now it is time to do little connection authentication
1180 protocol to figure out whether this connection is client or server
1181 and whether it has right to access this server (especially server
1182 connections needs to be authenticated). */
1184 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1186 SilcProtocol protocol = (SilcProtocol)context;
1187 SilcServerKEInternalContext *ctx =
1188 (SilcServerKEInternalContext *)protocol->context;
1189 SilcServer server = (SilcServer)ctx->server;
1190 SilcSocketConnection sock = ctx->sock;
1191 SilcServerConnAuthInternalContext *proto_ctx;
1193 SILC_LOG_DEBUG(("Start"));
1195 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1196 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1197 /* Error occured during protocol */
1198 silc_protocol_free(protocol);
1199 sock->protocol = NULL;
1200 silc_ske_free_key_material(ctx->keymat);
1202 silc_packet_context_free(ctx->packet);
1204 silc_ske_free(ctx->ske);
1205 silc_free(ctx->dest_id);
1207 silc_schedule_task_del_by_callback(server->schedule,
1208 silc_server_failure_callback);
1209 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1210 "Key exchange failed");
1211 server->stat.auth_failures++;
1215 /* We now have the key material as the result of the key exchange
1216 protocol. Take the key material into use. Free the raw key material
1217 as soon as we've set them into use. */
1218 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1219 ctx->sock, ctx->keymat,
1220 ctx->ske->prop->cipher,
1221 ctx->ske->prop->pkcs,
1222 ctx->ske->prop->hash,
1223 ctx->ske->prop->hmac,
1224 ctx->ske->prop->group,
1226 silc_protocol_free(protocol);
1227 sock->protocol = NULL;
1228 silc_ske_free_key_material(ctx->keymat);
1230 silc_packet_context_free(ctx->packet);
1232 silc_ske_free(ctx->ske);
1233 silc_free(ctx->dest_id);
1235 silc_schedule_task_del_by_callback(server->schedule,
1236 silc_server_failure_callback);
1237 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1238 "Key exchange failed");
1239 server->stat.auth_failures++;
1242 silc_ske_free_key_material(ctx->keymat);
1244 /* Allocate internal context for the authentication protocol. This
1245 is sent as context for the protocol. */
1246 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1247 proto_ctx->server = (void *)server;
1248 proto_ctx->sock = sock;
1249 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1250 proto_ctx->responder = TRUE;
1251 proto_ctx->dest_id_type = ctx->dest_id_type;
1252 proto_ctx->dest_id = ctx->dest_id;
1253 proto_ctx->cconfig = ctx->cconfig;
1254 proto_ctx->sconfig = ctx->sconfig;
1255 proto_ctx->rconfig = ctx->rconfig;
1257 /* Free old protocol as it is finished now */
1258 silc_protocol_free(protocol);
1260 silc_packet_context_free(ctx->packet);
1262 sock->protocol = NULL;
1264 /* Allocate the authentication protocol. This is allocated here
1265 but we won't start it yet. We will be receiving party of this
1266 protocol thus we will wait that connecting party will make
1267 their first move. */
1268 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1269 &sock->protocol, proto_ctx,
1270 silc_server_accept_new_connection_final);
1272 /* Register timeout task. If the protocol is not executed inside
1273 this timelimit the connection will be terminated. */
1274 proto_ctx->timeout_task =
1275 silc_schedule_task_add(server->schedule, sock->sock,
1276 silc_server_timeout_remote,
1277 (void *)server, 60, 0, /* XXX hardcoded */
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;
1296 uint32 hearbeat_timeout = SILC_SERVER_KEEPALIVE;
1298 SILC_LOG_DEBUG(("Start"));
1300 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1301 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1302 /* Error occured during protocol */
1303 silc_protocol_free(protocol);
1304 sock->protocol = NULL;
1306 silc_packet_context_free(ctx->packet);
1308 silc_ske_free(ctx->ske);
1309 silc_free(ctx->dest_id);
1311 silc_schedule_task_del_by_callback(server->schedule,
1312 silc_server_failure_callback);
1313 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1314 "Authentication failed");
1315 server->stat.auth_failures++;
1319 entry->data.last_receive = time(NULL);
1321 switch (ctx->conn_type) {
1322 case SILC_SOCKET_TYPE_CLIENT:
1324 SilcClientEntry client;
1325 SilcServerConfigSectionClient *conn = ctx->cconfig;
1327 SILC_LOG_DEBUG(("Remote host is client"));
1328 SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname,
1331 /* Add the client to the client ID cache. The nickname and Client ID
1332 and other information is created after we have received NEW_CLIENT
1333 packet from client. */
1334 client = silc_idlist_add_client(server->local_list,
1335 NULL, NULL, NULL, NULL, NULL, sock, 0);
1337 SILC_LOG_ERROR(("Could not add new client to cache"));
1338 silc_free(sock->user_data);
1339 silc_server_disconnect_remote(server, sock,
1340 "Server closed connection: "
1341 "Authentication failed");
1342 server->stat.auth_failures++;
1347 server->stat.my_clients++;
1348 server->stat.clients++;
1349 if (server->server_type == SILC_ROUTER)
1350 server->stat.cell_clients++;
1352 /* Get connection parameters */
1354 if (conn->param->keepalive_secs)
1355 hearbeat_timeout = conn->param->keepalive_secs;
1358 id_entry = (void *)client;
1361 case SILC_SOCKET_TYPE_SERVER:
1362 case SILC_SOCKET_TYPE_ROUTER:
1364 SilcServerEntry new_server;
1365 bool initiator = FALSE;
1366 bool backup_local = FALSE;
1367 bool backup_router = FALSE;
1368 char *backup_replace_ip = NULL;
1369 uint16 backup_replace_port = 0;
1370 SilcServerConfigSectionServer *sconn = ctx->sconfig;
1371 SilcServerConfigSectionRouter *rconn = ctx->rconfig;
1373 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && rconn) {
1374 initiator = rconn->initiator;
1375 backup_local = rconn->backup_local;
1376 backup_router = rconn->backup_router;
1377 backup_replace_ip = rconn->backup_replace_ip;
1378 backup_replace_port = rconn->backup_replace_port;
1381 if (rconn->param->keepalive_secs)
1382 hearbeat_timeout = rconn->param->keepalive_secs;
1386 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER && sconn) {
1387 backup_router = sconn->backup_router;
1390 if (sconn->param->keepalive_secs)
1391 hearbeat_timeout = sconn->param->keepalive_secs;
1395 SILC_LOG_DEBUG(("Remote host is %s",
1396 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1397 "server" : (backup_router ?
1398 "backup router" : "router")));
1399 SILC_LOG_INFO(("Connection from %s (%s) is %s", sock->hostname,
1400 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1401 "server" : (backup_router ?
1402 "backup router" : "router")));
1404 /* Add the server into server cache. The server name and Server ID
1405 is updated after we have received NEW_SERVER packet from the
1406 server. We mark ourselves as router for this server if we really
1409 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1410 server->local_list : (backup_router ?
1411 server->local_list :
1412 server->global_list)),
1414 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1415 SILC_SERVER : SILC_ROUTER),
1417 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1418 server->id_entry : (backup_router ?
1419 server->id_entry : NULL)),
1422 SILC_LOG_ERROR(("Could not add new server to cache"));
1423 silc_free(sock->user_data);
1424 silc_server_disconnect_remote(server, sock,
1425 "Server closed connection: "
1426 "Authentication failed");
1427 server->stat.auth_failures++;
1432 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER)
1433 server->stat.my_servers++;
1435 server->stat.my_routers++;
1436 server->stat.servers++;
1438 id_entry = (void *)new_server;
1440 /* If the incoming connection is router and marked as backup router
1441 then add it to be one of our backups */
1442 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) {
1443 silc_server_backup_add(server, new_server, backup_replace_ip,
1444 backup_replace_port, backup_local);
1446 /* Change it back to SERVER type since that's what it really is. */
1448 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1450 new_server->server_type = SILC_BACKUP_ROUTER;
1453 /* Check whether this connection is to be our primary router connection
1454 if we do not already have the primary route. */
1455 if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1456 if (silc_server_config_is_primary_route(server) && !initiator)
1459 SILC_LOG_DEBUG(("We are not standalone server anymore"));
1460 server->standalone = FALSE;
1461 if (!server->id_entry->router) {
1462 server->id_entry->router = id_entry;
1463 server->router = id_entry;
1474 sock->type = ctx->conn_type;
1476 /* Add the common data structure to the ID entry. */
1477 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1479 /* Add to sockets internal pointer for fast referencing */
1480 silc_free(sock->user_data);
1481 sock->user_data = id_entry;
1483 /* Connection has been fully established now. Everything is ok. */
1484 SILC_LOG_DEBUG(("New connection authenticated"));
1486 /* Perform keepalive. The `hb_context' will be freed automatically
1487 when finally calling the silc_socket_free function. */
1488 hb_context = silc_calloc(1, sizeof(*hb_context));
1489 hb_context->server = server;
1490 silc_socket_set_heartbeat(sock, hearbeat_timeout, hb_context,
1491 silc_server_perform_heartbeat,
1495 silc_schedule_task_del_by_callback(server->schedule,
1496 silc_server_failure_callback);
1497 silc_protocol_free(protocol);
1499 silc_packet_context_free(ctx->packet);
1501 silc_ske_free(ctx->ske);
1502 silc_free(ctx->dest_id);
1504 sock->protocol = NULL;
1507 /* This function is used to read packets from network and send packets to
1508 network. This is usually a generic task. */
1510 SILC_TASK_CALLBACK(silc_server_packet_process)
1512 SilcServer server = (SilcServer)context;
1513 SilcSocketConnection sock = server->sockets[fd];
1514 SilcIDListData idata;
1515 SilcCipher cipher = NULL;
1516 SilcHmac hmac = NULL;
1517 uint32 sequence = 0;
1523 SILC_LOG_DEBUG(("Processing packet"));
1525 /* Packet sending */
1527 if (type == SILC_TASK_WRITE) {
1528 /* Do not send data to disconnected connection */
1529 if (SILC_IS_DISCONNECTED(sock))
1532 server->stat.packets_sent++;
1534 if (sock->outbuf->data - sock->outbuf->head)
1535 silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
1537 /* Send the packet */
1538 ret = silc_packet_send(sock, TRUE);
1540 /* If returned -2 could not write to connection now, will do
1546 SILC_LOG_ERROR(("Error sending packet to connection "
1547 "%s:%d [%s]", sock->hostname, sock->port,
1548 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1549 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1550 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1555 /* The packet has been sent and now it is time to set the connection
1556 back to only for input. When there is again some outgoing data
1557 available for this connection it will be set for output as well.
1558 This call clears the output setting and sets it only for input. */
1559 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1560 SILC_UNSET_OUTBUF_PENDING(sock);
1562 silc_buffer_clear(sock->outbuf);
1566 /* Packet receiving */
1568 /* Read some data from connection */
1569 ret = silc_packet_receive(sock);
1573 SILC_LOG_ERROR(("Error receiving packet from connection "
1574 "%s:%d [%s] %s", sock->hostname, sock->port,
1575 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1576 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1577 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1578 "Router"), strerror(errno)));
1584 SILC_LOG_DEBUG(("Read EOF"));
1586 /* If connection is disconnecting already we will finally
1587 close the connection */
1588 if (SILC_IS_DISCONNECTING(sock)) {
1589 if (sock->user_data)
1590 silc_server_free_sock_user_data(server, sock, NULL);
1591 silc_server_close_connection(server, sock);
1595 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1596 SILC_SET_DISCONNECTING(sock);
1598 if (sock->user_data) {
1600 if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1))
1601 silc_server_free_sock_user_data(server, sock, tmp);
1603 silc_server_free_sock_user_data(server, sock, NULL);
1604 } else if (server->router_conn && server->router_conn->sock == sock &&
1605 !server->router && server->standalone)
1606 silc_schedule_task_add(server->schedule, 0,
1607 silc_server_connect_to_router,
1610 SILC_TASK_PRI_NORMAL);
1612 silc_server_close_connection(server, sock);
1616 /* If connection is disconnecting or disconnected we will ignore
1618 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1619 SILC_LOG_DEBUG(("Ignoring read data from disonnected connection"));
1623 server->stat.packets_received++;
1625 /* Get keys and stuff from ID entry */
1626 idata = (SilcIDListData)sock->user_data;
1628 cipher = idata->receive_key;
1629 hmac = idata->hmac_receive;
1630 sequence = idata->psn_receive;
1633 /* Process the packet. This will call the parser that will then
1634 decrypt and parse the packet. */
1635 ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1636 TRUE : FALSE, cipher, hmac, sequence,
1637 silc_server_packet_parse, server);
1639 /* If this socket connection is not authenticated yet and the packet
1640 processing failed we will drop the connection since it can be
1641 a malicious flooder. */
1642 if (sock->type == SILC_SOCKET_TYPE_UNKNOWN && ret == FALSE &&
1643 (!sock->protocol || sock->protocol->protocol->type ==
1644 SILC_PROTOCOL_SERVER_KEY_EXCHANGE)) {
1645 SILC_LOG_DEBUG(("Bad data sent from unknown connection %d", sock->sock));
1646 SILC_SET_DISCONNECTING(sock);
1648 if (sock->user_data)
1649 silc_server_free_sock_user_data(server, sock, NULL);
1650 silc_server_close_connection(server, sock);
1654 /* Parses whole packet, received earlier. */
1656 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1658 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1659 SilcServer server = (SilcServer)parse_ctx->context;
1660 SilcSocketConnection sock = parse_ctx->sock;
1661 SilcPacketContext *packet = parse_ctx->packet;
1662 SilcIDListData idata = (SilcIDListData)sock->user_data;
1665 SILC_LOG_DEBUG(("Start"));
1667 /* Parse the packet */
1668 if (parse_ctx->normal)
1669 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1671 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1673 /* If entry is disabled ignore what we got. */
1674 if (ret != SILC_PACKET_RESUME_ROUTER &&
1675 idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1676 SILC_LOG_DEBUG(("Connection is disabled"));
1680 if (ret == SILC_PACKET_NONE)
1683 /* Check that the the current client ID is same as in the client's packet. */
1684 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1685 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1686 if (client && client->id) {
1687 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1688 packet->src_id_type);
1689 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1697 if (server->server_type == SILC_ROUTER) {
1698 /* Route the packet if it is not destined to us. Other ID types but
1699 server are handled separately after processing them. */
1700 if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1701 packet->dst_id_type == SILC_ID_SERVER &&
1702 sock->type != SILC_SOCKET_TYPE_CLIENT &&
1703 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1705 /* Route the packet to fastest route for the destination ID */
1706 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1707 packet->dst_id_type);
1710 silc_server_packet_route(server,
1711 silc_server_route_get(server, id,
1712 packet->dst_id_type),
1719 /* Parse the incoming packet type */
1720 silc_server_packet_parse_type(server, sock, packet);
1722 if (server->server_type == SILC_ROUTER) {
1723 /* Broadcast packet if it is marked as broadcast packet and it is
1724 originated from router and we are router. */
1725 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1726 packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1727 !server->standalone) {
1728 /* Broadcast to our primary route */
1729 silc_server_packet_broadcast(server, server->router->connection, packet);
1731 /* If we have backup routers then we need to feed all broadcast
1732 data to those servers. */
1733 silc_server_backup_broadcast(server, sock, packet);
1738 silc_packet_context_free(packet);
1739 silc_free(parse_ctx);
1742 /* Parser callback called by silc_packet_receive_process. This merely
1743 registers timeout that will handle the actual parsing when appropriate. */
1745 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1748 SilcServer server = (SilcServer)context;
1749 SilcSocketConnection sock = parser_context->sock;
1750 SilcIDListData idata = (SilcIDListData)sock->user_data;
1753 idata->psn_receive = parser_context->packet->sequence + 1;
1755 /* If protocol for this connection is key exchange or rekey then we'll
1756 process all packets synchronously, since there might be packets in
1757 queue that we are not able to decrypt without first processing the
1758 packets before them. */
1759 if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1760 parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1761 (sock->protocol && sock->protocol->protocol &&
1762 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1763 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1764 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1767 /* Reprocess data since we'll return FALSE here. This is because
1768 the idata->receive_key might have become valid in the last packet
1769 and we want to call this processor with valid cipher. */
1771 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1772 TRUE : FALSE, idata->receive_key,
1773 idata->hmac_receive, idata->psn_receive,
1774 silc_server_packet_parse, server);
1776 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1777 TRUE : FALSE, NULL, NULL, 0,
1778 silc_server_packet_parse, server);
1782 switch (sock->type) {
1783 case SILC_SOCKET_TYPE_UNKNOWN:
1784 case SILC_SOCKET_TYPE_CLIENT:
1785 /* Parse the packet with timeout */
1786 silc_schedule_task_add(server->schedule, sock->sock,
1787 silc_server_packet_parse_real,
1788 (void *)parser_context, 0, 100000,
1790 SILC_TASK_PRI_NORMAL);
1792 case SILC_SOCKET_TYPE_SERVER:
1793 case SILC_SOCKET_TYPE_ROUTER:
1794 /* Packets from servers are parsed immediately */
1795 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1805 /* Parses the packet type and calls what ever routines the packet type
1806 requires. This is done for all incoming packets. */
1808 void silc_server_packet_parse_type(SilcServer server,
1809 SilcSocketConnection sock,
1810 SilcPacketContext *packet)
1812 SilcPacketType type = packet->type;
1813 SilcIDListData idata = (SilcIDListData)sock->user_data;
1815 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1817 /* Parse the packet type */
1819 case SILC_PACKET_DISCONNECT:
1820 SILC_LOG_DEBUG(("Disconnect packet"));
1821 if (packet->flags & SILC_PACKET_FLAG_LIST)
1825 case SILC_PACKET_SUCCESS:
1827 * Success received for something. For now we can have only
1828 * one protocol for connection executing at once hence this
1829 * success message is for whatever protocol is executing currently.
1831 SILC_LOG_DEBUG(("Success packet"));
1832 if (packet->flags & SILC_PACKET_FLAG_LIST)
1835 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1838 case SILC_PACKET_FAILURE:
1840 * Failure received for something. For now we can have only
1841 * one protocol for connection executing at once hence this
1842 * failure message is for whatever protocol is executing currently.
1844 SILC_LOG_DEBUG(("Failure packet"));
1845 if (packet->flags & SILC_PACKET_FLAG_LIST)
1847 if (sock->protocol) {
1848 SilcServerFailureContext f;
1849 f = silc_calloc(1, sizeof(*f));
1853 /* We will wait 5 seconds to process this failure packet */
1854 silc_schedule_task_add(server->schedule, sock->sock,
1855 silc_server_failure_callback, (void *)f, 5, 0,
1856 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1860 case SILC_PACKET_REJECT:
1861 SILC_LOG_DEBUG(("Reject packet"));
1862 if (packet->flags & SILC_PACKET_FLAG_LIST)
1867 case SILC_PACKET_NOTIFY:
1869 * Received notify packet. Server can receive notify packets from
1870 * router. Server then relays the notify messages to clients if needed.
1872 SILC_LOG_DEBUG(("Notify packet"));
1873 if (packet->flags & SILC_PACKET_FLAG_LIST)
1874 silc_server_notify_list(server, sock, packet);
1876 silc_server_notify(server, sock, packet);
1882 case SILC_PACKET_CHANNEL_MESSAGE:
1884 * Received channel message. Channel messages are special packets
1885 * (although probably most common ones) thus they are handled
1888 SILC_LOG_DEBUG(("Channel Message packet"));
1889 if (packet->flags & SILC_PACKET_FLAG_LIST)
1891 idata->last_receive = time(NULL);
1892 silc_server_channel_message(server, sock, packet);
1895 case SILC_PACKET_CHANNEL_KEY:
1897 * Received key for channel. As channels are created by the router
1898 * the keys are as well. We will distribute the key to all of our
1899 * locally connected clients on the particular channel. Router
1900 * never receives this channel and thus is ignored.
1902 SILC_LOG_DEBUG(("Channel Key packet"));
1903 if (packet->flags & SILC_PACKET_FLAG_LIST)
1905 silc_server_channel_key(server, sock, packet);
1911 case SILC_PACKET_COMMAND:
1913 * Recived command. Processes the command request and allocates the
1914 * command context and calls the command.
1916 SILC_LOG_DEBUG(("Command packet"));
1917 if (packet->flags & SILC_PACKET_FLAG_LIST)
1919 silc_server_command_process(server, sock, packet);
1922 case SILC_PACKET_COMMAND_REPLY:
1924 * Received command reply packet. Received command reply to command. It
1925 * may be reply to command sent by us or reply to command sent by client
1926 * that we've routed further.
1928 SILC_LOG_DEBUG(("Command Reply packet"));
1929 if (packet->flags & SILC_PACKET_FLAG_LIST)
1931 silc_server_command_reply(server, sock, packet);
1935 * Private Message packets
1937 case SILC_PACKET_PRIVATE_MESSAGE:
1939 * Received private message packet. The packet is coming from either
1942 SILC_LOG_DEBUG(("Private Message packet"));
1943 if (packet->flags & SILC_PACKET_FLAG_LIST)
1945 idata->last_receive = time(NULL);
1946 silc_server_private_message(server, sock, packet);
1949 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1951 * Private message key packet.
1953 if (packet->flags & SILC_PACKET_FLAG_LIST)
1955 silc_server_private_message_key(server, sock, packet);
1959 * Key Exchange protocol packets
1961 case SILC_PACKET_KEY_EXCHANGE:
1962 SILC_LOG_DEBUG(("KE packet"));
1963 if (packet->flags & SILC_PACKET_FLAG_LIST)
1966 if (sock->protocol && sock->protocol->protocol &&
1967 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
1969 SilcServerKEInternalContext *proto_ctx =
1970 (SilcServerKEInternalContext *)sock->protocol->context;
1972 proto_ctx->packet = silc_packet_context_dup(packet);
1974 /* Let the protocol handle the packet */
1975 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
1977 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1978 "protocol active, packet dropped."));
1982 case SILC_PACKET_KEY_EXCHANGE_1:
1983 SILC_LOG_DEBUG(("KE 1 packet"));
1984 if (packet->flags & SILC_PACKET_FLAG_LIST)
1987 if (sock->protocol && sock->protocol->protocol &&
1988 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1989 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
1991 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
1992 SilcServerRekeyInternalContext *proto_ctx =
1993 (SilcServerRekeyInternalContext *)sock->protocol->context;
1995 if (proto_ctx->packet)
1996 silc_packet_context_free(proto_ctx->packet);
1998 proto_ctx->packet = silc_packet_context_dup(packet);
2000 /* Let the protocol handle the packet */
2001 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2003 SilcServerKEInternalContext *proto_ctx =
2004 (SilcServerKEInternalContext *)sock->protocol->context;
2006 if (proto_ctx->packet)
2007 silc_packet_context_free(proto_ctx->packet);
2009 proto_ctx->packet = silc_packet_context_dup(packet);
2010 proto_ctx->dest_id_type = packet->src_id_type;
2011 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2012 packet->src_id_type);
2013 if (!proto_ctx->dest_id)
2016 /* Let the protocol handle the packet */
2017 silc_protocol_execute(sock->protocol, server->schedule,
2021 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
2022 "protocol active, packet dropped."));
2026 case SILC_PACKET_KEY_EXCHANGE_2:
2027 SILC_LOG_DEBUG(("KE 2 packet"));
2028 if (packet->flags & SILC_PACKET_FLAG_LIST)
2031 if (sock->protocol && sock->protocol->protocol &&
2032 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
2033 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
2035 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2036 SilcServerRekeyInternalContext *proto_ctx =
2037 (SilcServerRekeyInternalContext *)sock->protocol->context;
2039 if (proto_ctx->packet)
2040 silc_packet_context_free(proto_ctx->packet);
2042 proto_ctx->packet = silc_packet_context_dup(packet);
2044 /* Let the protocol handle the packet */
2045 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2047 SilcServerKEInternalContext *proto_ctx =
2048 (SilcServerKEInternalContext *)sock->protocol->context;
2050 if (proto_ctx->packet)
2051 silc_packet_context_free(proto_ctx->packet);
2053 proto_ctx->packet = silc_packet_context_dup(packet);
2054 proto_ctx->dest_id_type = packet->src_id_type;
2055 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2056 packet->src_id_type);
2057 if (!proto_ctx->dest_id)
2060 /* Let the protocol handle the packet */
2061 silc_protocol_execute(sock->protocol, server->schedule,
2065 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
2066 "protocol active, packet dropped."));
2070 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2072 * Connection authentication request packet. When we receive this packet
2073 * we will send to the other end information about our mandatory
2074 * authentication method for the connection. This packet maybe received
2077 SILC_LOG_DEBUG(("Connection authentication request packet"));
2078 if (packet->flags & SILC_PACKET_FLAG_LIST)
2080 silc_server_connection_auth_request(server, sock, packet);
2084 * Connection Authentication protocol packets
2086 case SILC_PACKET_CONNECTION_AUTH:
2087 /* Start of the authentication protocol. We receive here the
2088 authentication data and will verify it. */
2089 SILC_LOG_DEBUG(("Connection auth packet"));
2090 if (packet->flags & SILC_PACKET_FLAG_LIST)
2093 if (sock->protocol && sock->protocol->protocol->type
2094 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2096 SilcServerConnAuthInternalContext *proto_ctx =
2097 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2099 proto_ctx->packet = silc_packet_context_dup(packet);
2101 /* Let the protocol handle the packet */
2102 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2104 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2105 "protocol active, packet dropped."));
2109 case SILC_PACKET_NEW_ID:
2111 * Received New ID packet. This includes some new ID that has been
2112 * created. It may be for client, server or channel. This is the way
2113 * to distribute information about new registered entities in the
2116 SILC_LOG_DEBUG(("New ID packet"));
2117 if (packet->flags & SILC_PACKET_FLAG_LIST)
2118 silc_server_new_id_list(server, sock, packet);
2120 silc_server_new_id(server, sock, packet);
2123 case SILC_PACKET_NEW_CLIENT:
2125 * Received new client packet. This includes client information that
2126 * we will use to create initial client ID. After creating new
2127 * ID we will send it to the client.
2129 SILC_LOG_DEBUG(("New Client packet"));
2130 if (packet->flags & SILC_PACKET_FLAG_LIST)
2132 silc_server_new_client(server, sock, packet);
2135 case SILC_PACKET_NEW_SERVER:
2137 * Received new server packet. This includes Server ID and some other
2138 * information that we may save. This is received after server has
2141 SILC_LOG_DEBUG(("New Server packet"));
2142 if (packet->flags & SILC_PACKET_FLAG_LIST)
2144 silc_server_new_server(server, sock, packet);
2147 case SILC_PACKET_NEW_CHANNEL:
2149 * Received new channel packet. Information about new channel in the
2150 * network are distributed using this packet.
2152 SILC_LOG_DEBUG(("New Channel packet"));
2153 if (packet->flags & SILC_PACKET_FLAG_LIST)
2154 silc_server_new_channel_list(server, sock, packet);
2156 silc_server_new_channel(server, sock, packet);
2159 case SILC_PACKET_HEARTBEAT:
2161 * Received heartbeat.
2163 SILC_LOG_DEBUG(("Heartbeat packet"));
2164 if (packet->flags & SILC_PACKET_FLAG_LIST)
2168 case SILC_PACKET_KEY_AGREEMENT:
2170 * Received heartbeat.
2172 SILC_LOG_DEBUG(("Key agreement packet"));
2173 if (packet->flags & SILC_PACKET_FLAG_LIST)
2175 silc_server_key_agreement(server, sock, packet);
2178 case SILC_PACKET_REKEY:
2180 * Received re-key packet. The sender wants to regenerate the session
2183 SILC_LOG_DEBUG(("Re-key packet"));
2184 if (packet->flags & SILC_PACKET_FLAG_LIST)
2186 silc_server_rekey(server, sock, packet);
2189 case SILC_PACKET_REKEY_DONE:
2191 * The re-key is done.
2193 SILC_LOG_DEBUG(("Re-key done packet"));
2194 if (packet->flags & SILC_PACKET_FLAG_LIST)
2197 if (sock->protocol && sock->protocol->protocol &&
2198 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2200 SilcServerRekeyInternalContext *proto_ctx =
2201 (SilcServerRekeyInternalContext *)sock->protocol->context;
2203 if (proto_ctx->packet)
2204 silc_packet_context_free(proto_ctx->packet);
2206 proto_ctx->packet = silc_packet_context_dup(packet);
2208 /* Let the protocol handle the packet */
2209 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2211 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2212 "protocol active, packet dropped."));
2216 case SILC_PACKET_FTP:
2218 SILC_LOG_DEBUG(("FTP packet"));
2219 if (packet->flags & SILC_PACKET_FLAG_LIST)
2221 silc_server_ftp(server, sock, packet);
2224 case SILC_PACKET_RESUME_ROUTER:
2225 /* Resume router packet received. This packet is received for backup
2226 router resuming protocol. */
2227 SILC_LOG_DEBUG(("Resume router packet"));
2228 if (packet->flags & SILC_PACKET_FLAG_LIST)
2230 silc_server_backup_resume_router(server, sock, packet);
2234 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2240 /* Creates connection to a remote router. */
2242 void silc_server_create_connection(SilcServer server,
2243 const char *remote_host, uint32 port)
2245 SilcServerConnection sconn;
2247 /* Allocate connection object for hold connection specific stuff. */
2248 sconn = silc_calloc(1, sizeof(*sconn));
2249 sconn->server = server;
2250 sconn->remote_host = strdup(remote_host);
2251 sconn->remote_port = port;
2252 sconn->no_reconnect = TRUE;
2253 sconn->param = &server->config->param;
2255 silc_schedule_task_add(server->schedule, 0,
2256 silc_server_connect_router,
2257 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
2258 SILC_TASK_PRI_NORMAL);
2261 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2263 silc_socket_free((SilcSocketConnection)context);
2266 /* Closes connection to socket connection */
2268 void silc_server_close_connection(SilcServer server,
2269 SilcSocketConnection sock)
2271 if (!server->sockets[sock->sock])
2274 SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2276 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2277 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2278 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2281 /* We won't listen for this connection anymore */
2282 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2284 /* Unregister all tasks */
2285 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2287 /* Close the actual connection */
2288 silc_net_close_connection(sock->sock);
2289 server->sockets[sock->sock] = NULL;
2291 /* If sock->user_data is NULL then we'll check for active protocols
2292 here since the silc_server_free_sock_user_data has not been called
2293 for this connection. */
2294 if (!sock->user_data) {
2295 /* If any protocol is active cancel its execution. It will call
2296 the final callback which will finalize the disconnection. */
2297 if (sock->protocol) {
2298 silc_protocol_cancel(sock->protocol, server->schedule);
2299 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2300 silc_protocol_execute_final(sock->protocol, server->schedule);
2301 sock->protocol = NULL;
2306 silc_schedule_task_add(server->schedule, 0,
2307 silc_server_close_connection_final,
2308 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
2309 SILC_TASK_PRI_NORMAL);
2312 /* Sends disconnect message to remote connection and disconnects the
2315 void silc_server_disconnect_remote(SilcServer server,
2316 SilcSocketConnection sock,
2317 const char *fmt, ...)
2320 unsigned char buf[4096];
2325 memset(buf, 0, sizeof(buf));
2327 vsprintf(buf, fmt, ap);
2330 SILC_LOG_DEBUG(("Disconnecting remote host"));
2332 /* Notify remote end that the conversation is over. The notify message
2333 is tried to be sent immediately. */
2334 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
2335 buf, strlen(buf), TRUE);
2337 /* Mark the connection to be disconnected */
2338 SILC_SET_DISCONNECTED(sock);
2339 silc_server_close_connection(server, sock);
2344 SilcClientEntry client;
2345 } *FreeClientInternal;
2347 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2349 FreeClientInternal i = (FreeClientInternal)context;
2351 silc_idlist_del_data(i->client);
2352 silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2356 /* Frees client data and notifies about client's signoff. */
2358 void silc_server_free_client_data(SilcServer server,
2359 SilcSocketConnection sock,
2360 SilcClientEntry client,
2362 const char *signoff)
2364 FreeClientInternal i = silc_calloc(1, sizeof(*i));
2366 /* If there is pending outgoing data for the client then purge it
2367 to the network before removing the client entry. */
2368 silc_server_packet_queue_purge(server, sock);
2373 /* Send SIGNOFF notify to routers. */
2374 if (notify && !server->standalone && server->router)
2375 silc_server_send_notify_signoff(server, server->router->connection,
2376 server->server_type == SILC_SERVER ?
2377 FALSE : TRUE, client->id, signoff);
2379 /* Remove client from all channels */
2381 silc_server_remove_from_channels(server, NULL, client,
2382 TRUE, (char *)signoff, TRUE);
2384 silc_server_remove_from_channels(server, NULL, client,
2385 FALSE, NULL, FALSE);
2387 /* Update statistics */
2388 server->stat.my_clients--;
2389 server->stat.clients--;
2390 if (server->server_type == SILC_ROUTER)
2391 server->stat.cell_clients--;
2392 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2393 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2395 /* We will not delete the client entry right away. We will take it
2396 into history (for WHOWAS command) for 5 minutes */
2399 silc_schedule_task_add(server->schedule, 0,
2400 silc_server_free_client_data_timeout,
2402 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2403 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2404 client->router = NULL;
2405 client->connection = NULL;
2409 /* Frees user_data pointer from socket connection object. This also sends
2410 appropriate notify packets to the network to inform about leaving
2413 void silc_server_free_sock_user_data(SilcServer server,
2414 SilcSocketConnection sock,
2415 const char *signoff_message)
2417 SILC_LOG_DEBUG(("Start"));
2419 switch (sock->type) {
2420 case SILC_SOCKET_TYPE_CLIENT:
2422 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2423 silc_server_free_client_data(server, sock, user_data, TRUE,
2427 case SILC_SOCKET_TYPE_SERVER:
2428 case SILC_SOCKET_TYPE_ROUTER:
2430 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2431 SilcServerEntry backup_router = NULL;
2434 backup_router = silc_server_backup_get(server, user_data->id);
2436 /* If this was our primary router connection then we're lost to
2437 the outside world. */
2438 if (server->router == user_data) {
2439 /* Check whether we have a backup router connection */
2440 if (!backup_router || backup_router == user_data) {
2441 silc_schedule_task_add(server->schedule, 0,
2442 silc_server_connect_to_router,
2445 SILC_TASK_PRI_NORMAL);
2447 server->id_entry->router = NULL;
2448 server->router = NULL;
2449 server->standalone = TRUE;
2450 backup_router = NULL;
2452 SILC_LOG_INFO(("New primary router is backup router %s",
2453 backup_router->server_name));
2454 SILC_LOG_DEBUG(("New primary router is backup router %s",
2455 backup_router->server_name));
2456 server->id_entry->router = backup_router;
2457 server->router = backup_router;
2458 server->router_connect = time(0);
2459 server->backup_primary = TRUE;
2460 if (server->server_type == SILC_BACKUP_ROUTER) {
2461 server->server_type = SILC_ROUTER;
2463 /* We'll need to constantly try to reconnect to the primary
2464 router so that we'll see when it comes back online. */
2465 silc_server_backup_reconnect(server, sock->ip, sock->port,
2466 silc_server_backup_connected,
2470 /* Mark this connection as replaced */
2471 silc_server_backup_replaced_add(server, user_data->id,
2474 } else if (backup_router) {
2475 SILC_LOG_INFO(("Enabling the use of backup router %s",
2476 backup_router->server_name));
2477 SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2478 backup_router->server_name));
2480 /* Mark this connection as replaced */
2481 silc_server_backup_replaced_add(server, user_data->id,
2485 if (!backup_router) {
2486 /* Free all client entries that this server owns as they will
2487 become invalid now as well. */
2489 silc_server_remove_clients_by_server(server, user_data, TRUE);
2490 if (server->server_type == SILC_SERVER)
2491 silc_server_remove_channels_by_server(server, user_data);
2493 /* Update the client entries of this server to the new backup
2494 router. This also removes the clients that *really* was owned
2495 by the primary router and went down with the router. */
2496 silc_server_update_clients_by_server(server, user_data, backup_router,
2498 silc_server_update_servers_by_server(server, user_data, backup_router);
2499 if (server->server_type == SILC_SERVER)
2500 silc_server_update_channels_by_server(server, user_data,
2504 /* Free the server entry */
2505 silc_server_backup_del(server, user_data);
2506 silc_server_backup_replaced_del(server, user_data);
2507 silc_idlist_del_data(user_data);
2508 if (!silc_idlist_del_server(server->local_list, user_data))
2509 silc_idlist_del_server(server->global_list, user_data);
2510 server->stat.my_servers--;
2511 server->stat.servers--;
2512 if (server->server_type == SILC_ROUTER)
2513 server->stat.cell_servers--;
2515 if (backup_router) {
2516 /* Announce all of our stuff that was created about 5 minutes ago.
2517 The backup router knows all the other stuff already. */
2518 if (server->server_type == SILC_ROUTER)
2519 silc_server_announce_servers(server, FALSE, time(0) - 300,
2520 backup_router->connection);
2522 /* Announce our clients and channels to the router */
2523 silc_server_announce_clients(server, time(0) - 300,
2524 backup_router->connection);
2525 silc_server_announce_channels(server, time(0) - 300,
2526 backup_router->connection);
2532 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2534 silc_idlist_del_data(user_data);
2535 silc_free(user_data);
2540 /* If any protocol is active cancel its execution */
2541 if (sock->protocol) {
2542 silc_protocol_cancel(sock->protocol, server->schedule);
2543 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2544 silc_protocol_execute_final(sock->protocol, server->schedule);
2545 sock->protocol = NULL;
2548 sock->user_data = NULL;
2551 /* Removes client from all channels it has joined. This is used when client
2552 connection is disconnected. If the client on a channel is last, the
2553 channel is removed as well. This sends the SIGNOFF notify types. */
2555 void silc_server_remove_from_channels(SilcServer server,
2556 SilcSocketConnection sock,
2557 SilcClientEntry client,
2559 char *signoff_message,
2562 SilcChannelEntry channel;
2563 SilcChannelClientEntry chl;
2564 SilcHashTableList htl;
2567 SILC_LOG_DEBUG(("Start"));
2569 if (!client || !client->id)
2572 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2574 /* Remove the client from all channels. The client is removed from
2575 the channels' user list. */
2576 silc_hash_table_list(client->channels, &htl);
2577 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2578 channel = chl->channel;
2580 /* Remove channel from client's channel list */
2581 silc_hash_table_del(client->channels, channel);
2583 /* Remove channel if there is no users anymore */
2584 if (server->server_type == SILC_ROUTER &&
2585 silc_hash_table_count(channel->user_list) < 2) {
2587 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2588 if (silc_idlist_del_channel(server->local_list, channel))
2589 server->stat.my_channels--;
2591 silc_idlist_del_channel(server->global_list, channel);
2595 /* Remove client from channel's client list */
2596 silc_hash_table_del(channel->user_list, chl->client);
2598 /* If there is no global users on the channel anymore mark the channel
2599 as local channel. Do not check if the removed client is local client. */
2600 if (server->server_type != SILC_ROUTER && channel->global_users &&
2601 chl->client->router && !silc_server_channel_has_global(channel))
2602 channel->global_users = FALSE;
2605 server->stat.my_chanclients--;
2607 /* If there is not at least one local user on the channel then we don't
2608 need the channel entry anymore, we can remove it safely. */
2609 if (server->server_type != SILC_ROUTER &&
2610 !silc_server_channel_has_local(channel)) {
2611 /* Notify about leaving client if this channel has global users. */
2612 if (notify && channel->global_users)
2613 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2614 SILC_NOTIFY_TYPE_SIGNOFF,
2615 signoff_message ? 2 : 1,
2616 clidp->data, clidp->len,
2617 signoff_message, signoff_message ?
2618 strlen(signoff_message) : 0);
2621 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2623 if (channel->founder_key) {
2624 /* The founder auth data exists, do not remove the channel entry */
2625 SilcChannelClientEntry chl2;
2626 SilcHashTableList htl2;
2628 channel->disabled = TRUE;
2630 silc_hash_table_list(channel->user_list, &htl2);
2631 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2632 silc_hash_table_del(chl2->client->channels, channel);
2633 silc_hash_table_del(channel->user_list, chl2->client);
2636 silc_hash_table_list_reset(&htl2);
2640 /* Remove the channel entry */
2641 if (silc_idlist_del_channel(server->local_list, channel))
2642 server->stat.my_channels--;
2644 silc_idlist_del_channel(server->global_list, channel);
2648 /* Send notify to channel about client leaving SILC and thus
2649 the entire channel. */
2651 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2652 SILC_NOTIFY_TYPE_SIGNOFF,
2653 signoff_message ? 2 : 1,
2654 clidp->data, clidp->len,
2655 signoff_message, signoff_message ?
2656 strlen(signoff_message) : 0);
2658 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2659 /* Re-generate channel key */
2660 if (!silc_server_create_channel_key(server, channel, 0))
2663 /* Send the channel key to the channel. The key of course is not sent
2664 to the client who was removed from the channel. */
2665 silc_server_send_channel_key(server, client->connection, channel,
2666 server->server_type == SILC_ROUTER ?
2667 FALSE : !server->standalone);
2672 silc_hash_table_list_reset(&htl);
2673 silc_buffer_free(clidp);
2676 /* Removes client from one channel. This is used for example when client
2677 calls LEAVE command to remove itself from the channel. Returns TRUE
2678 if channel still exists and FALSE if the channel is removed when
2679 last client leaves the channel. If `notify' is FALSE notify messages
2682 int silc_server_remove_from_one_channel(SilcServer server,
2683 SilcSocketConnection sock,
2684 SilcChannelEntry channel,
2685 SilcClientEntry client,
2688 SilcChannelClientEntry chl;
2691 SILC_LOG_DEBUG(("Start"));
2693 /* Get the entry to the channel, if this client is not on the channel
2695 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2698 /* Remove the client from the channel. The client is removed from
2699 the channel's user list. */
2701 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2703 /* Remove channel from client's channel list */
2704 silc_hash_table_del(client->channels, chl->channel);
2706 /* Remove channel if there is no users anymore */
2707 if (server->server_type == SILC_ROUTER &&
2708 silc_hash_table_count(channel->user_list) < 2) {
2710 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2711 if (silc_idlist_del_channel(server->local_list, channel))
2712 server->stat.my_channels--;
2714 silc_idlist_del_channel(server->global_list, channel);
2715 silc_buffer_free(clidp);
2719 /* Remove client from channel's client list */
2720 silc_hash_table_del(channel->user_list, chl->client);
2722 /* If there is no global users on the channel anymore mark the channel
2723 as local channel. Do not check if the client is local client. */
2724 if (server->server_type != SILC_ROUTER && channel->global_users &&
2725 chl->client->router && !silc_server_channel_has_global(channel))
2726 channel->global_users = FALSE;
2729 server->stat.my_chanclients--;
2731 /* If there is not at least one local user on the channel then we don't
2732 need the channel entry anymore, we can remove it safely. */
2733 if (server->server_type != SILC_ROUTER &&
2734 !silc_server_channel_has_local(channel)) {
2735 /* Notify about leaving client if this channel has global users. */
2736 if (notify && channel->global_users)
2737 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2738 SILC_NOTIFY_TYPE_LEAVE, 1,
2739 clidp->data, clidp->len);
2741 silc_buffer_free(clidp);
2744 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2746 if (channel->founder_key) {
2747 /* The founder auth data exists, do not remove the channel entry */
2748 SilcChannelClientEntry chl2;
2749 SilcHashTableList htl2;
2751 channel->disabled = TRUE;
2753 silc_hash_table_list(channel->user_list, &htl2);
2754 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2755 silc_hash_table_del(chl2->client->channels, channel);
2756 silc_hash_table_del(channel->user_list, chl2->client);
2759 silc_hash_table_list_reset(&htl2);
2763 /* Remove the channel entry */
2764 if (silc_idlist_del_channel(server->local_list, channel))
2765 server->stat.my_channels--;
2767 silc_idlist_del_channel(server->global_list, channel);
2771 /* Send notify to channel about client leaving the channel */
2773 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2774 SILC_NOTIFY_TYPE_LEAVE, 1,
2775 clidp->data, clidp->len);
2777 silc_buffer_free(clidp);
2781 /* Timeout callback. This is called if connection is idle or for some
2782 other reason is not responding within some period of time. This
2783 disconnects the remote end. */
2785 SILC_TASK_CALLBACK(silc_server_timeout_remote)
2787 SilcServer server = (SilcServer)context;
2788 SilcSocketConnection sock = server->sockets[fd];
2790 SILC_LOG_DEBUG(("Start"));
2795 /* If we have protocol active we must assure that we call the protocol's
2796 final callback so that all the memory is freed. */
2797 if (sock->protocol) {
2798 silc_protocol_cancel(sock->protocol, server->schedule);
2799 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2800 silc_protocol_execute_final(sock->protocol, server->schedule);
2801 sock->protocol = NULL;
2805 if (sock->user_data)
2806 silc_server_free_sock_user_data(server, sock, NULL);
2808 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2809 "Connection timeout");
2812 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
2813 function may be used only by router. In real SILC network all channels
2814 are created by routers thus this function is never used by normal
2817 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
2818 SilcServerID *router_id,
2824 SilcChannelID *channel_id;
2825 SilcChannelEntry entry;
2829 SILC_LOG_DEBUG(("Creating new channel"));
2832 cipher = SILC_DEFAULT_CIPHER;
2834 hmac = SILC_DEFAULT_HMAC;
2836 /* Allocate cipher */
2837 if (!silc_cipher_alloc(cipher, &key))
2841 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2842 silc_cipher_free(key);
2846 channel_name = strdup(channel_name);
2848 /* Create the channel ID */
2849 if (!silc_id_create_channel_id(server, router_id, server->rng,
2851 silc_free(channel_name);
2852 silc_cipher_free(key);
2853 silc_hmac_free(newhmac);
2857 /* Create the channel */
2858 entry = silc_idlist_add_channel(server->local_list, channel_name,
2859 SILC_CHANNEL_MODE_NONE, channel_id,
2860 NULL, key, newhmac, 0);
2862 silc_free(channel_name);
2863 silc_cipher_free(key);
2864 silc_hmac_free(newhmac);
2865 silc_free(channel_id);
2869 entry->cipher = strdup(cipher);
2870 entry->hmac_name = strdup(hmac);
2872 /* Now create the actual key material */
2873 if (!silc_server_create_channel_key(server, entry,
2874 silc_cipher_get_key_len(key) / 8)) {
2875 silc_idlist_del_channel(server->local_list, entry);
2879 /* Notify other routers about the new channel. We send the packet
2880 to our primary route. */
2881 if (broadcast && server->standalone == FALSE)
2882 silc_server_send_new_channel(server, server->router->connection, TRUE,
2883 channel_name, entry->id,
2884 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2887 server->stat.my_channels++;
2892 /* Same as above but creates the channel with Channel ID `channel_id. */
2895 silc_server_create_new_channel_with_id(SilcServer server,
2899 SilcChannelID *channel_id,
2902 SilcChannelEntry entry;
2906 SILC_LOG_DEBUG(("Creating new channel"));
2909 cipher = SILC_DEFAULT_CIPHER;
2911 hmac = SILC_DEFAULT_HMAC;
2913 /* Allocate cipher */
2914 if (!silc_cipher_alloc(cipher, &key))
2918 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2919 silc_cipher_free(key);
2923 channel_name = strdup(channel_name);
2925 /* Create the channel */
2926 entry = silc_idlist_add_channel(server->local_list, channel_name,
2927 SILC_CHANNEL_MODE_NONE, channel_id,
2928 NULL, key, newhmac, 0);
2930 silc_cipher_free(key);
2931 silc_hmac_free(newhmac);
2932 silc_free(channel_name);
2936 /* Now create the actual key material */
2937 if (!silc_server_create_channel_key(server, entry,
2938 silc_cipher_get_key_len(key) / 8)) {
2939 silc_idlist_del_channel(server->local_list, entry);
2943 /* Notify other routers about the new channel. We send the packet
2944 to our primary route. */
2945 if (broadcast && server->standalone == FALSE)
2946 silc_server_send_new_channel(server, server->router->connection, TRUE,
2947 channel_name, entry->id,
2948 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2951 server->stat.my_channels++;
2956 /* Channel's key re-key timeout callback. */
2958 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
2960 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
2961 SilcServer server = (SilcServer)rekey->context;
2965 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
2968 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
2971 /* Generates new channel key. This is used to create the initial channel key
2972 but also to re-generate new key for channel. If `key_len' is provided
2973 it is the bytes of the key length. */
2975 bool silc_server_create_channel_key(SilcServer server,
2976 SilcChannelEntry channel,
2980 unsigned char channel_key[32], hash[32];
2983 SILC_LOG_DEBUG(("Generating channel key"));
2985 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2986 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
2990 if (!channel->channel_key)
2991 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
2992 channel->channel_key = NULL;
2998 else if (channel->key_len)
2999 len = channel->key_len / 8;
3001 len = silc_cipher_get_key_len(channel->channel_key) / 8;
3003 /* Create channel key */
3004 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3007 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
3009 /* Remove old key if exists */
3011 memset(channel->key, 0, channel->key_len / 8);
3012 silc_free(channel->key);
3016 channel->key_len = len * 8;
3017 channel->key = silc_calloc(len, sizeof(*channel->key));
3018 memcpy(channel->key, channel_key, len);
3019 memset(channel_key, 0, sizeof(channel_key));
3021 /* Generate HMAC key from the channel key data and set it */
3023 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3024 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3025 silc_hmac_set_key(channel->hmac, hash,
3026 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3027 memset(hash, 0, sizeof(hash));
3029 if (server->server_type == SILC_ROUTER) {
3030 if (!channel->rekey)
3031 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3032 channel->rekey->context = (void *)server;
3033 channel->rekey->channel = channel;
3034 channel->rekey->key_len = key_len;
3035 if (channel->rekey->task)
3036 silc_schedule_task_del(server->schedule, channel->rekey->task);
3038 channel->rekey->task =
3039 silc_schedule_task_add(server->schedule, 0,
3040 silc_server_channel_key_rekey,
3041 (void *)channel->rekey, 3600, 0,
3043 SILC_TASK_PRI_NORMAL);
3049 /* Saves the channel key found in the encoded `key_payload' buffer. This
3050 function is used when we receive Channel Key Payload and also when we're
3051 processing JOIN command reply. Returns entry to the channel. */
3053 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3054 SilcBuffer key_payload,
3055 SilcChannelEntry channel)
3057 SilcChannelKeyPayload payload = NULL;
3058 SilcChannelID *id = NULL;
3059 unsigned char *tmp, hash[32];
3063 SILC_LOG_DEBUG(("Start"));
3065 /* Decode channel key payload */
3066 payload = silc_channel_key_payload_parse(key_payload->data,
3069 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3074 /* Get the channel entry */
3077 /* Get channel ID */
3078 tmp = silc_channel_key_get_id(payload, &tmp_len);
3079 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
3085 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
3087 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
3089 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3090 silc_id_render(id, SILC_ID_CHANNEL)));
3096 tmp = silc_channel_key_get_key(payload, &tmp_len);
3102 cipher = silc_channel_key_get_cipher(payload, NULL);
3108 /* Remove old key if exists */
3110 memset(channel->key, 0, channel->key_len / 8);
3111 silc_free(channel->key);
3112 silc_cipher_free(channel->channel_key);
3115 /* Create new cipher */
3116 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3117 channel->channel_key = NULL;
3122 if (channel->cipher)
3123 silc_free(channel->cipher);
3124 channel->cipher = strdup(cipher);
3127 channel->key_len = tmp_len * 8;
3128 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
3129 memcpy(channel->key, tmp, tmp_len);
3130 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3132 /* Generate HMAC key from the channel key data and set it */
3134 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3135 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3136 silc_hmac_set_key(channel->hmac, hash,
3137 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3139 memset(hash, 0, sizeof(hash));
3140 memset(tmp, 0, tmp_len);
3142 if (server->server_type == SILC_ROUTER) {
3143 if (!channel->rekey)
3144 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3145 channel->rekey->context = (void *)server;
3146 channel->rekey->channel = channel;
3147 if (channel->rekey->task)
3148 silc_schedule_task_del(server->schedule, channel->rekey->task);
3150 channel->rekey->task =
3151 silc_schedule_task_add(server->schedule, 0,
3152 silc_server_channel_key_rekey,
3153 (void *)channel->rekey, 3600, 0,
3155 SILC_TASK_PRI_NORMAL);
3161 silc_channel_key_payload_free(payload);
3166 /* Heartbeat callback. This function is set as argument for the
3167 silc_socket_set_heartbeat function. The library will call this function
3168 at the set time interval. */
3170 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3173 SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3175 SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
3177 /* Send the heartbeat */
3178 silc_server_send_heartbeat(hb->server, sock);
3181 /* Returns assembled of all servers in the given ID list. The packet's
3182 form is dictated by the New ID payload. */
3184 static void silc_server_announce_get_servers(SilcServer server,
3185 SilcServerEntry remote,
3187 SilcBuffer *servers,
3188 unsigned long creation_time)
3190 SilcIDCacheList list;
3191 SilcIDCacheEntry id_cache;
3192 SilcServerEntry entry;
3195 /* Go through all clients in the list */
3196 if (silc_idcache_get_all(id_list->servers, &list)) {
3197 if (silc_idcache_list_first(list, &id_cache)) {
3199 entry = (SilcServerEntry)id_cache->context;
3201 /* Do not announce the one we've sending our announcements and
3202 do not announce ourself. Also check the creation time if it's
3204 if ((entry == remote) || (entry == server->id_entry) ||
3205 (creation_time && entry->data.created < creation_time)) {
3206 if (!silc_idcache_list_next(list, &id_cache))
3211 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3213 *servers = silc_buffer_realloc(*servers,
3215 (*servers)->truelen + idp->len :
3217 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3218 silc_buffer_put(*servers, idp->data, idp->len);
3219 silc_buffer_pull(*servers, idp->len);
3220 silc_buffer_free(idp);
3222 if (!silc_idcache_list_next(list, &id_cache))
3227 silc_idcache_list_free(list);
3232 silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
3238 p = silc_notify_payload_encode(notify, argc, ap);
3244 /* This function is used by router to announce existing servers to our
3245 primary router when we've connected to it. If `creation_time' is non-zero
3246 then only the servers that has been created after the `creation_time'
3247 will be announced. */
3249 void silc_server_announce_servers(SilcServer server, bool global,
3250 unsigned long creation_time,
3251 SilcSocketConnection remote)
3253 SilcBuffer servers = NULL;
3255 SILC_LOG_DEBUG(("Announcing servers"));
3257 /* Get servers in local list */
3258 silc_server_announce_get_servers(server, remote->user_data,
3259 server->local_list, &servers,
3263 /* Get servers in global list */
3264 silc_server_announce_get_servers(server, remote->user_data,
3265 server->global_list, &servers,
3269 silc_buffer_push(servers, servers->data - servers->head);
3270 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3272 /* Send the packet */
3273 silc_server_packet_send(server, remote,
3274 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3275 servers->data, servers->len, TRUE);
3277 silc_buffer_free(servers);
3281 /* Returns assembled packet of all clients in the given ID list. The
3282 packet's form is dictated by the New ID Payload. */
3284 static void silc_server_announce_get_clients(SilcServer server,
3286 SilcBuffer *clients,
3288 unsigned long creation_time)
3290 SilcIDCacheList list;
3291 SilcIDCacheEntry id_cache;
3292 SilcClientEntry client;
3295 unsigned char mode[4];
3297 /* Go through all clients in the list */
3298 if (silc_idcache_get_all(id_list->clients, &list)) {
3299 if (silc_idcache_list_first(list, &id_cache)) {
3301 client = (SilcClientEntry)id_cache->context;
3303 if (creation_time && client->data.created < creation_time) {
3304 if (!silc_idcache_list_next(list, &id_cache))
3309 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3311 *clients = silc_buffer_realloc(*clients,
3313 (*clients)->truelen + idp->len :
3315 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3316 silc_buffer_put(*clients, idp->data, idp->len);
3317 silc_buffer_pull(*clients, idp->len);
3319 SILC_PUT32_MSB(client->mode, mode);
3320 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3321 2, idp->data, idp->len,
3323 *umodes = silc_buffer_realloc(*umodes,
3325 (*umodes)->truelen + tmp->len :
3327 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3328 silc_buffer_put(*umodes, tmp->data, tmp->len);
3329 silc_buffer_pull(*umodes, tmp->len);
3330 silc_buffer_free(tmp);
3332 silc_buffer_free(idp);
3334 if (!silc_idcache_list_next(list, &id_cache))
3339 silc_idcache_list_free(list);
3343 /* This function is used to announce our existing clients to our router
3344 when we've connected to it. If `creation_time' is non-zero then only
3345 the clients that has been created after the `creation_time' will be
3348 void silc_server_announce_clients(SilcServer server,
3349 unsigned long creation_time,
3350 SilcSocketConnection remote)
3352 SilcBuffer clients = NULL;
3353 SilcBuffer umodes = NULL;
3355 SILC_LOG_DEBUG(("Announcing clients"));
3357 /* Get clients in local list */
3358 silc_server_announce_get_clients(server, server->local_list,
3359 &clients, &umodes, creation_time);
3361 /* As router we announce our global list as well */
3362 if (server->server_type == SILC_ROUTER)
3363 silc_server_announce_get_clients(server, server->global_list,
3364 &clients, &umodes, creation_time);
3367 silc_buffer_push(clients, clients->data - clients->head);
3368 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3370 /* Send the packet */
3371 silc_server_packet_send(server, remote,
3372 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3373 clients->data, clients->len, TRUE);
3375 silc_buffer_free(clients);
3379 silc_buffer_push(umodes, umodes->data - umodes->head);
3380 SILC_LOG_HEXDUMP(("umodes"), umodes->data, umodes->len);
3382 /* Send the packet */
3383 silc_server_packet_send(server, remote,
3384 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3385 umodes->data, umodes->len, TRUE);
3387 silc_buffer_free(umodes);
3391 /* Returns channel's topic for announcing it */
3393 void silc_server_announce_get_channel_topic(SilcServer server,
3394 SilcChannelEntry channel,
3399 if (channel->topic) {
3400 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3401 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3402 chidp->data, chidp->len,
3404 strlen(channel->topic));
3405 silc_buffer_free(chidp);
3409 /* Returns assembled packets for channel users of the `channel'. */
3411 void silc_server_announce_get_channel_users(SilcServer server,
3412 SilcChannelEntry channel,
3413 SilcBuffer *channel_users,
3414 SilcBuffer *channel_users_modes)
3416 SilcChannelClientEntry chl;
3417 SilcHashTableList htl;
3418 SilcBuffer chidp, clidp;
3421 unsigned char mode[4];
3423 SILC_LOG_DEBUG(("Start"));
3425 /* Now find all users on the channel */
3426 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3427 silc_hash_table_list(channel->user_list, &htl);
3428 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3429 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3432 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
3433 clidp->data, clidp->len,
3434 chidp->data, chidp->len);
3437 silc_buffer_realloc(*channel_users,
3439 (*channel_users)->truelen + len : len));
3440 silc_buffer_pull_tail(*channel_users,
3441 ((*channel_users)->end -
3442 (*channel_users)->data));
3444 silc_buffer_put(*channel_users, tmp->data, tmp->len);
3445 silc_buffer_pull(*channel_users, len);
3446 silc_buffer_free(tmp);
3448 /* CUMODE notify for mode change on the channel */
3449 SILC_PUT32_MSB(chl->mode, mode);
3450 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
3451 3, clidp->data, clidp->len,
3453 clidp->data, clidp->len);
3455 *channel_users_modes =
3456 silc_buffer_realloc(*channel_users_modes,
3457 (*channel_users_modes ?
3458 (*channel_users_modes)->truelen + len : len));
3459 silc_buffer_pull_tail(*channel_users_modes,
3460 ((*channel_users_modes)->end -
3461 (*channel_users_modes)->data));
3463 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3464 silc_buffer_pull(*channel_users_modes, len);
3465 silc_buffer_free(tmp);
3467 silc_buffer_free(clidp);
3469 silc_hash_table_list_reset(&htl);
3470 silc_buffer_free(chidp);
3473 /* Returns assembled packets for all channels and users on those channels
3474 from the given ID List. The packets are in the form dictated by the
3475 New Channel and New Channel User payloads. */
3477 void silc_server_announce_get_channels(SilcServer server,
3479 SilcBuffer *channels,
3480 SilcBuffer *channel_users,
3481 SilcBuffer **channel_users_modes,
3482 uint32 *channel_users_modes_c,
3483 SilcBuffer **channel_topics,
3484 SilcChannelID ***channel_ids,
3485 unsigned long creation_time)
3487 SilcIDCacheList list;
3488 SilcIDCacheEntry id_cache;
3489 SilcChannelEntry channel;
3494 int i = *channel_users_modes_c;
3497 SILC_LOG_DEBUG(("Start"));
3499 /* Go through all channels in the list */
3500 if (silc_idcache_get_all(id_list->channels, &list)) {
3501 if (silc_idcache_list_first(list, &id_cache)) {
3503 channel = (SilcChannelEntry)id_cache->context;
3505 if (creation_time && channel->created < creation_time)
3510 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3511 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3512 name_len = strlen(channel->channel_name);
3515 len = 4 + name_len + id_len + 4;
3517 silc_buffer_realloc(*channels,
3518 (*channels ? (*channels)->truelen +
3520 silc_buffer_pull_tail(*channels,
3521 ((*channels)->end - (*channels)->data));
3522 silc_buffer_format(*channels,
3523 SILC_STR_UI_SHORT(name_len),
3524 SILC_STR_UI_XNSTRING(channel->channel_name,
3526 SILC_STR_UI_SHORT(id_len),
3527 SILC_STR_UI_XNSTRING(cid, id_len),
3528 SILC_STR_UI_INT(channel->mode),
3530 silc_buffer_pull(*channels, len);
3533 /* Channel user modes */
3534 *channel_users_modes = silc_realloc(*channel_users_modes,
3535 sizeof(**channel_users_modes) *
3537 (*channel_users_modes)[i] = NULL;
3538 *channel_ids = silc_realloc(*channel_ids,
3539 sizeof(**channel_ids) * (i + 1));
3540 (*channel_ids)[i] = NULL;
3541 silc_server_announce_get_channel_users(server, channel,
3543 &(*channel_users_modes)[i]);
3544 (*channel_ids)[i] = channel->id;
3546 /* Channel's topic */
3547 *channel_topics = silc_realloc(*channel_topics,
3548 sizeof(**channel_topics) * (i + 1));
3549 (*channel_topics)[i] = NULL;
3550 silc_server_announce_get_channel_topic(server, channel,
3551 &(*channel_topics)[i]);
3554 if (!silc_idcache_list_next(list, &id_cache))
3558 *channel_users_modes_c += i;
3561 silc_idcache_list_free(list);
3565 /* This function is used to announce our existing channels to our router
3566 when we've connected to it. This also announces the users on the
3567 channels to the router. If the `creation_time' is non-zero only the
3568 channels that was created after the `creation_time' are announced.
3569 Note that the channel users are still announced even if the `creation_time'
3572 void silc_server_announce_channels(SilcServer server,
3573 unsigned long creation_time,
3574 SilcSocketConnection remote)
3576 SilcBuffer channels = NULL, channel_users = NULL;
3577 SilcBuffer *channel_users_modes = NULL;
3578 SilcBuffer *channel_topics = NULL;
3579 uint32 channel_users_modes_c = 0;
3580 SilcChannelID **channel_ids = NULL;
3582 SILC_LOG_DEBUG(("Announcing channels and channel users"));
3584 /* Get channels and channel users in local list */
3585 silc_server_announce_get_channels(server, server->local_list,
3586 &channels, &channel_users,
3587 &channel_users_modes,
3588 &channel_users_modes_c,
3590 &channel_ids, creation_time);
3592 /* Get channels and channel users in global list */
3593 if (server->server_type != SILC_SERVER)
3594 silc_server_announce_get_channels(server, server->global_list,
3595 &channels, &channel_users,
3596 &channel_users_modes,
3597 &channel_users_modes_c,
3599 &channel_ids, creation_time);
3602 silc_buffer_push(channels, channels->data - channels->head);
3603 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3605 /* Send the packet */
3606 silc_server_packet_send(server, remote,
3607 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3608 channels->data, channels->len,
3611 silc_buffer_free(channels);
3614 if (channel_users) {
3615 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3616 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
3617 channel_users->len);
3619 /* Send the packet */
3620 silc_server_packet_send(server, remote,
3621 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3622 channel_users->data, channel_users->len,
3625 silc_buffer_free(channel_users);
3628 if (channel_users_modes) {
3631 for (i = 0; i < channel_users_modes_c; i++) {
3632 if (!channel_users_modes[i])
3634 silc_buffer_push(channel_users_modes[i],
3635 channel_users_modes[i]->data -
3636 channel_users_modes[i]->head);
3637 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
3638 channel_users_modes[i]->len);
3639 silc_server_packet_send_dest(server, remote,
3640 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3641 channel_ids[i], SILC_ID_CHANNEL,
3642 channel_users_modes[i]->data,
3643 channel_users_modes[i]->len,
3645 silc_buffer_free(channel_users_modes[i]);
3647 silc_free(channel_users_modes);
3650 if (channel_topics) {
3653 for (i = 0; i < channel_users_modes_c; i++) {
3654 if (!channel_topics[i])
3657 silc_buffer_push(channel_topics[i],
3658 channel_topics[i]->data -
3659 channel_topics[i]->head);
3660 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
3661 channel_topics[i]->len);
3662 silc_server_packet_send_dest(server, remote,
3663 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3664 channel_ids[i], SILC_ID_CHANNEL,
3665 channel_topics[i]->data,
3666 channel_topics[i]->len,
3668 silc_buffer_free(channel_topics[i]);
3670 silc_free(channel_topics);
3673 silc_free(channel_ids);
3676 /* Failure timeout callback. If this is called then we will immediately
3677 process the received failure. We always process the failure with timeout
3678 since we do not want to blindly trust to received failure packets.
3679 This won't be called (the timeout is cancelled) if the failure was
3680 bogus (it is bogus if remote does not close the connection after sending
3683 SILC_TASK_CALLBACK(silc_server_failure_callback)
3685 SilcServerFailureContext f = (SilcServerFailureContext)context;
3687 if (f->sock->protocol) {
3688 f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
3689 silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
3695 /* Assembles user list and users mode list from the `channel'. */
3697 void silc_server_get_users_on_channel(SilcServer server,
3698 SilcChannelEntry channel,
3699 SilcBuffer *user_list,
3700 SilcBuffer *mode_list,
3703 SilcChannelClientEntry chl;
3704 SilcHashTableList htl;
3705 SilcBuffer client_id_list;
3706 SilcBuffer client_mode_list;
3708 uint32 list_count = 0, len = 0;
3710 silc_hash_table_list(channel->user_list, &htl);
3711 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
3712 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
3713 silc_hash_table_list_reset(&htl);
3715 client_id_list = silc_buffer_alloc(len);
3717 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
3718 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
3719 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
3721 silc_hash_table_list(channel->user_list, &htl);
3722 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3724 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3725 silc_buffer_put(client_id_list, idp->data, idp->len);
3726 silc_buffer_pull(client_id_list, idp->len);
3727 silc_buffer_free(idp);
3729 /* Client's mode on channel */
3730 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
3731 silc_buffer_pull(client_mode_list, 4);
3735 silc_hash_table_list_reset(&htl);
3736 silc_buffer_push(client_id_list,
3737 client_id_list->data - client_id_list->head);
3738 silc_buffer_push(client_mode_list,
3739 client_mode_list->data - client_mode_list->head);
3741 *user_list = client_id_list;
3742 *mode_list = client_mode_list;
3743 *user_count = list_count;
3746 /* Saves users and their modes to the `channel'. */
3748 void silc_server_save_users_on_channel(SilcServer server,
3749 SilcSocketConnection sock,
3750 SilcChannelEntry channel,
3751 SilcClientID *noadd,
3752 SilcBuffer user_list,
3753 SilcBuffer mode_list,
3759 SilcClientID *client_id;
3760 SilcClientEntry client;
3761 SilcIDCacheEntry cache;
3764 SILC_LOG_DEBUG(("Start"));
3766 for (i = 0; i < user_count; i++) {
3768 SILC_GET16_MSB(idp_len, user_list->data + 2);
3770 client_id = silc_id_payload_parse_id(user_list->data, idp_len);
3771 silc_buffer_pull(user_list, idp_len);
3776 SILC_GET32_MSB(mode, mode_list->data);
3777 silc_buffer_pull(mode_list, 4);
3779 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
3780 silc_free(client_id);
3786 /* Check if we have this client cached already. */
3787 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3788 server->server_type, &cache);
3790 client = silc_idlist_find_client_by_id(server->global_list,
3791 client_id, server->server_type,
3796 /* If router did not find such Client ID in its lists then this must
3797 be bogus client or some router in the net is buggy. */
3798 if (server->server_type == SILC_ROUTER) {
3799 silc_free(client_id);
3803 /* We don't have that client anywhere, add it. The client is added
3804 to global list since server didn't have it in the lists so it must be
3806 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
3807 silc_id_dup(client_id, SILC_ID_CLIENT),
3808 sock->user_data, NULL, 0);
3810 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
3811 silc_free(client_id);
3815 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3817 /* Found, if it is from global list we'll assure that we won't
3818 expire it now that the entry is on channel. */
3823 silc_free(client_id);
3825 if (!silc_server_client_on_channel(client, channel)) {
3826 /* Client was not on the channel, add it. */
3827 SilcChannelClientEntry chl = silc_calloc(1, sizeof(*chl));
3828 chl->client = client;
3830 chl->channel = channel;
3831 silc_hash_table_add(channel->user_list, chl->client, chl);
3832 silc_hash_table_add(client->channels, chl->channel, chl);
3837 /* Lookups route to the client indicated by the `id_data'. The connection
3838 object and internal data object is returned. Returns NULL if route
3839 could not be found to the client. If the `client_id' is specified then
3840 it is used and the `id_data' is ignored. */
3842 SilcSocketConnection silc_server_get_client_route(SilcServer server,
3843 unsigned char *id_data,
3845 SilcClientID *client_id,
3846 SilcIDListData *idata)
3849 SilcClientEntry client;
3851 SILC_LOG_DEBUG(("Start"));
3853 /* Decode destination Client ID */
3855 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
3857 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
3861 id = silc_id_dup(client_id, SILC_ID_CLIENT);
3864 /* If the destination belongs to our server we don't have to route
3865 the packet anywhere but to send it to the local destination. */
3866 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
3870 /* If we are router and the client has router then the client is in
3871 our cell but not directly connected to us. */
3872 if (server->server_type == SILC_ROUTER && client->router) {
3873 /* We are of course in this case the client's router thus the route
3874 to the client is the server who owns the client. So, we will send
3875 the packet to that server. */
3877 *idata = (SilcIDListData)client->router;
3878 return client->router->connection;
3881 /* Seems that client really is directly connected to us */
3883 *idata = (SilcIDListData)client;
3884 return client->connection;
3887 /* Destination belongs to someone not in this server. If we are normal
3888 server our action is to send the packet to our router. */
3889 if (server->server_type != SILC_ROUTER && !server->standalone) {
3892 *idata = (SilcIDListData)server->router;
3893 return server->router->connection;
3896 /* We are router and we will perform route lookup for the destination
3897 and send the packet to fastest route. */
3898 if (server->server_type == SILC_ROUTER && !server->standalone) {
3899 /* Check first that the ID is valid */
3900 client = silc_idlist_find_client_by_id(server->global_list, id,
3903 SilcSocketConnection dst_sock;
3905 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
3909 *idata = (SilcIDListData)dst_sock->user_data;
3918 /* Encodes and returns channel list of channels the `client' has joined.
3919 Secret channels are not put to the list. */
3921 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
3922 SilcClientEntry client)
3924 SilcBuffer buffer = NULL;
3925 SilcChannelEntry channel;
3926 SilcChannelClientEntry chl;
3927 SilcHashTableList htl;
3933 silc_hash_table_list(client->channels, &htl);
3934 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3935 channel = chl->channel;
3937 if (channel->mode & SILC_CHANNEL_MODE_SECRET ||
3938 channel->mode & SILC_CHANNEL_MODE_PRIVATE)
3941 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3942 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3943 name_len = strlen(channel->channel_name);
3945 len = 4 + name_len + id_len + 4;
3946 buffer = silc_buffer_realloc(buffer,
3947 (buffer ? (buffer)->truelen + len : len));
3948 silc_buffer_pull_tail(buffer, ((buffer)->end - (buffer)->data));
3949 silc_buffer_format(buffer,
3950 SILC_STR_UI_SHORT(name_len),
3951 SILC_STR_UI_XNSTRING(channel->channel_name,
3953 SILC_STR_UI_SHORT(id_len),
3954 SILC_STR_UI_XNSTRING(cid, id_len),
3955 SILC_STR_UI_INT(chl->mode), /* Client's mode */
3957 silc_buffer_pull(buffer, len);
3960 silc_hash_table_list_reset(&htl);
3963 silc_buffer_push(buffer, buffer->data - buffer->head);
3968 /* Finds client entry by Client ID and if it is not found then resolves
3969 it using WHOIS command. */
3971 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
3972 SilcClientID *client_id,
3975 SilcClientEntry client;
3980 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3983 client = silc_idlist_find_client_by_id(server->global_list,
3984 client_id, TRUE, NULL);
3985 if (!client && server->server_type == SILC_ROUTER)
3989 if (!client && server->standalone)
3992 if (!client || !client->nickname || !client->username) {
3993 SilcBuffer buffer, idp;
3995 client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
3996 client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
3997 client->resolve_cmd_ident = ++server->cmd_ident;
3999 idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
4000 buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
4001 server->cmd_ident, 1,
4002 3, idp->data, idp->len);
4003 silc_server_packet_send(server, client ? client->router->connection :
4004 server->router->connection,
4005 SILC_PACKET_COMMAND, 0,
4006 buffer->data, buffer->len, FALSE);
4007 silc_buffer_free(idp);
4008 silc_buffer_free(buffer);
4019 /* A timeout callback for the re-key. We will be the initiator of the
4022 SILC_TASK_CALLBACK(silc_server_rekey_callback)
4024 SilcSocketConnection sock = (SilcSocketConnection)context;
4025 SilcIDListData idata = (SilcIDListData)sock->user_data;
4026 SilcServer server = (SilcServer)idata->rekey->context;
4027 SilcProtocol protocol;
4028 SilcServerRekeyInternalContext *proto_ctx;
4030 SILC_LOG_DEBUG(("Start"));
4032 /* Allocate internal protocol context. This is sent as context
4034 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
4035 proto_ctx->server = (void *)server;
4036 proto_ctx->sock = sock;
4037 proto_ctx->responder = FALSE;
4038 proto_ctx->pfs = idata->rekey->pfs;
4040 /* Perform rekey protocol. Will call the final callback after the
4041 protocol is over. */
4042 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
4043 &protocol, proto_ctx, silc_server_rekey_final);
4044 sock->protocol = protocol;
4046 /* Run the protocol */
4047 silc_protocol_execute(protocol, server->schedule, 0, 0);
4049 /* Re-register re-key timeout */
4050 silc_schedule_task_add(server->schedule, sock->sock,
4051 silc_server_rekey_callback,
4052 context, idata->rekey->timeout, 0,
4053 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
4056 /* The final callback for the REKEY protocol. This will actually take the
4057 new key material into use. */
4059 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
4061 SilcProtocol protocol = (SilcProtocol)context;
4062 SilcServerRekeyInternalContext *ctx =
4063 (SilcServerRekeyInternalContext *)protocol->context;
4064 SilcServer server = (SilcServer)ctx->server;
4065 SilcSocketConnection sock = ctx->sock;
4067 SILC_LOG_DEBUG(("Start"));
4069 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
4070 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
4071 /* Error occured during protocol */
4072 SILC_LOG_ERROR(("Error occurred during rekey protocol"));
4073 silc_protocol_cancel(protocol, server->schedule);
4074 silc_protocol_free(protocol);
4075 sock->protocol = NULL;
4077 silc_packet_context_free(ctx->packet);
4079 silc_ske_free(ctx->ske);
4084 /* Purge the outgoing data queue to assure that all rekey packets really
4085 go to the network before we quit the protocol. */
4086 silc_server_packet_queue_purge(server, sock);
4089 silc_protocol_free(protocol);
4090 sock->protocol = NULL;
4092 silc_packet_context_free(ctx->packet);
4094 silc_ske_free(ctx->ske);