5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * This is the actual SILC server than handles everything relating to
22 * servicing the SILC connections. This is also a SILC router as a router
23 * is also normal server.
27 #include "serverincludes.h"
28 #include "server_internal.h"
30 /* Static prototypes */
31 SILC_TASK_CALLBACK(silc_server_connect_router);
32 SILC_TASK_CALLBACK(silc_server_connect_to_router);
33 SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
34 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
35 SILC_TASK_CALLBACK(silc_server_accept_new_connection);
36 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second);
37 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final);
38 SILC_TASK_CALLBACK(silc_server_packet_process);
39 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
40 SILC_TASK_CALLBACK(silc_server_timeout_remote);
41 SILC_TASK_CALLBACK(silc_server_failure_callback);
42 SILC_TASK_CALLBACK(silc_server_rekey_callback);
44 /* Allocates a new SILC server object. This has to be done before the server
45 can be used. After allocation one must call silc_server_init to initialize
46 the server. The new allocated server object is returned to the new_server
49 int silc_server_alloc(SilcServer *new_server)
53 SILC_LOG_DEBUG(("Allocating new server object"));
55 server = silc_calloc(1, sizeof(*server));
56 server->server_type = SILC_SERVER;
57 server->standalone = TRUE;
58 server->local_list = silc_calloc(1, sizeof(*server->local_list));
59 server->global_list = silc_calloc(1, sizeof(*server->global_list));
60 server->pending_commands = silc_dlist_init();
62 server->sim = silc_dlist_init();
70 /* Free's the SILC server object. This is called at the very end before
73 void silc_server_free(SilcServer server)
80 silc_free(server->local_list);
81 silc_free(server->global_list);
83 silc_rng_free(server->rng);
86 silc_pkcs_free(server->pkcs);
89 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
90 silc_dlist_del(server->sim, sim);
93 silc_dlist_uninit(server->sim);
96 silc_free(server->params);
98 if (server->pending_commands)
99 silc_dlist_uninit(server->pending_commands);
105 /* Initializes the entire SILC server. This is called always before running
106 the server. This is called only once at the initialization of the program.
107 This binds the server to its listenning port. After this function returns
108 one should call silc_server_run to start the server. This returns TRUE
109 when everything is ok to run the server. Configuration file must be
110 read and parsed before calling this. */
112 int silc_server_init(SilcServer server)
114 int *sock = NULL, sock_count, i;
116 SilcServerEntry id_entry;
117 SilcIDListPurge purge;
118 SilcServerConfigSectionListenPort *listen;
120 SILC_LOG_DEBUG(("Initializing server"));
122 assert(server->config);
124 /* Set public and private keys */
125 if (!server->config->server_keys ||
126 !server->config->server_keys->public_key ||
127 !server->config->server_keys->private_key) {
128 SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
131 server->public_key = server->config->server_keys->public_key;
132 server->private_key = server->config->server_keys->private_key;
134 /* XXX After server is made as Silc Server Library this can be given
135 as argument, for now this is hard coded */
136 server->params = silc_calloc(1, sizeof(*server->params));
137 server->params->retry_count = SILC_SERVER_RETRY_COUNT;
138 server->params->retry_interval_min = SILC_SERVER_RETRY_INTERVAL_MIN;
139 server->params->retry_interval_max = SILC_SERVER_RETRY_INTERVAL_MAX;
140 server->params->retry_keep_trying = FALSE;
141 server->params->protocol_timeout = 60;
142 server->params->require_reverse_mapping = FALSE;
144 /* Set log files where log message should be saved. */
145 server->config->server = server;
146 silc_server_config_setlogfiles(server->config);
148 /* Register all configured ciphers, PKCS and hash functions. */
149 if (!silc_server_config_register_ciphers(server->config))
150 silc_cipher_register_default();
151 if (!silc_server_config_register_pkcs(server->config))
152 silc_pkcs_register_default();
153 if (!silc_server_config_register_hashfuncs(server->config))
154 silc_hash_register_default();
155 if (!silc_server_config_register_hmacs(server->config))
156 silc_hmac_register_default();
158 /* Initialize random number generator for the server. */
159 server->rng = silc_rng_alloc();
160 silc_rng_init(server->rng);
161 silc_rng_global_init(server->rng);
163 /* Initialize hash functions for server to use */
164 silc_hash_alloc("md5", &server->md5hash);
165 silc_hash_alloc("sha1", &server->sha1hash);
167 /* Initialize none cipher */
168 silc_cipher_alloc("none", &server->none_cipher);
170 /* Allocate PKCS context for local public and private keys */
171 silc_pkcs_alloc(server->public_key->name, &server->pkcs);
172 silc_pkcs_public_key_set(server->pkcs, server->public_key);
173 silc_pkcs_private_key_set(server->pkcs, server->private_key);
175 /* Create a listening server. Note that our server can listen on multiple
176 ports. All listeners are created here and now. */
178 listen = server->config->listen_port;
182 tmp = silc_net_create_server(server->config->listen_port->port,
183 server->config->listen_port->listener_ip);
186 SILC_LOG_ERROR(("Could not create server listener: %s on %d",
187 server->config->listen_port->listener_ip,
188 server->config->listen_port->port));
192 sock = silc_realloc(sock, sizeof(*sock) * (sock_count + 1));
193 sock[sock_count] = tmp;
195 listen = listen->next;
198 /* Initialize ID caches */
199 server->local_list->clients =
200 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
201 server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
202 server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
204 /* These are allocated for normal server as well as these hold some
205 global information that the server has fetched from its router. For
206 router these are used as they are supposed to be used on router. */
207 server->global_list->clients =
208 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
209 server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
210 server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
212 /* Allocate the entire socket list that is used in server. Eventually
213 all connections will have entry in this table (it is a table of
214 pointers to the actual object that is allocated individually
216 server->sockets = silc_calloc(SILC_SERVER_MAX_CONNECTIONS,
217 sizeof(*server->sockets));
219 for (i = 0; i < sock_count; i++) {
220 SilcSocketConnection newsocket = NULL;
222 /* Set socket to non-blocking mode */
223 silc_net_set_socket_nonblock(sock[i]);
224 server->sock = sock[i];
226 /* Add ourselves also to the socket table. The entry allocated above
227 is sent as argument for fast referencing in the future. */
228 silc_socket_alloc(sock[i], SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
229 server->sockets[sock[i]] = newsocket;
231 /* Perform name and address lookups to resolve the listenning address
233 if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname,
235 if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
237 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
238 newsocket->hostname ? newsocket->hostname :
239 newsocket->ip ? newsocket->ip : ""));
240 server->stat.conn_failures++;
243 if (!newsocket->hostname)
244 newsocket->hostname = strdup(newsocket->ip);
246 newsocket->port = silc_net_get_local_port(sock[i]);
248 /* Create a Server ID for the server. */
249 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
254 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
255 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
256 server->id_type = SILC_ID_SERVER;
257 server->server_name = server->config->server_info->server_name;
259 /* Add ourselves to the server list. We don't have a router yet
260 beacuse we haven't established a route yet. It will be done later.
261 For now, NULL is sent as router. This allocates new entry to
264 silc_idlist_add_server(server->local_list,
265 server->config->server_info->server_name,
266 server->server_type, server->id, NULL, NULL);
268 SILC_LOG_ERROR(("Could not add ourselves to cache"));
271 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
273 /* Put the allocated socket pointer also to the entry allocated above
274 for fast back-referencing to the socket list. */
275 newsocket->user_data = (void *)id_entry;
276 id_entry->connection = (void *)newsocket;
277 server->id_entry = id_entry;
280 /* Register protocols */
281 silc_server_protocols_register();
283 /* Initialize the scheduler. */
284 server->schedule = silc_schedule_init(SILC_SERVER_MAX_CONNECTIONS);
285 if (!server->schedule)
288 /* Add the first task to the scheduler. This is task that is executed by
289 timeout. It expires as soon as the caller calls silc_server_run. This
290 task performs authentication protocol and key exchange with our
292 silc_schedule_task_add(server->schedule, sock[0],
293 silc_server_connect_to_router,
294 (void *)server, 0, 1,
296 SILC_TASK_PRI_NORMAL);
298 /* Add listener task to the scheduler. This task receives new connections
299 to the server. This task remains on the queue until the end of the
301 silc_schedule_task_add(server->schedule, sock[0],
302 silc_server_accept_new_connection,
303 (void *)server, 0, 0,
305 SILC_TASK_PRI_NORMAL);
306 server->listenning = TRUE;
308 /* If server connections has been configured then we must be router as
309 normal server cannot have server connections, only router connections. */
310 if (server->config->servers) {
311 SilcServerConfigSectionServerConnection *ptr = server->config->servers;
313 server->server_type = SILC_ROUTER;
315 if (ptr->backup_router) {
316 server->server_type = SILC_BACKUP_ROUTER;
317 server->backup_router = TRUE;
318 server->id_entry->server_type = SILC_BACKUP_ROUTER;
325 /* Register the ID Cache purge task. This periodically purges the ID cache
326 and removes the expired cache entries. */
328 /* Clients local list */
329 purge = silc_calloc(1, sizeof(*purge));
330 purge->cache = server->local_list->clients;
331 purge->schedule = server->schedule;
332 silc_schedule_task_add(purge->schedule, 0,
334 (void *)purge, 600, 0,
335 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
337 /* Clients global list */
338 purge = silc_calloc(1, sizeof(*purge));
339 purge->cache = server->global_list->clients;
340 purge->schedule = server->schedule;
341 silc_schedule_task_add(purge->schedule, 0,
343 (void *)purge, 300, 0,
344 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
346 SILC_LOG_DEBUG(("Server initialized"));
348 /* We are done here, return succesfully */
352 for (i = 0; i < sock_count; i++)
353 silc_net_close_server(sock[i]);
358 /* Fork server to background and set gid+uid to non-root */
360 void silc_server_daemonise(SilcServer server)
369 SILC_LOG_DEBUG(("Server started as user"));
371 SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
373 SILC_LOG_DEBUG(("Forking SILC server to background"));
376 SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
383 /* Drop root privligies. If this cannot be done, die. */
385 void silc_server_drop(SilcServer server)
387 /* Are we executing silcd as root or a regular user? */
394 if (!server->config->identity || !server->config->identity->user ||
395 !server->config->identity->group) {
396 fprintf(stderr, "Error:"
397 "\tSILC server must not be run as root. For the security of your\n"
398 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
399 "\tuser account. Modify the [Identity] configuration section to run\n"
400 "\tthe server as non-root user.\n");
404 /* Get the values given for user and group in configuration file */
405 user=server->config->identity->user;
406 group=server->config->identity->group;
408 /* Check whether the user/group information is text */
409 if (atoi(user)!=0 || atoi(group)!=0) {
410 SILC_LOG_DEBUG(("Invalid user and/or group information"));
411 SILC_LOG_DEBUG(("User and/or group given as number"));
412 fprintf(stderr, "Invalid user and/or group information\n");
413 fprintf(stderr, "Please assign them as names, not numbers\n");
417 /* Catch the nasty incident of string "0" returning 0 from atoi */
418 if (strcmp("0", user)==0 || strcmp("0", group)==0) {
419 SILC_LOG_DEBUG(("User and/or group configured to 0. Unacceptable"));
420 fprintf(stderr, "User and/or group configured to 0. Exiting\n");
424 if (!(pw=getpwnam(user))) {
425 fprintf(stderr, "No such user %s found\n", user);
429 if (!(gr=getgrnam(group))) {
430 fprintf(stderr, "No such group %s found\n", group);
434 /* Check whether user and/or group is set to root. If yes, exit
435 immediately. Otherwise, setgid and setuid server to user.group */
436 if (gr->gr_gid==0 || pw->pw_uid==0) {
437 fprintf(stderr, "Error:"
438 "\tSILC server must not be run as root. For the security of your\n"
439 "\tsystem it is strongly suggested that you run SILC under dedicated\n"
440 "\tuser account. Modify the [Identity] configuration section to run\n"
441 "\tthe server as non-root user.\n");
444 SILC_LOG_DEBUG(("Changing to group %s", group));
445 if (setgid(gr->gr_gid)==0) {
446 SILC_LOG_DEBUG(("Setgid to %s", group));
448 SILC_LOG_DEBUG(("Setgid to %s failed", group));
449 fprintf(stderr, "Tried to setgid %s but no such group. Exiting\n",
453 #if defined HAVE_SETGROUPS && defined HAVE_INITGROUPS
454 if (setgroups(0, NULL)!=0) {
455 SILC_LOG_DEBUG(("Setgroups to NULL failed"));
456 fprintf(stderr, "Tried to setgroups NULL but failed. Exiting\n");
459 if (initgroups(user, gr->gr_gid)!=0) {
460 SILC_LOG_DEBUG(("Initgroups to user %s (gid=%d) failed", user, gr->gr_gid));
461 fprintf(stderr, "Tried to initgroups %s (gid=%d) but no such user. Exiting\n",
466 SILC_LOG_DEBUG(("Changing to user %s", user));
467 if (setuid(pw->pw_uid)==0) {
468 SILC_LOG_DEBUG(("Setuid to %s", user));
470 SILC_LOG_DEBUG(("Setuid to %s failed", user));
471 fprintf(stderr, "Tried to setuid %s but no such user. Exiting\n",
479 /* The heart of the server. This runs the scheduler thus runs the server.
480 When this returns the server has been stopped and the program will
483 void silc_server_run(SilcServer server)
485 SILC_LOG_DEBUG(("Running server"));
487 SILC_LOG_INFO(("SILC Server started"));
489 /* Start the scheduler, the heart of the SILC server. When this returns
490 the program will be terminated. */
491 silc_schedule(server->schedule);
494 /* Stops the SILC server. This function is used to shutdown the server.
495 This is usually called after the scheduler has returned. After stopping
496 the server one should call silc_server_free. */
498 void silc_server_stop(SilcServer server)
500 SILC_LOG_DEBUG(("Stopping server"));
502 silc_schedule_stop(server->schedule);
503 silc_schedule_uninit(server->schedule);
505 silc_server_protocols_unregister();
507 SILC_LOG_DEBUG(("Server stopped"));
510 /* Function that is called when the network connection to a router has
511 been established. This will continue with the key exchange protocol
512 with the remote router. */
514 void silc_server_start_key_exchange(SilcServer server,
515 SilcServerConnection sconn,
518 SilcSocketConnection newsocket;
519 SilcProtocol protocol;
520 SilcServerKEInternalContext *proto_ctx;
523 /* Set socket options */
524 silc_net_set_socket_nonblock(sock);
525 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
527 /* Create socket connection for the connection. Even though we
528 know that we are connecting to a router we will mark the socket
529 to be unknown connection until we have executed authentication
531 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
532 server->sockets[sock] = newsocket;
533 newsocket->hostname = strdup(sconn->remote_host);
534 newsocket->ip = strdup(sconn->remote_host);
535 newsocket->port = sconn->remote_port;
536 sconn->sock = newsocket;
538 /* Allocate internal protocol context. This is sent as context
540 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
541 proto_ctx->server = (void *)server;
542 proto_ctx->context = (void *)sconn;
543 proto_ctx->sock = newsocket;
544 proto_ctx->rng = server->rng;
545 proto_ctx->responder = FALSE;
547 /* Perform key exchange protocol. silc_server_connect_to_router_second
548 will be called after the protocol is finished. */
549 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
550 &protocol, proto_ctx,
551 silc_server_connect_to_router_second);
552 newsocket->protocol = protocol;
554 /* Register a timeout task that will be executed if the protocol
555 is not executed within set limit. */
556 proto_ctx->timeout_task =
557 silc_schedule_task_add(server->schedule, sock,
558 silc_server_timeout_remote,
559 server, server->params->protocol_timeout,
560 server->params->protocol_timeout_usec,
564 /* Register the connection for network input and output. This sets
565 that scheduler will listen for incoming packets for this connection
566 and sets that outgoing packets may be sent to this connection as
567 well. However, this doesn't set the scheduler for outgoing traffic,
568 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
569 later when outgoing data is available. */
570 context = (void *)server;
571 SILC_REGISTER_CONNECTION_FOR_IO(sock);
573 /* Run the protocol */
574 silc_protocol_execute(protocol, server->schedule, 0, 0);
577 /* Timeout callback that will be called to retry connecting to remote
578 router. This is used by both normal and router server. This will wait
579 before retrying the connecting. The timeout is generated by exponential
580 backoff algorithm. */
582 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
584 SilcServerConnection sconn = (SilcServerConnection)context;
585 SilcServer server = sconn->server;
587 SILC_LOG_INFO(("Retrying connecting to a router"));
589 /* Calculate next timeout */
590 if (sconn->retry_count >= 1) {
591 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
592 if (sconn->retry_timeout > SILC_SERVER_RETRY_INTERVAL_MAX)
593 sconn->retry_timeout = SILC_SERVER_RETRY_INTERVAL_MAX;
595 sconn->retry_timeout = server->params->retry_interval_min;
597 sconn->retry_count++;
598 sconn->retry_timeout = sconn->retry_timeout +
599 silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
601 /* If we've reached max retry count, give up. */
602 if (sconn->retry_count > server->params->retry_count &&
603 server->params->retry_keep_trying == FALSE) {
604 SILC_LOG_ERROR(("Could not connect to router, giving up"));
608 /* Wait one before retrying */
609 silc_schedule_task_add(server->schedule, fd, silc_server_connect_router,
610 context, sconn->retry_timeout,
611 server->params->retry_interval_min_usec,
612 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
615 /* Generic routine to use connect to a router. */
617 SILC_TASK_CALLBACK(silc_server_connect_router)
619 SilcServerConnection sconn = (SilcServerConnection)context;
620 SilcServer server = sconn->server;
623 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
624 (sconn->backup ? "backup router" : "router"),
625 sconn->remote_host, sconn->remote_port));
627 server->router_connect = time(0);
629 /* Connect to remote host */
630 sock = silc_net_create_connection(server->config->listen_port->local_ip,
634 SILC_LOG_ERROR(("Could not connect to router"));
635 silc_schedule_task_add(server->schedule, fd,
636 silc_server_connect_to_router_retry,
637 context, 0, 1, SILC_TASK_TIMEOUT,
638 SILC_TASK_PRI_NORMAL);
642 /* Continue with key exchange protocol */
643 silc_server_start_key_exchange(server, sconn, sock);
646 /* This function connects to our primary router or if we are a router this
647 establishes all our primary routes. This is called at the start of the
648 server to do authentication and key exchange with our router - called
651 SILC_TASK_CALLBACK(silc_server_connect_to_router)
653 SilcServer server = (SilcServer)context;
654 SilcServerConnection sconn;
655 SilcServerConfigSectionServerConnection *ptr;
657 SILC_LOG_DEBUG(("Connecting to router(s)"));
659 if (server->server_type == SILC_SERVER) {
660 SILC_LOG_DEBUG(("We are normal server"));
661 } else if (server->server_type == SILC_ROUTER) {
662 SILC_LOG_DEBUG(("We are router"));
664 SILC_LOG_DEBUG(("We are backup router/normal server"));
667 /* Create the connections to all our routes */
668 ptr = server->config->routers;
671 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
672 ptr->backup_router ? "Backup router" : "Router",
673 ptr->initiator ? "Initiator" : "Responder",
674 ptr->host, ptr->port));
676 if (ptr->initiator) {
677 /* Allocate connection object for hold connection specific stuff. */
678 sconn = silc_calloc(1, sizeof(*sconn));
679 sconn->server = server;
680 sconn->remote_host = strdup(ptr->host);
681 sconn->remote_port = ptr->port;
682 sconn->backup = ptr->backup_router;
684 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
685 sconn->backup_replace_port = ptr->backup_replace_port;
688 silc_schedule_task_add(server->schedule, fd,
689 silc_server_connect_router,
690 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
691 SILC_TASK_PRI_NORMAL);
700 SILC_LOG_DEBUG(("No router(s), server will be standalone"));
702 /* There wasn't a configured router, we will continue but we don't
703 have a connection to outside world. We will be standalone server. */
704 server->standalone = TRUE;
707 /* Second part of connecting to router(s). Key exchange protocol has been
708 executed and now we will execute authentication protocol. */
710 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
712 SilcProtocol protocol = (SilcProtocol)context;
713 SilcServerKEInternalContext *ctx =
714 (SilcServerKEInternalContext *)protocol->context;
715 SilcServer server = (SilcServer)ctx->server;
716 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
717 SilcSocketConnection sock = ctx->sock;
718 SilcServerConnAuthInternalContext *proto_ctx;
719 SilcServerConfigSectionServerConnection *conn = NULL;
721 SILC_LOG_DEBUG(("Start"));
723 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
724 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
725 /* Error occured during protocol */
726 silc_protocol_free(protocol);
727 sock->protocol = NULL;
728 silc_ske_free_key_material(ctx->keymat);
730 silc_packet_context_free(ctx->packet);
732 silc_ske_free(ctx->ske);
733 silc_free(ctx->dest_id);
735 silc_schedule_task_del_by_callback(server->schedule,
736 silc_server_failure_callback);
737 silc_server_disconnect_remote(server, sock, "Server closed connection: "
738 "Key exchange failed");
742 /* We now have the key material as the result of the key exchange
743 protocol. Take the key material into use. Free the raw key material
744 as soon as we've set them into use. */
745 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
746 ctx->sock, ctx->keymat,
747 ctx->ske->prop->cipher,
748 ctx->ske->prop->pkcs,
749 ctx->ske->prop->hash,
750 ctx->ske->prop->hmac,
751 ctx->ske->prop->group,
753 silc_protocol_free(protocol);
754 sock->protocol = NULL;
755 silc_ske_free_key_material(ctx->keymat);
757 silc_packet_context_free(ctx->packet);
759 silc_ske_free(ctx->ske);
760 silc_free(ctx->dest_id);
762 silc_schedule_task_del_by_callback(server->schedule,
763 silc_server_failure_callback);
764 silc_server_disconnect_remote(server, sock, "Server closed connection: "
765 "Key exchange failed");
768 silc_ske_free_key_material(ctx->keymat);
770 /* Allocate internal context for the authentication protocol. This
771 is sent as context for the protocol. */
772 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
773 proto_ctx->server = (void *)server;
774 proto_ctx->context = (void *)sconn;
775 proto_ctx->sock = sock;
776 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
777 proto_ctx->dest_id_type = ctx->dest_id_type;
778 proto_ctx->dest_id = ctx->dest_id;
780 /* Resolve the authentication method used in this connection. Check if
781 we find a match from user configured connections */
782 conn = silc_server_config_find_router_conn(server->config,
786 /* Match found. Use the configured authentication method */
787 proto_ctx->auth_meth = conn->auth_meth;
788 if (conn->auth_data) {
789 proto_ctx->auth_data = strdup(conn->auth_data);
790 proto_ctx->auth_data_len = strlen(conn->auth_data);
793 SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
794 sock->hostname, sock->ip, sock->port));
795 silc_protocol_free(protocol);
796 sock->protocol = NULL;
798 silc_packet_context_free(ctx->packet);
800 silc_ske_free(ctx->ske);
801 silc_free(ctx->dest_id);
803 silc_schedule_task_del_by_callback(server->schedule,
804 silc_server_failure_callback);
805 silc_server_disconnect_remote(server, sock, "Server closed connection: "
806 "Key exchange failed");
810 /* Free old protocol as it is finished now */
811 silc_protocol_free(protocol);
813 silc_packet_context_free(ctx->packet);
815 sock->protocol = NULL;
817 /* Allocate the authentication protocol. This is allocated here
818 but we won't start it yet. We will be receiving party of this
819 protocol thus we will wait that connecting party will make
821 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
822 &sock->protocol, proto_ctx,
823 silc_server_connect_to_router_final);
825 /* Register timeout task. If the protocol is not executed inside
826 this timelimit the connection will be terminated. Currently
827 this is 15 seconds and is hard coded limit (XXX). */
828 proto_ctx->timeout_task =
829 silc_schedule_task_add(server->schedule, sock->sock,
830 silc_server_timeout_remote,
831 (void *)server, 15, 0,
835 /* Run the protocol */
836 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
839 /* Finalizes the connection to router. Registers a server task to the
840 queue so that we can accept new connections. */
842 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
844 SilcProtocol protocol = (SilcProtocol)context;
845 SilcServerConnAuthInternalContext *ctx =
846 (SilcServerConnAuthInternalContext *)protocol->context;
847 SilcServer server = (SilcServer)ctx->server;
848 SilcServerConnection sconn = (SilcServerConnection)ctx->context;
849 SilcSocketConnection sock = ctx->sock;
850 SilcServerEntry id_entry;
852 SilcServerHBContext hb_context;
853 unsigned char *id_string;
855 SilcIDListData idata;
857 SILC_LOG_DEBUG(("Start"));
859 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
860 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
861 /* Error occured during protocol */
862 silc_free(ctx->dest_id);
863 silc_server_disconnect_remote(server, sock, "Server closed connection: "
864 "Authentication failed");
868 /* Add a task to the queue. This task receives new connections to the
869 server. This task remains on the queue until the end of the program. */
870 if (!server->listenning && !sconn->backup) {
871 silc_schedule_task_add(server->schedule, server->sock,
872 silc_server_accept_new_connection,
873 (void *)server, 0, 0,
875 SILC_TASK_PRI_NORMAL);
876 server->listenning = TRUE;
879 /* Send NEW_SERVER packet to the router. We will become registered
880 to the SILC network after sending this packet. */
881 id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
882 id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
883 packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
884 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
885 silc_buffer_format(packet,
886 SILC_STR_UI_SHORT(id_len),
887 SILC_STR_UI_XNSTRING(id_string, id_len),
888 SILC_STR_UI_SHORT(strlen(server->server_name)),
889 SILC_STR_UI_XNSTRING(server->server_name,
890 strlen(server->server_name)),
893 /* Send the packet */
894 silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
895 packet->data, packet->len, TRUE);
896 silc_buffer_free(packet);
897 silc_free(id_string);
899 SILC_LOG_INFO(("Connected to router %s", sock->hostname));
901 /* Check that we do not have this ID already */
902 id_entry = silc_idlist_find_server_by_id(server->local_list,
903 ctx->dest_id, TRUE, NULL);
905 silc_idcache_del_by_context(server->local_list->servers, id_entry);
907 id_entry = silc_idlist_find_server_by_id(server->global_list,
908 ctx->dest_id, TRUE, NULL);
910 silc_idcache_del_by_context(server->global_list->servers, id_entry);
913 SILC_LOG_DEBUG(("New server id(%s)",
914 silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
916 /* Add the connected router to global server list */
917 id_entry = silc_idlist_add_server(server->global_list,
918 strdup(sock->hostname),
919 SILC_ROUTER, ctx->dest_id, NULL, sock);
921 silc_free(ctx->dest_id);
922 silc_server_disconnect_remote(server, sock, "Server closed connection: "
923 "Authentication failed");
927 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
928 silc_free(sock->user_data);
929 sock->user_data = (void *)id_entry;
930 sock->type = SILC_SOCKET_TYPE_ROUTER;
931 idata = (SilcIDListData)sock->user_data;
932 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
934 /* Perform keepalive. The `hb_context' will be freed automatically
935 when finally calling the silc_socket_free function. XXX hardcoded
937 hb_context = silc_calloc(1, sizeof(*hb_context));
938 hb_context->server = server;
939 silc_socket_set_heartbeat(sock, 600, hb_context,
940 silc_server_perform_heartbeat,
943 /* Register re-key timeout */
944 idata->rekey->timeout = 3600; /* XXX hardcoded */
945 idata->rekey->context = (void *)server;
946 silc_schedule_task_add(server->schedule, sock->sock,
947 silc_server_rekey_callback,
948 (void *)sock, idata->rekey->timeout, 0,
949 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
951 if (!sconn->backup) {
952 /* Mark this router our primary router if we're still standalone */
953 if (server->standalone) {
954 server->id_entry->router = id_entry;
955 server->router = id_entry;
956 server->standalone = FALSE;
958 /* If we are router then announce our possible servers. */
959 if (server->server_type == SILC_ROUTER)
960 silc_server_announce_servers(server, FALSE, 0,
961 server->router->connection);
963 /* Announce our clients and channels to the router */
964 silc_server_announce_clients(server, 0, server->router->connection);
965 silc_server_announce_channels(server, 0, server->router->connection);
968 /* Add this server to be our backup router */
969 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
970 sconn->backup_replace_port, FALSE);
973 sock->protocol = NULL;
975 /* Call the completion callback to indicate that we've connected to
978 (*sconn->callback)(server, id_entry, sconn->callback_context);
981 /* Free the temporary connection data context */
983 silc_free(sconn->remote_host);
984 silc_free(sconn->backup_replace_ip);
988 /* Free the protocol object */
989 if (sock->protocol == protocol)
990 sock->protocol = NULL;
991 silc_protocol_free(protocol);
993 silc_packet_context_free(ctx->packet);
995 silc_ske_free(ctx->ske);
999 /* Host lookup callbcak that is called after the incoming connection's
1000 IP and FQDN lookup is performed. This will actually check the acceptance
1001 of the incoming connection and will register the key exchange protocol
1002 for this connection. */
1005 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
1008 SilcServer server = (SilcServer)context;
1009 SilcServerKEInternalContext *proto_ctx;
1010 void *cconfig, *sconfig, *rconfig;
1011 SilcServerConfigSectionDenyConnection *deny;
1014 SILC_LOG_DEBUG(("Start"));
1016 /* Check whether we could resolve both IP and FQDN. */
1017 if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1018 server->params->require_reverse_mapping)) {
1019 SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1020 sock->hostname ? sock->hostname :
1021 sock->ip ? sock->ip : ""));
1022 server->stat.conn_failures++;
1023 silc_server_disconnect_remote(server, sock,
1024 "Server closed connection: Unknown host");
1028 /* Register the connection for network input and output. This sets
1029 that scheduler will listen for incoming packets for this connection
1030 and sets that outgoing packets may be sent to this connection as well.
1031 However, this doesn't set the scheduler for outgoing traffic, it
1032 will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1033 later when outgoing data is available. */
1034 SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1036 SILC_LOG_INFO(("Incoming connection from %s (%s)", sock->hostname,
1039 port = server->sockets[server->sock]->port; /* Listenning port */
1041 /* Check whether this connection is denied to connect to us. */
1042 deny = silc_server_config_denied_conn(server->config, sock->ip, port);
1044 deny = silc_server_config_denied_conn(server->config, sock->hostname,
1047 /* The connection is denied */
1048 SILC_LOG_INFO(("Connection %s (%s) is denied",
1049 sock->hostname, sock->ip));
1050 silc_server_disconnect_remote(server, sock, deny->comment ?
1052 "Server closed connection: "
1053 "Connection refused");
1054 server->stat.conn_failures++;
1058 /* Check whether we have configred this sort of connection at all. We
1059 have to check all configurations since we don't know what type of
1060 connection this is. */
1061 if (!(cconfig = silc_server_config_find_client_conn(server->config,
1063 cconfig = silc_server_config_find_client_conn(server->config,
1066 if (!(sconfig = silc_server_config_find_server_conn(server->config,
1069 sconfig = silc_server_config_find_server_conn(server->config,
1072 if (!(rconfig = silc_server_config_find_router_conn(server->config,
1074 rconfig = silc_server_config_find_router_conn(server->config,
1077 if (!cconfig && !sconfig && !rconfig) {
1078 silc_server_disconnect_remote(server, sock,
1079 "Server closed connection: "
1080 "Connection refused");
1081 server->stat.conn_failures++;
1085 /* The connection is allowed */
1087 /* Allocate internal context for key exchange protocol. This is
1088 sent as context for the protocol. */
1089 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1090 proto_ctx->server = context;
1091 proto_ctx->sock = sock;
1092 proto_ctx->rng = server->rng;
1093 proto_ctx->responder = TRUE;
1094 proto_ctx->cconfig = cconfig;
1095 proto_ctx->sconfig = sconfig;
1096 proto_ctx->rconfig = rconfig;
1098 /* Prepare the connection for key exchange protocol. We allocate the
1099 protocol but will not start it yet. The connector will be the
1100 initiator of the protocol thus we will wait for initiation from
1101 there before we start the protocol. */
1102 server->stat.auth_attempts++;
1103 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1104 &sock->protocol, proto_ctx,
1105 silc_server_accept_new_connection_second);
1107 /* Register a timeout task that will be executed if the connector
1108 will not start the key exchange protocol within 60 seconds. For
1109 now, this is a hard coded limit. After 60 secs the connection will
1110 be closed if the key exchange protocol has not been started. */
1111 proto_ctx->timeout_task =
1112 silc_schedule_task_add(server->schedule, sock->sock,
1113 silc_server_timeout_remote,
1119 /* Accepts new connections to the server. Accepting new connections are
1120 done in three parts to make it async. */
1122 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1124 SilcServer server = (SilcServer)context;
1125 SilcSocketConnection newsocket;
1128 SILC_LOG_DEBUG(("Accepting new connection"));
1130 server->stat.conn_attempts++;
1132 sock = silc_net_accept_connection(server->sock);
1134 SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1135 server->stat.conn_failures++;
1139 /* Check max connections */
1140 if (sock > SILC_SERVER_MAX_CONNECTIONS) {
1141 SILC_LOG_ERROR(("Refusing connection, server is full"));
1142 server->stat.conn_failures++;
1146 /* Set socket options */
1147 silc_net_set_socket_nonblock(sock);
1148 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1150 /* We don't create a ID yet, since we don't know what type of connection
1151 this is yet. But, we do add the connection to the socket table. */
1152 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1153 server->sockets[sock] = newsocket;
1155 /* Perform asynchronous host lookup. This will lookup the IP and the
1156 FQDN of the remote connection. After the lookup is done the connection
1157 is accepted further. */
1158 silc_socket_host_lookup(newsocket, TRUE,
1159 silc_server_accept_new_connection_lookup, context,
1163 /* Second part of accepting new connection. Key exchange protocol has been
1164 performed and now it is time to do little connection authentication
1165 protocol to figure out whether this connection is client or server
1166 and whether it has right to access this server (especially server
1167 connections needs to be authenticated). */
1169 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1171 SilcProtocol protocol = (SilcProtocol)context;
1172 SilcServerKEInternalContext *ctx =
1173 (SilcServerKEInternalContext *)protocol->context;
1174 SilcServer server = (SilcServer)ctx->server;
1175 SilcSocketConnection sock = ctx->sock;
1176 SilcServerConnAuthInternalContext *proto_ctx;
1178 SILC_LOG_DEBUG(("Start"));
1180 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1181 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1182 /* Error occured during protocol */
1183 silc_protocol_free(protocol);
1184 sock->protocol = NULL;
1185 silc_ske_free_key_material(ctx->keymat);
1187 silc_packet_context_free(ctx->packet);
1189 silc_ske_free(ctx->ske);
1190 silc_free(ctx->dest_id);
1192 silc_schedule_task_del_by_callback(server->schedule,
1193 silc_server_failure_callback);
1194 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1195 "Key exchange failed");
1196 server->stat.auth_failures++;
1200 /* We now have the key material as the result of the key exchange
1201 protocol. Take the key material into use. Free the raw key material
1202 as soon as we've set them into use. */
1203 if (!silc_server_protocol_ke_set_keys(server, ctx->ske,
1204 ctx->sock, ctx->keymat,
1205 ctx->ske->prop->cipher,
1206 ctx->ske->prop->pkcs,
1207 ctx->ske->prop->hash,
1208 ctx->ske->prop->hmac,
1209 ctx->ske->prop->group,
1211 silc_protocol_free(protocol);
1212 sock->protocol = NULL;
1213 silc_ske_free_key_material(ctx->keymat);
1215 silc_packet_context_free(ctx->packet);
1217 silc_ske_free(ctx->ske);
1218 silc_free(ctx->dest_id);
1220 silc_schedule_task_del_by_callback(server->schedule,
1221 silc_server_failure_callback);
1222 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1223 "Key exchange failed");
1224 server->stat.auth_failures++;
1227 silc_ske_free_key_material(ctx->keymat);
1229 /* Allocate internal context for the authentication protocol. This
1230 is sent as context for the protocol. */
1231 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1232 proto_ctx->server = (void *)server;
1233 proto_ctx->sock = sock;
1234 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
1235 proto_ctx->responder = TRUE;
1236 proto_ctx->dest_id_type = ctx->dest_id_type;
1237 proto_ctx->dest_id = ctx->dest_id;
1238 proto_ctx->cconfig = ctx->cconfig;
1239 proto_ctx->sconfig = ctx->sconfig;
1240 proto_ctx->rconfig = ctx->rconfig;
1242 /* Free old protocol as it is finished now */
1243 silc_protocol_free(protocol);
1245 silc_packet_context_free(ctx->packet);
1247 sock->protocol = NULL;
1249 /* Allocate the authentication protocol. This is allocated here
1250 but we won't start it yet. We will be receiving party of this
1251 protocol thus we will wait that connecting party will make
1252 their first move. */
1253 silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1254 &sock->protocol, proto_ctx,
1255 silc_server_accept_new_connection_final);
1257 /* Register timeout task. If the protocol is not executed inside
1258 this timelimit the connection will be terminated. Currently
1259 this is 60 seconds and is hard coded limit (XXX). */
1260 proto_ctx->timeout_task =
1261 silc_schedule_task_add(server->schedule, sock->sock,
1262 silc_server_timeout_remote,
1263 (void *)server, 60, 0,
1268 /* Final part of accepting new connection. The connection has now
1269 been authenticated and keys has been exchanged. We also know whether
1270 this is client or server connection. */
1272 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1274 SilcProtocol protocol = (SilcProtocol)context;
1275 SilcServerConnAuthInternalContext *ctx =
1276 (SilcServerConnAuthInternalContext *)protocol->context;
1277 SilcServer server = (SilcServer)ctx->server;
1278 SilcSocketConnection sock = ctx->sock;
1279 SilcServerHBContext hb_context;
1280 SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1281 void *id_entry = NULL;
1283 SILC_LOG_DEBUG(("Start"));
1285 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1286 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1287 /* Error occured during protocol */
1288 silc_protocol_free(protocol);
1289 sock->protocol = NULL;
1291 silc_packet_context_free(ctx->packet);
1293 silc_ske_free(ctx->ske);
1294 silc_free(ctx->dest_id);
1296 silc_schedule_task_del_by_callback(server->schedule,
1297 silc_server_failure_callback);
1298 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1299 "Authentication failed");
1300 server->stat.auth_failures++;
1304 entry->data.last_receive = time(NULL);
1306 switch (ctx->conn_type) {
1307 case SILC_SOCKET_TYPE_CLIENT:
1309 SilcClientEntry client;
1311 SILC_LOG_DEBUG(("Remote host is client"));
1312 SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname,
1315 /* Add the client to the client ID cache. The nickname and Client ID
1316 and other information is created after we have received NEW_CLIENT
1317 packet from client. */
1318 client = silc_idlist_add_client(server->local_list,
1319 NULL, NULL, NULL, NULL, NULL, sock);
1321 SILC_LOG_ERROR(("Could not add new client to cache"));
1322 silc_free(sock->user_data);
1323 silc_server_disconnect_remote(server, sock,
1324 "Server closed connection: "
1325 "Authentication failed");
1326 server->stat.auth_failures++;
1331 server->stat.my_clients++;
1332 server->stat.clients++;
1333 if (server->server_type == SILC_ROUTER)
1334 server->stat.cell_clients++;
1336 id_entry = (void *)client;
1339 case SILC_SOCKET_TYPE_SERVER:
1340 case SILC_SOCKET_TYPE_ROUTER:
1342 SilcServerEntry new_server;
1343 SilcServerConfigSectionServerConnection *conn =
1344 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1345 ctx->sconfig : ctx->rconfig;
1347 SILC_LOG_DEBUG(("Remote host is %s",
1348 ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1349 "server" : (conn->backup_router ?
1350 "backup router" : "router")));
1351 SILC_LOG_INFO(("Connection from %s (%s) is %s", sock->hostname,
1352 sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1353 "server" : (conn->backup_router ?
1354 "backup router" : "router")));
1356 /* Add the server into server cache. The server name and Server ID
1357 is updated after we have received NEW_SERVER packet from the
1358 server. We mark ourselves as router for this server if we really
1361 silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1362 server->local_list : (conn->backup_router ?
1363 server->local_list :
1364 server->global_list)),
1366 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1367 SILC_SERVER : SILC_ROUTER),
1369 (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1370 server->id_entry : (conn->backup_router ?
1371 server->id_entry : NULL)),
1374 SILC_LOG_ERROR(("Could not add new server to cache"));
1375 silc_free(sock->user_data);
1376 silc_server_disconnect_remote(server, sock,
1377 "Server closed connection: "
1378 "Authentication failed");
1379 server->stat.auth_failures++;
1384 if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER)
1385 server->stat.my_servers++;
1387 server->stat.my_routers++;
1388 server->stat.servers++;
1390 id_entry = (void *)new_server;
1392 /* If the incoming connection is router and marked as backup router
1393 then add it to be one of our backups */
1394 if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && conn->backup_router) {
1395 silc_server_backup_add(server, new_server, conn->backup_replace_ip,
1396 conn->backup_replace_port, conn->backup_local);
1398 /* Change it back to SERVER type since that's what it really is. */
1399 if (conn->backup_local)
1400 ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1402 new_server->server_type = SILC_BACKUP_ROUTER;
1405 /* Check whether this connection is to be our primary router connection
1406 if we do not already have the primary route. */
1407 if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1408 if (silc_server_config_is_primary_route(server->config) &&
1412 SILC_LOG_DEBUG(("We are not standalone server anymore"));
1413 server->standalone = FALSE;
1414 if (!server->id_entry->router) {
1415 server->id_entry->router = id_entry;
1416 server->router = id_entry;
1426 sock->type = ctx->conn_type;
1428 /* Add the common data structure to the ID entry. */
1430 silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1432 /* Add to sockets internal pointer for fast referencing */
1433 silc_free(sock->user_data);
1434 sock->user_data = id_entry;
1436 /* Connection has been fully established now. Everything is ok. */
1437 SILC_LOG_DEBUG(("New connection authenticated"));
1439 /* Perform keepalive. The `hb_context' will be freed automatically
1440 when finally calling the silc_socket_free function. XXX hardcoded
1442 hb_context = silc_calloc(1, sizeof(*hb_context));
1443 hb_context->server = server;
1444 silc_socket_set_heartbeat(sock, 600, hb_context,
1445 silc_server_perform_heartbeat,
1449 silc_schedule_task_del_by_callback(server->schedule,
1450 silc_server_failure_callback);
1451 silc_protocol_free(protocol);
1453 silc_packet_context_free(ctx->packet);
1455 silc_ske_free(ctx->ske);
1456 silc_free(ctx->dest_id);
1458 sock->protocol = NULL;
1461 /* This function is used to read packets from network and send packets to
1462 network. This is usually a generic task. */
1464 SILC_TASK_CALLBACK(silc_server_packet_process)
1466 SilcServer server = (SilcServer)context;
1467 SilcSocketConnection sock = server->sockets[fd];
1468 SilcIDListData idata;
1469 SilcCipher cipher = NULL;
1470 SilcHmac hmac = NULL;
1471 uint32 sequence = 0;
1477 SILC_LOG_DEBUG(("Processing packet"));
1479 /* Packet sending */
1481 if (type == SILC_TASK_WRITE) {
1482 /* Do not send data to disconnected connection */
1483 if (SILC_IS_DISCONNECTED(sock))
1486 server->stat.packets_sent++;
1488 if (sock->outbuf->data - sock->outbuf->head)
1489 silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
1491 /* Send the packet */
1492 ret = silc_packet_send(sock, TRUE);
1494 /* If returned -2 could not write to connection now, will do
1500 SILC_LOG_ERROR(("Error sending packet to connection "
1501 "%s:%d [%s]", sock->hostname, sock->port,
1502 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1503 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1504 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1509 /* The packet has been sent and now it is time to set the connection
1510 back to only for input. When there is again some outgoing data
1511 available for this connection it will be set for output as well.
1512 This call clears the output setting and sets it only for input. */
1513 SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1514 SILC_UNSET_OUTBUF_PENDING(sock);
1516 silc_buffer_clear(sock->outbuf);
1520 /* Packet receiving */
1522 /* Read some data from connection */
1523 ret = silc_packet_receive(sock);
1527 SILC_LOG_ERROR(("Error receiving packet from connection "
1528 "%s:%d [%s] %s", sock->hostname, sock->port,
1529 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1530 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1531 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1532 "Router"), strerror(errno)));
1538 SILC_LOG_DEBUG(("Read EOF"));
1540 /* If connection is disconnecting already we will finally
1541 close the connection */
1542 if (SILC_IS_DISCONNECTING(sock)) {
1543 if (sock->user_data)
1544 silc_server_free_sock_user_data(server, sock);
1545 silc_server_close_connection(server, sock);
1549 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1550 SILC_SET_DISCONNECTING(sock);
1552 if (sock->user_data)
1553 silc_server_free_sock_user_data(server, sock);
1554 silc_server_close_connection(server, sock);
1558 /* If connection is disconnecting or disconnected we will ignore
1560 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1561 SILC_LOG_DEBUG(("Ignoring read data from disonnected connection"));
1565 server->stat.packets_received++;
1567 /* Get keys and stuff from ID entry */
1568 idata = (SilcIDListData)sock->user_data;
1570 cipher = idata->receive_key;
1571 hmac = idata->hmac_receive;
1572 sequence = idata->psn_receive;
1575 /* Process the packet. This will call the parser that will then
1576 decrypt and parse the packet. */
1577 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1578 TRUE : FALSE, cipher, hmac, sequence,
1579 silc_server_packet_parse, server);
1582 /* Parses whole packet, received earlier. */
1584 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1586 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1587 SilcServer server = (SilcServer)parse_ctx->context;
1588 SilcSocketConnection sock = parse_ctx->sock;
1589 SilcPacketContext *packet = parse_ctx->packet;
1590 SilcIDListData idata = (SilcIDListData)sock->user_data;
1593 SILC_LOG_DEBUG(("Start"));
1595 /* Parse the packet */
1596 if (parse_ctx->normal)
1597 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1599 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1601 /* If entry is disabled ignore what we got. */
1602 if (ret != SILC_PACKET_RESUME_ROUTER &&
1603 idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1604 SILC_LOG_DEBUG(("Connection is disabled"));
1608 if (ret == SILC_PACKET_NONE)
1611 /* Check that the the current client ID is same as in the client's packet. */
1612 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1613 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1614 if (client && client->id) {
1615 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1616 packet->src_id_type);
1617 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1625 if (server->server_type == SILC_ROUTER) {
1626 /* Route the packet if it is not destined to us. Other ID types but
1627 server are handled separately after processing them. */
1628 if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1629 packet->dst_id_type == SILC_ID_SERVER &&
1630 sock->type != SILC_SOCKET_TYPE_CLIENT &&
1631 memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1633 /* Route the packet to fastest route for the destination ID */
1634 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1635 packet->dst_id_type);
1638 silc_server_packet_route(server,
1639 silc_server_route_get(server, id,
1640 packet->dst_id_type),
1647 /* Parse the incoming packet type */
1648 silc_server_packet_parse_type(server, sock, packet);
1650 if (server->server_type == SILC_ROUTER) {
1651 /* Broadcast packet if it is marked as broadcast packet and it is
1652 originated from router and we are router. */
1653 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1654 packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1655 !server->standalone) {
1656 /* Broadcast to our primary route */
1657 silc_server_packet_broadcast(server, server->router->connection, packet);
1659 /* If we have backup routers then we need to feed all broadcast
1660 data to those servers. */
1661 silc_server_backup_broadcast(server, sock, packet);
1666 silc_packet_context_free(packet);
1667 silc_free(parse_ctx);
1670 /* Parser callback called by silc_packet_receive_process. This merely
1671 registers timeout that will handle the actual parsing when appropriate. */
1673 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1676 SilcServer server = (SilcServer)context;
1677 SilcSocketConnection sock = parser_context->sock;
1678 SilcIDListData idata = (SilcIDListData)sock->user_data;
1681 idata->psn_receive = parser_context->packet->sequence + 1;
1683 /* If protocol for this connection is key exchange or rekey then we'll
1684 process all packets synchronously, since there might be packets in
1685 queue that we are not able to decrypt without first processing the
1686 packets before them. */
1687 if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1688 parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1689 (sock->protocol && sock->protocol->protocol &&
1690 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1691 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1692 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1695 /* Reprocess data since we'll return FALSE here. This is because
1696 the idata->receive_key might have become valid in the last packet
1697 and we want to call this processor with valid cipher. */
1699 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1700 TRUE : FALSE, idata->receive_key,
1701 idata->hmac_receive, idata->psn_receive,
1702 silc_server_packet_parse, server);
1704 silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
1705 TRUE : FALSE, NULL, NULL, 0,
1706 silc_server_packet_parse, server);
1710 switch (sock->type) {
1711 case SILC_SOCKET_TYPE_UNKNOWN:
1712 case SILC_SOCKET_TYPE_CLIENT:
1713 /* Parse the packet with timeout */
1714 silc_schedule_task_add(server->schedule, sock->sock,
1715 silc_server_packet_parse_real,
1716 (void *)parser_context, 0, 100000,
1718 SILC_TASK_PRI_NORMAL);
1720 case SILC_SOCKET_TYPE_SERVER:
1721 case SILC_SOCKET_TYPE_ROUTER:
1722 /* Packets from servers are parsed immediately */
1723 silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1733 /* Parses the packet type and calls what ever routines the packet type
1734 requires. This is done for all incoming packets. */
1736 void silc_server_packet_parse_type(SilcServer server,
1737 SilcSocketConnection sock,
1738 SilcPacketContext *packet)
1740 SilcPacketType type = packet->type;
1741 SilcIDListData idata = (SilcIDListData)sock->user_data;
1743 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1745 /* Parse the packet type */
1747 case SILC_PACKET_DISCONNECT:
1748 SILC_LOG_DEBUG(("Disconnect packet"));
1749 if (packet->flags & SILC_PACKET_FLAG_LIST)
1753 case SILC_PACKET_SUCCESS:
1755 * Success received for something. For now we can have only
1756 * one protocol for connection executing at once hence this
1757 * success message is for whatever protocol is executing currently.
1759 SILC_LOG_DEBUG(("Success packet"));
1760 if (packet->flags & SILC_PACKET_FLAG_LIST)
1763 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1766 case SILC_PACKET_FAILURE:
1768 * Failure received for something. For now we can have only
1769 * one protocol for connection executing at once hence this
1770 * failure message is for whatever protocol is executing currently.
1772 SILC_LOG_DEBUG(("Failure packet"));
1773 if (packet->flags & SILC_PACKET_FLAG_LIST)
1775 if (sock->protocol) {
1776 SilcServerFailureContext f;
1777 f = silc_calloc(1, sizeof(*f));
1781 /* We will wait 5 seconds to process this failure packet */
1782 silc_schedule_task_add(server->schedule, sock->sock,
1783 silc_server_failure_callback, (void *)f, 5, 0,
1784 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1788 case SILC_PACKET_REJECT:
1789 SILC_LOG_DEBUG(("Reject packet"));
1790 if (packet->flags & SILC_PACKET_FLAG_LIST)
1795 case SILC_PACKET_NOTIFY:
1797 * Received notify packet. Server can receive notify packets from
1798 * router. Server then relays the notify messages to clients if needed.
1800 SILC_LOG_DEBUG(("Notify packet"));
1801 if (packet->flags & SILC_PACKET_FLAG_LIST)
1802 silc_server_notify_list(server, sock, packet);
1804 silc_server_notify(server, sock, packet);
1810 case SILC_PACKET_CHANNEL_MESSAGE:
1812 * Received channel message. Channel messages are special packets
1813 * (although probably most common ones) thus they are handled
1816 SILC_LOG_DEBUG(("Channel Message packet"));
1817 if (packet->flags & SILC_PACKET_FLAG_LIST)
1819 idata->last_receive = time(NULL);
1820 silc_server_channel_message(server, sock, packet);
1823 case SILC_PACKET_CHANNEL_KEY:
1825 * Received key for channel. As channels are created by the router
1826 * the keys are as well. We will distribute the key to all of our
1827 * locally connected clients on the particular channel. Router
1828 * never receives this channel and thus is ignored.
1830 SILC_LOG_DEBUG(("Channel Key packet"));
1831 if (packet->flags & SILC_PACKET_FLAG_LIST)
1833 silc_server_channel_key(server, sock, packet);
1839 case SILC_PACKET_COMMAND:
1841 * Recived command. Processes the command request and allocates the
1842 * command context and calls the command.
1844 SILC_LOG_DEBUG(("Command packet"));
1845 if (packet->flags & SILC_PACKET_FLAG_LIST)
1847 silc_server_command_process(server, sock, packet);
1850 case SILC_PACKET_COMMAND_REPLY:
1852 * Received command reply packet. Received command reply to command. It
1853 * may be reply to command sent by us or reply to command sent by client
1854 * that we've routed further.
1856 SILC_LOG_DEBUG(("Command Reply packet"));
1857 if (packet->flags & SILC_PACKET_FLAG_LIST)
1859 silc_server_command_reply(server, sock, packet);
1863 * Private Message packets
1865 case SILC_PACKET_PRIVATE_MESSAGE:
1867 * Received private message packet. The packet is coming from either
1870 SILC_LOG_DEBUG(("Private Message packet"));
1871 if (packet->flags & SILC_PACKET_FLAG_LIST)
1873 idata->last_receive = time(NULL);
1874 silc_server_private_message(server, sock, packet);
1877 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1879 * Private message key packet.
1881 if (packet->flags & SILC_PACKET_FLAG_LIST)
1883 silc_server_private_message_key(server, sock, packet);
1887 * Key Exchange protocol packets
1889 case SILC_PACKET_KEY_EXCHANGE:
1890 SILC_LOG_DEBUG(("KE packet"));
1891 if (packet->flags & SILC_PACKET_FLAG_LIST)
1894 if (sock->protocol && sock->protocol->protocol &&
1895 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
1897 SilcServerKEInternalContext *proto_ctx =
1898 (SilcServerKEInternalContext *)sock->protocol->context;
1900 proto_ctx->packet = silc_packet_context_dup(packet);
1902 /* Let the protocol handle the packet */
1903 silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
1905 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1906 "protocol active, packet dropped."));
1910 case SILC_PACKET_KEY_EXCHANGE_1:
1911 SILC_LOG_DEBUG(("KE 1 packet"));
1912 if (packet->flags & SILC_PACKET_FLAG_LIST)
1915 if (sock->protocol && sock->protocol->protocol &&
1916 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1917 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
1919 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
1920 SilcServerRekeyInternalContext *proto_ctx =
1921 (SilcServerRekeyInternalContext *)sock->protocol->context;
1923 if (proto_ctx->packet)
1924 silc_packet_context_free(proto_ctx->packet);
1926 proto_ctx->packet = silc_packet_context_dup(packet);
1928 /* Let the protocol handle the packet */
1929 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1931 SilcServerKEInternalContext *proto_ctx =
1932 (SilcServerKEInternalContext *)sock->protocol->context;
1934 if (proto_ctx->packet)
1935 silc_packet_context_free(proto_ctx->packet);
1937 proto_ctx->packet = silc_packet_context_dup(packet);
1938 proto_ctx->dest_id_type = packet->src_id_type;
1939 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1940 packet->src_id_type);
1941 if (!proto_ctx->dest_id)
1944 /* Let the protocol handle the packet */
1945 silc_protocol_execute(sock->protocol, server->schedule,
1949 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1950 "protocol active, packet dropped."));
1954 case SILC_PACKET_KEY_EXCHANGE_2:
1955 SILC_LOG_DEBUG(("KE 2 packet"));
1956 if (packet->flags & SILC_PACKET_FLAG_LIST)
1959 if (sock->protocol && sock->protocol->protocol &&
1960 (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1961 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
1963 if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
1964 SilcServerRekeyInternalContext *proto_ctx =
1965 (SilcServerRekeyInternalContext *)sock->protocol->context;
1967 if (proto_ctx->packet)
1968 silc_packet_context_free(proto_ctx->packet);
1970 proto_ctx->packet = silc_packet_context_dup(packet);
1972 /* Let the protocol handle the packet */
1973 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1975 SilcServerKEInternalContext *proto_ctx =
1976 (SilcServerKEInternalContext *)sock->protocol->context;
1978 if (proto_ctx->packet)
1979 silc_packet_context_free(proto_ctx->packet);
1981 proto_ctx->packet = silc_packet_context_dup(packet);
1982 proto_ctx->dest_id_type = packet->src_id_type;
1983 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1984 packet->src_id_type);
1985 if (!proto_ctx->dest_id)
1988 /* Let the protocol handle the packet */
1989 silc_protocol_execute(sock->protocol, server->schedule,
1993 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1994 "protocol active, packet dropped."));
1998 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
2000 * Connection authentication request packet. When we receive this packet
2001 * we will send to the other end information about our mandatory
2002 * authentication method for the connection. This packet maybe received
2005 SILC_LOG_DEBUG(("Connection authentication request packet"));
2006 if (packet->flags & SILC_PACKET_FLAG_LIST)
2008 silc_server_connection_auth_request(server, sock, packet);
2012 * Connection Authentication protocol packets
2014 case SILC_PACKET_CONNECTION_AUTH:
2015 /* Start of the authentication protocol. We receive here the
2016 authentication data and will verify it. */
2017 SILC_LOG_DEBUG(("Connection auth packet"));
2018 if (packet->flags & SILC_PACKET_FLAG_LIST)
2021 if (sock->protocol && sock->protocol->protocol->type
2022 == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2024 SilcServerConnAuthInternalContext *proto_ctx =
2025 (SilcServerConnAuthInternalContext *)sock->protocol->context;
2027 proto_ctx->packet = silc_packet_context_dup(packet);
2029 /* Let the protocol handle the packet */
2030 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2032 SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2033 "protocol active, packet dropped."));
2037 case SILC_PACKET_NEW_ID:
2039 * Received New ID packet. This includes some new ID that has been
2040 * created. It may be for client, server or channel. This is the way
2041 * to distribute information about new registered entities in the
2044 SILC_LOG_DEBUG(("New ID packet"));
2045 if (packet->flags & SILC_PACKET_FLAG_LIST)
2046 silc_server_new_id_list(server, sock, packet);
2048 silc_server_new_id(server, sock, packet);
2051 case SILC_PACKET_NEW_CLIENT:
2053 * Received new client packet. This includes client information that
2054 * we will use to create initial client ID. After creating new
2055 * ID we will send it to the client.
2057 SILC_LOG_DEBUG(("New Client packet"));
2058 if (packet->flags & SILC_PACKET_FLAG_LIST)
2060 silc_server_new_client(server, sock, packet);
2063 case SILC_PACKET_NEW_SERVER:
2065 * Received new server packet. This includes Server ID and some other
2066 * information that we may save. This is received after server has
2069 SILC_LOG_DEBUG(("New Server packet"));
2070 if (packet->flags & SILC_PACKET_FLAG_LIST)
2072 silc_server_new_server(server, sock, packet);
2075 case SILC_PACKET_NEW_CHANNEL:
2077 * Received new channel packet. Information about new channel in the
2078 * network are distributed using this packet.
2080 SILC_LOG_DEBUG(("New Channel packet"));
2081 if (packet->flags & SILC_PACKET_FLAG_LIST)
2082 silc_server_new_channel_list(server, sock, packet);
2084 silc_server_new_channel(server, sock, packet);
2087 case SILC_PACKET_HEARTBEAT:
2089 * Received heartbeat.
2091 SILC_LOG_DEBUG(("Heartbeat packet"));
2092 if (packet->flags & SILC_PACKET_FLAG_LIST)
2096 case SILC_PACKET_KEY_AGREEMENT:
2098 * Received heartbeat.
2100 SILC_LOG_DEBUG(("Key agreement packet"));
2101 if (packet->flags & SILC_PACKET_FLAG_LIST)
2103 silc_server_key_agreement(server, sock, packet);
2106 case SILC_PACKET_REKEY:
2108 * Received re-key packet. The sender wants to regenerate the session
2111 SILC_LOG_DEBUG(("Re-key packet"));
2112 if (packet->flags & SILC_PACKET_FLAG_LIST)
2114 silc_server_rekey(server, sock, packet);
2117 case SILC_PACKET_REKEY_DONE:
2119 * The re-key is done.
2121 SILC_LOG_DEBUG(("Re-key done packet"));
2122 if (packet->flags & SILC_PACKET_FLAG_LIST)
2125 if (sock->protocol && sock->protocol->protocol &&
2126 sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2128 SilcServerRekeyInternalContext *proto_ctx =
2129 (SilcServerRekeyInternalContext *)sock->protocol->context;
2131 if (proto_ctx->packet)
2132 silc_packet_context_free(proto_ctx->packet);
2134 proto_ctx->packet = silc_packet_context_dup(packet);
2136 /* Let the protocol handle the packet */
2137 silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2139 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2140 "protocol active, packet dropped."));
2144 case SILC_PACKET_FTP:
2146 SILC_LOG_DEBUG(("FTP packet"));
2147 if (packet->flags & SILC_PACKET_FLAG_LIST)
2149 silc_server_ftp(server, sock, packet);
2152 case SILC_PACKET_RESUME_ROUTER:
2153 /* Resume router packet received. This packet is received for backup
2154 router resuming protocol. */
2155 SILC_LOG_DEBUG(("Resume router packet"));
2156 if (packet->flags & SILC_PACKET_FLAG_LIST)
2158 silc_server_backup_resume_router(server, sock, packet);
2162 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2168 /* Creates connection to a remote router. */
2170 void silc_server_create_connection(SilcServer server,
2171 char *remote_host, uint32 port)
2173 SilcServerConnection sconn;
2175 /* Allocate connection object for hold connection specific stuff. */
2176 sconn = silc_calloc(1, sizeof(*sconn));
2177 sconn->server = server;
2178 sconn->remote_host = strdup(remote_host);
2179 sconn->remote_port = port;
2181 silc_schedule_task_add(server->schedule, 0,
2182 silc_server_connect_router,
2183 (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
2184 SILC_TASK_PRI_NORMAL);
2187 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2189 silc_socket_free((SilcSocketConnection)context);
2192 /* Closes connection to socket connection */
2194 void silc_server_close_connection(SilcServer server,
2195 SilcSocketConnection sock)
2197 if (!server->sockets[sock->sock])
2200 SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2202 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2203 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2204 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2207 /* We won't listen for this connection anymore */
2208 silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2210 /* Unregister all tasks */
2211 silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2213 /* Close the actual connection */
2214 silc_net_close_connection(sock->sock);
2215 server->sockets[sock->sock] = NULL;
2217 /* If sock->user_data is NULL then we'll check for active protocols
2218 here since the silc_server_free_sock_user_data has not been called
2219 for this connection. */
2220 if (!sock->user_data) {
2221 /* If any protocol is active cancel its execution. It will call
2222 the final callback which will finalize the disconnection. */
2223 if (sock->protocol) {
2224 silc_protocol_cancel(sock->protocol, server->schedule);
2225 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2226 silc_protocol_execute_final(sock->protocol, server->schedule);
2227 sock->protocol = NULL;
2232 silc_schedule_task_add(server->schedule, 0,
2233 silc_server_close_connection_final,
2234 (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
2235 SILC_TASK_PRI_NORMAL);
2238 /* Sends disconnect message to remote connection and disconnects the
2241 void silc_server_disconnect_remote(SilcServer server,
2242 SilcSocketConnection sock,
2243 const char *fmt, ...)
2246 unsigned char buf[4096];
2251 memset(buf, 0, sizeof(buf));
2253 vsprintf(buf, fmt, ap);
2256 SILC_LOG_DEBUG(("Disconnecting remote host"));
2258 /* Notify remote end that the conversation is over. The notify message
2259 is tried to be sent immediately. */
2260 silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,
2261 buf, strlen(buf), TRUE);
2263 /* Mark the connection to be disconnected */
2264 SILC_SET_DISCONNECTED(sock);
2265 silc_server_close_connection(server, sock);
2270 SilcClientEntry client;
2271 } *FreeClientInternal;
2273 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2275 FreeClientInternal i = (FreeClientInternal)context;
2277 silc_idlist_del_data(i->client);
2278 silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2282 /* Frees client data and notifies about client's signoff. */
2284 void silc_server_free_client_data(SilcServer server,
2285 SilcSocketConnection sock,
2286 SilcClientEntry client,
2290 FreeClientInternal i = silc_calloc(1, sizeof(*i));
2292 /* If there is pending outgoing data for the client then purge it
2293 to the network before removing the client entry. */
2294 silc_server_packet_queue_purge(server, sock);
2299 /* Send SIGNOFF notify to routers. */
2300 if (notify && !server->standalone && server->router)
2301 silc_server_send_notify_signoff(server, server->router->connection,
2302 server->server_type == SILC_SERVER ?
2303 FALSE : TRUE, client->id, signoff);
2305 /* Remove client from all channels */
2307 silc_server_remove_from_channels(server, NULL, client,
2308 TRUE, signoff, TRUE);
2310 silc_server_remove_from_channels(server, NULL, client,
2311 FALSE, NULL, FALSE);
2313 /* We will not delete the client entry right away. We will take it
2314 into history (for WHOWAS command) for 5 minutes */
2317 silc_schedule_task_add(server->schedule, 0,
2318 silc_server_free_client_data_timeout,
2320 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2321 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2322 client->router = NULL;
2323 client->connection = NULL;
2325 /* Free the client entry and everything in it */
2326 server->stat.my_clients--;
2327 server->stat.clients--;
2328 if (server->server_type == SILC_ROUTER)
2329 server->stat.cell_clients--;
2332 /* Frees user_data pointer from socket connection object. This also sends
2333 appropriate notify packets to the network to inform about leaving
2336 void silc_server_free_sock_user_data(SilcServer server,
2337 SilcSocketConnection sock)
2339 SILC_LOG_DEBUG(("Start"));
2341 switch (sock->type) {
2342 case SILC_SOCKET_TYPE_CLIENT:
2344 SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2345 silc_server_free_client_data(server, sock, user_data, TRUE, NULL);
2348 case SILC_SOCKET_TYPE_SERVER:
2349 case SILC_SOCKET_TYPE_ROUTER:
2351 SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2352 SilcServerEntry backup_router = NULL;
2355 backup_router = silc_server_backup_get(server, user_data->id);
2357 /* If this was our primary router connection then we're lost to
2358 the outside world. */
2359 if (server->router == user_data) {
2360 /* Check whether we have a backup router connection */
2361 if (!backup_router || backup_router == user_data) {
2362 silc_schedule_task_add(server->schedule, 0,
2363 silc_server_connect_to_router,
2366 SILC_TASK_PRI_NORMAL);
2368 server->id_entry->router = NULL;
2369 server->router = NULL;
2370 server->standalone = TRUE;
2371 backup_router = NULL;
2373 SILC_LOG_INFO(("New primary router is backup router %s",
2374 backup_router->server_name));
2375 SILC_LOG_DEBUG(("New primary router is backup router %s",
2376 backup_router->server_name));
2377 server->id_entry->router = backup_router;
2378 server->router = backup_router;
2379 server->router_connect = time(0);
2380 server->backup_primary = TRUE;
2381 if (server->server_type == SILC_BACKUP_ROUTER) {
2382 server->server_type = SILC_ROUTER;
2384 /* We'll need to constantly try to reconnect to the primary
2385 router so that we'll see when it comes back online. */
2386 silc_server_backup_reconnect(server, sock->ip, sock->port,
2387 silc_server_backup_connected,
2391 /* Mark this connection as replaced */
2392 silc_server_backup_replaced_add(server, user_data->id,
2395 } else if (backup_router) {
2396 SILC_LOG_INFO(("Enabling the use of backup router %s",
2397 backup_router->server_name));
2398 SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2399 backup_router->server_name));
2401 /* Mark this connection as replaced */
2402 silc_server_backup_replaced_add(server, user_data->id,
2406 if (!backup_router) {
2407 /* Free all client entries that this server owns as they will
2408 become invalid now as well. */
2410 silc_server_remove_clients_by_server(server, user_data, TRUE);
2411 if (server->server_type == SILC_SERVER)
2412 silc_server_remove_channels_by_server(server, user_data);
2414 /* Update the client entries of this server to the new backup
2415 router. This also removes the clients that *really* was owned
2416 by the primary router and went down with the router. */
2417 silc_server_update_clients_by_server(server, user_data, backup_router,
2419 silc_server_update_servers_by_server(server, user_data, backup_router);
2420 if (server->server_type == SILC_SERVER)
2421 silc_server_update_channels_by_server(server, user_data,
2425 /* Free the server entry */
2426 silc_server_backup_del(server, user_data);
2427 silc_server_backup_replaced_del(server, user_data);
2428 silc_idlist_del_data(user_data);
2429 if (!silc_idlist_del_server(server->local_list, user_data))
2430 silc_idlist_del_server(server->global_list, user_data);
2431 server->stat.my_servers--;
2432 server->stat.servers--;
2433 if (server->server_type == SILC_ROUTER)
2434 server->stat.cell_servers--;
2436 if (backup_router) {
2437 /* Announce all of our stuff that was created about 5 minutes ago.
2438 The backup router knows all the other stuff already. */
2439 if (server->server_type == SILC_ROUTER)
2440 silc_server_announce_servers(server, FALSE, time(0) - 300,
2441 backup_router->connection);
2443 /* Announce our clients and channels to the router */
2444 silc_server_announce_clients(server, time(0) - 300,
2445 backup_router->connection);
2446 silc_server_announce_channels(server, time(0) - 300,
2447 backup_router->connection);
2453 SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2455 silc_idlist_del_data(user_data);
2456 silc_free(user_data);
2461 /* If any protocol is active cancel its execution */
2462 if (sock->protocol) {
2463 silc_protocol_cancel(sock->protocol, server->schedule);
2464 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2465 silc_protocol_execute_final(sock->protocol, server->schedule);
2466 sock->protocol = NULL;
2469 sock->user_data = NULL;
2472 /* Removes client from all channels it has joined. This is used when client
2473 connection is disconnected. If the client on a channel is last, the
2474 channel is removed as well. This sends the SIGNOFF notify types. */
2476 void silc_server_remove_from_channels(SilcServer server,
2477 SilcSocketConnection sock,
2478 SilcClientEntry client,
2480 char *signoff_message,
2483 SilcChannelEntry channel;
2484 SilcChannelClientEntry chl;
2485 SilcHashTableList htl;
2488 SILC_LOG_DEBUG(("Start"));
2490 if (!client || !client->id)
2493 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2495 /* Remove the client from all channels. The client is removed from
2496 the channels' user list. */
2497 silc_hash_table_list(client->channels, &htl);
2498 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2499 channel = chl->channel;
2501 /* Remove channel from client's channel list */
2502 silc_hash_table_del(client->channels, channel);
2504 /* Remove channel if there is no users anymore */
2505 if (server->server_type == SILC_ROUTER &&
2506 silc_hash_table_count(channel->user_list) < 2) {
2508 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2509 if (silc_idlist_del_channel(server->local_list, channel))
2510 server->stat.my_channels--;
2512 silc_idlist_del_channel(server->global_list, channel);
2516 /* Remove client from channel's client list */
2517 silc_hash_table_del(channel->user_list, chl->client);
2519 /* If there is no global users on the channel anymore mark the channel
2520 as local channel. Do not check if the removed client is local client. */
2521 if (server->server_type != SILC_ROUTER && channel->global_users &&
2522 chl->client->router && !silc_server_channel_has_global(channel))
2523 channel->global_users = FALSE;
2526 server->stat.my_chanclients--;
2528 /* If there is not at least one local user on the channel then we don't
2529 need the channel entry anymore, we can remove it safely. */
2530 if (server->server_type != SILC_ROUTER &&
2531 !silc_server_channel_has_local(channel)) {
2532 /* Notify about leaving client if this channel has global users. */
2533 if (notify && channel->global_users)
2534 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2535 SILC_NOTIFY_TYPE_SIGNOFF,
2536 signoff_message ? 2 : 1,
2537 clidp->data, clidp->len,
2538 signoff_message, signoff_message ?
2539 strlen(signoff_message) : 0);
2542 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2544 if (channel->founder_key) {
2545 /* The founder auth data exists, do not remove the channel entry */
2546 SilcChannelClientEntry chl2;
2547 SilcHashTableList htl2;
2549 channel->disabled = TRUE;
2551 silc_hash_table_list(channel->user_list, &htl2);
2552 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2553 silc_hash_table_del(chl2->client->channels, channel);
2554 silc_hash_table_del(channel->user_list, chl2->client);
2560 /* Remove the channel entry */
2561 if (silc_idlist_del_channel(server->local_list, channel))
2562 server->stat.my_channels--;
2564 silc_idlist_del_channel(server->global_list, channel);
2568 /* Send notify to channel about client leaving SILC and thus
2569 the entire channel. */
2571 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2572 SILC_NOTIFY_TYPE_SIGNOFF,
2573 signoff_message ? 2 : 1,
2574 clidp->data, clidp->len,
2575 signoff_message, signoff_message ?
2576 strlen(signoff_message) : 0);
2578 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2579 /* Re-generate channel key */
2580 if (!silc_server_create_channel_key(server, channel, 0))
2583 /* Send the channel key to the channel. The key of course is not sent
2584 to the client who was removed from the channel. */
2585 silc_server_send_channel_key(server, client->connection, channel,
2586 server->server_type == SILC_ROUTER ?
2587 FALSE : !server->standalone);
2591 silc_buffer_free(clidp);
2594 /* Removes client from one channel. This is used for example when client
2595 calls LEAVE command to remove itself from the channel. Returns TRUE
2596 if channel still exists and FALSE if the channel is removed when
2597 last client leaves the channel. If `notify' is FALSE notify messages
2600 int silc_server_remove_from_one_channel(SilcServer server,
2601 SilcSocketConnection sock,
2602 SilcChannelEntry channel,
2603 SilcClientEntry client,
2606 SilcChannelClientEntry chl;
2609 SILC_LOG_DEBUG(("Start"));
2611 /* Get the entry to the channel, if this client is not on the channel
2613 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2616 /* Remove the client from the channel. The client is removed from
2617 the channel's user list. */
2619 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2621 /* Remove channel from client's channel list */
2622 silc_hash_table_del(client->channels, chl->channel);
2624 /* Remove channel if there is no users anymore */
2625 if (server->server_type == SILC_ROUTER &&
2626 silc_hash_table_count(channel->user_list) < 2) {
2628 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2629 if (silc_idlist_del_channel(server->local_list, channel))
2630 server->stat.my_channels--;
2632 silc_idlist_del_channel(server->global_list, channel);
2633 silc_buffer_free(clidp);
2637 /* Remove client from channel's client list */
2638 silc_hash_table_del(channel->user_list, chl->client);
2640 /* If there is no global users on the channel anymore mark the channel
2641 as local channel. Do not check if the client is local client. */
2642 if (server->server_type != SILC_ROUTER && channel->global_users &&
2643 chl->client->router && !silc_server_channel_has_global(channel))
2644 channel->global_users = FALSE;
2647 server->stat.my_chanclients--;
2649 /* If there is not at least one local user on the channel then we don't
2650 need the channel entry anymore, we can remove it safely. */
2651 if (server->server_type != SILC_ROUTER &&
2652 !silc_server_channel_has_local(channel)) {
2653 /* Notify about leaving client if this channel has global users. */
2654 if (notify && channel->global_users)
2655 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2656 SILC_NOTIFY_TYPE_LEAVE, 1,
2657 clidp->data, clidp->len);
2659 silc_buffer_free(clidp);
2662 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2664 if (channel->founder_key) {
2665 /* The founder auth data exists, do not remove the channel entry */
2666 SilcChannelClientEntry chl2;
2667 SilcHashTableList htl2;
2669 channel->disabled = TRUE;
2671 silc_hash_table_list(channel->user_list, &htl2);
2672 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2673 silc_hash_table_del(chl2->client->channels, channel);
2674 silc_hash_table_del(channel->user_list, chl2->client);
2680 /* Remove the channel entry */
2681 if (silc_idlist_del_channel(server->local_list, channel))
2682 server->stat.my_channels--;
2684 silc_idlist_del_channel(server->global_list, channel);
2688 /* Send notify to channel about client leaving the channel */
2690 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2691 SILC_NOTIFY_TYPE_LEAVE, 1,
2692 clidp->data, clidp->len);
2694 silc_buffer_free(clidp);
2698 /* Timeout callback. This is called if connection is idle or for some
2699 other reason is not responding within some period of time. This
2700 disconnects the remote end. */
2702 SILC_TASK_CALLBACK(silc_server_timeout_remote)
2704 SilcServer server = (SilcServer)context;
2705 SilcSocketConnection sock = server->sockets[fd];
2707 SILC_LOG_DEBUG(("Start"));
2712 /* If we have protocol active we must assure that we call the protocol's
2713 final callback so that all the memory is freed. */
2714 if (sock->protocol) {
2715 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2716 silc_protocol_execute_final(sock->protocol, server->schedule);
2720 if (sock->user_data)
2721 silc_server_free_sock_user_data(server, sock);
2723 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2724 "Connection timeout");
2727 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
2728 function may be used only by router. In real SILC network all channels
2729 are created by routers thus this function is never used by normal
2732 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
2733 SilcServerID *router_id,
2739 SilcChannelID *channel_id;
2740 SilcChannelEntry entry;
2744 SILC_LOG_DEBUG(("Creating new channel"));
2747 cipher = SILC_DEFAULT_CIPHER;
2749 hmac = SILC_DEFAULT_HMAC;
2751 /* Allocate cipher */
2752 if (!silc_cipher_alloc(cipher, &key))
2756 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2757 silc_cipher_free(key);
2761 channel_name = strdup(channel_name);
2763 /* Create the channel */
2764 if (!silc_id_create_channel_id(server, router_id, server->rng,
2766 silc_free(channel_name);
2767 silc_cipher_free(key);
2768 silc_hmac_free(newhmac);
2771 entry = silc_idlist_add_channel(server->local_list, channel_name,
2772 SILC_CHANNEL_MODE_NONE, channel_id,
2773 NULL, key, newhmac);
2775 silc_free(channel_name);
2776 silc_cipher_free(key);
2777 silc_hmac_free(newhmac);
2781 entry->cipher = strdup(cipher);
2782 entry->hmac_name = strdup(hmac);
2784 /* Now create the actual key material */
2785 if (!silc_server_create_channel_key(server, entry,
2786 silc_cipher_get_key_len(key) / 8)) {
2787 silc_free(channel_name);
2788 silc_cipher_free(key);
2789 silc_hmac_free(newhmac);
2790 silc_free(entry->cipher);
2791 silc_free(entry->hmac_name);
2795 /* Notify other routers about the new channel. We send the packet
2796 to our primary route. */
2797 if (broadcast && server->standalone == FALSE)
2798 silc_server_send_new_channel(server, server->router->connection, TRUE,
2799 channel_name, entry->id,
2800 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2803 server->stat.my_channels++;
2808 /* Same as above but creates the channel with Channel ID `channel_id. */
2811 silc_server_create_new_channel_with_id(SilcServer server,
2815 SilcChannelID *channel_id,
2818 SilcChannelEntry entry;
2822 SILC_LOG_DEBUG(("Creating new channel"));
2825 cipher = SILC_DEFAULT_CIPHER;
2827 hmac = SILC_DEFAULT_HMAC;
2829 /* Allocate cipher */
2830 if (!silc_cipher_alloc(cipher, &key))
2834 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2835 silc_cipher_free(key);
2839 channel_name = strdup(channel_name);
2841 /* Create the channel */
2842 entry = silc_idlist_add_channel(server->local_list, channel_name,
2843 SILC_CHANNEL_MODE_NONE, channel_id,
2844 NULL, key, newhmac);
2846 silc_free(channel_name);
2850 /* Now create the actual key material */
2851 if (!silc_server_create_channel_key(server, entry,
2852 silc_cipher_get_key_len(key) / 8)) {
2853 silc_free(channel_name);
2857 /* Notify other routers about the new channel. We send the packet
2858 to our primary route. */
2859 if (broadcast && server->standalone == FALSE)
2860 silc_server_send_new_channel(server, server->router->connection, TRUE,
2861 channel_name, entry->id,
2862 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2865 server->stat.my_channels++;
2870 /* Channel's key re-key timeout callback. */
2872 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
2874 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
2875 SilcServer server = (SilcServer)rekey->context;
2879 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
2882 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
2885 /* Generates new channel key. This is used to create the initial channel key
2886 but also to re-generate new key for channel. If `key_len' is provided
2887 it is the bytes of the key length. */
2889 bool silc_server_create_channel_key(SilcServer server,
2890 SilcChannelEntry channel,
2894 unsigned char channel_key[32], hash[32];
2897 SILC_LOG_DEBUG(("Generating channel key"));
2899 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2900 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
2904 if (!channel->channel_key)
2905 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
2906 channel->channel_key = NULL;
2912 else if (channel->key_len)
2913 len = channel->key_len / 8;
2915 len = silc_cipher_get_key_len(channel->channel_key) / 8;
2917 /* Create channel key */
2918 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
2921 silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
2923 /* Remove old key if exists */
2925 memset(channel->key, 0, channel->key_len / 8);
2926 silc_free(channel->key);
2930 channel->key_len = len * 8;
2931 channel->key = silc_calloc(len, sizeof(*channel->key));
2932 memcpy(channel->key, channel_key, len);
2933 memset(channel_key, 0, sizeof(channel_key));
2935 /* Generate HMAC key from the channel key data and set it */
2937 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
2938 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
2939 silc_hmac_set_key(channel->hmac, hash,
2940 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
2941 memset(hash, 0, sizeof(hash));
2943 if (server->server_type == SILC_ROUTER) {
2944 if (!channel->rekey)
2945 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
2946 channel->rekey->context = (void *)server;
2947 channel->rekey->channel = channel;
2948 channel->rekey->key_len = key_len;
2949 if (channel->rekey->task)
2950 silc_schedule_task_del(server->schedule, channel->rekey->task);
2952 channel->rekey->task =
2953 silc_schedule_task_add(server->schedule, 0,
2954 silc_server_channel_key_rekey,
2955 (void *)channel->rekey, 3600, 0,
2957 SILC_TASK_PRI_NORMAL);
2963 /* Saves the channel key found in the encoded `key_payload' buffer. This
2964 function is used when we receive Channel Key Payload and also when we're
2965 processing JOIN command reply. Returns entry to the channel. */
2967 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
2968 SilcBuffer key_payload,
2969 SilcChannelEntry channel)
2971 SilcChannelKeyPayload payload = NULL;
2972 SilcChannelID *id = NULL;
2973 unsigned char *tmp, hash[32];
2977 SILC_LOG_DEBUG(("Start"));
2979 /* Decode channel key payload */
2980 payload = silc_channel_key_payload_parse(key_payload->data,
2983 SILC_LOG_ERROR(("Bad channel key payload, dropped"));
2988 /* Get the channel entry */
2991 /* Get channel ID */
2992 tmp = silc_channel_key_get_id(payload, &tmp_len);
2993 id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
2999 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
3001 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
3003 SILC_LOG_ERROR(("Received key for non-existent channel"));
3009 tmp = silc_channel_key_get_key(payload, &tmp_len);
3015 cipher = silc_channel_key_get_cipher(payload, NULL);
3021 /* Remove old key if exists */
3023 memset(channel->key, 0, channel->key_len / 8);
3024 silc_free(channel->key);
3025 silc_cipher_free(channel->channel_key);
3028 /* Create new cipher */
3029 if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3030 channel->channel_key = NULL;
3035 if (channel->cipher)
3036 silc_free(channel->cipher);
3037 channel->cipher = strdup(cipher);
3040 channel->key_len = tmp_len * 8;
3041 channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
3042 memcpy(channel->key, tmp, tmp_len);
3043 silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3045 /* Generate HMAC key from the channel key data and set it */
3047 silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3048 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3049 silc_hmac_set_key(channel->hmac, hash,
3050 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3052 memset(hash, 0, sizeof(hash));
3053 memset(tmp, 0, tmp_len);
3055 if (server->server_type == SILC_ROUTER) {
3056 if (!channel->rekey)
3057 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3058 channel->rekey->context = (void *)server;
3059 channel->rekey->channel = channel;
3060 if (channel->rekey->task)
3061 silc_schedule_task_del(server->schedule, channel->rekey->task);
3063 channel->rekey->task =
3064 silc_schedule_task_add(server->schedule, 0,
3065 silc_server_channel_key_rekey,
3066 (void *)channel->rekey, 3600, 0,
3068 SILC_TASK_PRI_NORMAL);
3074 silc_channel_key_payload_free(payload);
3079 /* Heartbeat callback. This function is set as argument for the
3080 silc_socket_set_heartbeat function. The library will call this function
3081 at the set time interval. */
3083 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3086 SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3088 SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname,
3091 /* Send the heartbeat */
3092 silc_server_send_heartbeat(hb->server, sock);
3095 /* Returns assembled of all servers in the given ID list. The packet's
3096 form is dictated by the New ID payload. */
3098 static void silc_server_announce_get_servers(SilcServer server,
3099 SilcServerEntry remote,
3101 SilcBuffer *servers,
3102 unsigned long creation_time)
3104 SilcIDCacheList list;
3105 SilcIDCacheEntry id_cache;
3106 SilcServerEntry entry;
3109 /* Go through all clients in the list */
3110 if (silc_idcache_get_all(id_list->servers, &list)) {
3111 if (silc_idcache_list_first(list, &id_cache)) {
3113 entry = (SilcServerEntry)id_cache->context;
3115 /* Do not announce the one we've sending our announcements and
3116 do not announce ourself. Also check the creation time if it's
3118 if ((entry == remote) || (entry == server->id_entry) ||
3119 (creation_time && entry->data.created < creation_time)) {
3120 if (!silc_idcache_list_next(list, &id_cache))
3125 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3127 *servers = silc_buffer_realloc(*servers,
3129 (*servers)->truelen + idp->len :
3131 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3132 silc_buffer_put(*servers, idp->data, idp->len);
3133 silc_buffer_pull(*servers, idp->len);
3134 silc_buffer_free(idp);
3136 if (!silc_idcache_list_next(list, &id_cache))
3141 silc_idcache_list_free(list);
3145 /* This function is used by router to announce existing servers to our
3146 primary router when we've connected to it. If `creation_time' is non-zero
3147 then only the servers that has been created after the `creation_time'
3148 will be announced. */
3150 void silc_server_announce_servers(SilcServer server, bool global,
3151 unsigned long creation_time,
3152 SilcSocketConnection remote)
3154 SilcBuffer servers = NULL;
3156 SILC_LOG_DEBUG(("Announcing servers"));
3158 /* Get servers in local list */
3159 silc_server_announce_get_servers(server, remote->user_data,
3160 server->local_list, &servers,
3164 /* Get servers in global list */
3165 silc_server_announce_get_servers(server, remote->user_data,
3166 server->global_list, &servers,
3170 silc_buffer_push(servers, servers->data - servers->head);
3171 SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3173 /* Send the packet */
3174 silc_server_packet_send(server, remote,
3175 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3176 servers->data, servers->len, TRUE);
3178 silc_buffer_free(servers);
3182 /* Returns assembled packet of all clients in the given ID list. The
3183 packet's form is dictated by the New ID Payload. */
3185 static void silc_server_announce_get_clients(SilcServer server,
3187 SilcBuffer *clients,
3188 unsigned long creation_time)
3190 SilcIDCacheList list;
3191 SilcIDCacheEntry id_cache;
3192 SilcClientEntry client;
3195 /* Go through all clients in the list */
3196 if (silc_idcache_get_all(id_list->clients, &list)) {
3197 if (silc_idcache_list_first(list, &id_cache)) {
3199 client = (SilcClientEntry)id_cache->context;
3201 if (creation_time && client->data.created < creation_time) {
3202 if (!silc_idcache_list_next(list, &id_cache))
3207 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3209 *clients = silc_buffer_realloc(*clients,
3211 (*clients)->truelen + idp->len :
3213 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3214 silc_buffer_put(*clients, idp->data, idp->len);
3215 silc_buffer_pull(*clients, idp->len);
3216 silc_buffer_free(idp);
3218 if (!silc_idcache_list_next(list, &id_cache))
3223 silc_idcache_list_free(list);
3227 /* This function is used to announce our existing clients to our router
3228 when we've connected to it. If `creation_time' is non-zero then only
3229 the clients that has been created after the `creation_time' will be
3232 void silc_server_announce_clients(SilcServer server,
3233 unsigned long creation_time,
3234 SilcSocketConnection remote)
3236 SilcBuffer clients = NULL;
3238 SILC_LOG_DEBUG(("Announcing clients"));
3240 /* Get clients in local list */
3241 silc_server_announce_get_clients(server, server->local_list,
3242 &clients, creation_time);
3244 /* As router we announce our global list as well */
3245 if (server->server_type == SILC_ROUTER)
3246 silc_server_announce_get_clients(server, server->global_list,
3247 &clients, creation_time);
3250 silc_buffer_push(clients, clients->data - clients->head);
3251 SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3253 /* Send the packet */
3254 silc_server_packet_send(server, remote,
3255 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3256 clients->data, clients->len, TRUE);
3258 silc_buffer_free(clients);
3263 silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
3269 p = silc_notify_payload_encode(notify, argc, ap);
3275 /* Returns assembled packets for channel users of the `channel'. */
3277 void silc_server_announce_get_channel_users(SilcServer server,
3278 SilcChannelEntry channel,
3279 SilcBuffer *channel_users,
3280 SilcBuffer *channel_users_modes)
3282 SilcChannelClientEntry chl;
3283 SilcHashTableList htl;
3284 SilcBuffer chidp, clidp;
3287 unsigned char mode[4];
3289 SILC_LOG_DEBUG(("Start"));
3291 /* Now find all users on the channel */
3292 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3293 silc_hash_table_list(channel->user_list, &htl);
3294 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3295 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3298 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
3299 clidp->data, clidp->len,
3300 chidp->data, chidp->len);
3303 silc_buffer_realloc(*channel_users,
3305 (*channel_users)->truelen + len : len));
3306 silc_buffer_pull_tail(*channel_users,
3307 ((*channel_users)->end -
3308 (*channel_users)->data));
3310 silc_buffer_put(*channel_users, tmp->data, tmp->len);
3311 silc_buffer_pull(*channel_users, len);
3312 silc_buffer_free(tmp);
3314 /* CUMODE notify for mode change on the channel */
3315 SILC_PUT32_MSB(chl->mode, mode);
3316 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
3317 3, clidp->data, clidp->len,
3319 clidp->data, clidp->len);
3321 *channel_users_modes =
3322 silc_buffer_realloc(*channel_users_modes,
3323 (*channel_users_modes ?
3324 (*channel_users_modes)->truelen + len : len));
3325 silc_buffer_pull_tail(*channel_users_modes,
3326 ((*channel_users_modes)->end -
3327 (*channel_users_modes)->data));
3329 silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3330 silc_buffer_pull(*channel_users_modes, len);
3331 silc_buffer_free(tmp);
3333 silc_buffer_free(clidp);
3335 silc_buffer_free(chidp);
3338 /* Returns assembled packets for all channels and users on those channels
3339 from the given ID List. The packets are in the form dictated by the
3340 New Channel and New Channel User payloads. */
3342 void silc_server_announce_get_channels(SilcServer server,
3344 SilcBuffer *channels,
3345 SilcBuffer *channel_users,
3346 SilcBuffer **channel_users_modes,
3347 uint32 *channel_users_modes_c,
3348 SilcChannelID ***channel_ids,
3349 unsigned long creation_time)
3351 SilcIDCacheList list;
3352 SilcIDCacheEntry id_cache;
3353 SilcChannelEntry channel;
3358 int i = *channel_users_modes_c;
3361 SILC_LOG_DEBUG(("Start"));
3363 /* Go through all channels in the list */
3364 if (silc_idcache_get_all(id_list->channels, &list)) {
3365 if (silc_idcache_list_first(list, &id_cache)) {
3367 channel = (SilcChannelEntry)id_cache->context;
3369 if (creation_time && channel->created < creation_time)
3374 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3375 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3376 name_len = strlen(channel->channel_name);
3379 len = 4 + name_len + id_len + 4;
3381 silc_buffer_realloc(*channels,
3382 (*channels ? (*channels)->truelen +
3384 silc_buffer_pull_tail(*channels,
3385 ((*channels)->end - (*channels)->data));
3386 silc_buffer_format(*channels,
3387 SILC_STR_UI_SHORT(name_len),
3388 SILC_STR_UI_XNSTRING(channel->channel_name,
3390 SILC_STR_UI_SHORT(id_len),
3391 SILC_STR_UI_XNSTRING(cid, id_len),
3392 SILC_STR_UI_INT(channel->mode),
3394 silc_buffer_pull(*channels, len);
3397 *channel_users_modes = silc_realloc(*channel_users_modes,
3398 sizeof(**channel_users_modes) *
3400 (*channel_users_modes)[i] = NULL;
3401 *channel_ids = silc_realloc(*channel_ids,
3402 sizeof(**channel_ids) * (i + 1));
3403 (*channel_ids)[i] = NULL;
3404 silc_server_announce_get_channel_users(server, channel,
3406 &(*channel_users_modes)[i]);
3407 (*channel_ids)[i] = channel->id;
3410 if (!silc_idcache_list_next(list, &id_cache))
3414 *channel_users_modes_c += i;
3417 silc_idcache_list_free(list);
3421 /* This function is used to announce our existing channels to our router
3422 when we've connected to it. This also announces the users on the
3423 channels to the router. If the `creation_time' is non-zero only the
3424 channels that was created after the `creation_time' are announced.
3425 Note that the channel users are still announced even if the `creation_time'
3428 void silc_server_announce_channels(SilcServer server,
3429 unsigned long creation_time,
3430 SilcSocketConnection remote)
3432 SilcBuffer channels = NULL, channel_users = NULL;
3433 SilcBuffer *channel_users_modes = NULL;
3434 uint32 channel_users_modes_c = 0;
3435 SilcChannelID **channel_ids = NULL;
3437 SILC_LOG_DEBUG(("Announcing channels and channel users"));
3439 /* Get channels and channel users in local list */
3440 silc_server_announce_get_channels(server, server->local_list,
3441 &channels, &channel_users,
3442 &channel_users_modes,
3443 &channel_users_modes_c,
3444 &channel_ids, creation_time);
3446 /* Get channels and channel users in global list */
3447 if (server->server_type != SILC_SERVER)
3448 silc_server_announce_get_channels(server, server->global_list,
3449 &channels, &channel_users,
3450 &channel_users_modes,
3451 &channel_users_modes_c,
3452 &channel_ids, creation_time);
3455 silc_buffer_push(channels, channels->data - channels->head);
3456 SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3458 /* Send the packet */
3459 silc_server_packet_send(server, remote,
3460 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3461 channels->data, channels->len,
3464 silc_buffer_free(channels);
3467 if (channel_users) {
3468 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3469 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
3470 channel_users->len);
3472 /* Send the packet */
3473 silc_server_packet_send(server, remote,
3474 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3475 channel_users->data, channel_users->len,
3478 silc_buffer_free(channel_users);
3481 if (channel_users_modes) {
3484 for (i = 0; i < channel_users_modes_c; i++) {
3485 silc_buffer_push(channel_users_modes[i],
3486 channel_users_modes[i]->data -
3487 channel_users_modes[i]->head);
3488 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
3489 channel_users_modes[i]->len);
3490 silc_server_packet_send_dest(server, remote,
3491 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3492 channel_ids[i], SILC_ID_CHANNEL,
3493 channel_users_modes[i]->data,
3494 channel_users_modes[i]->len,
3496 silc_buffer_free(channel_users_modes[i]);
3498 silc_free(channel_users_modes);
3499 silc_free(channel_ids);
3503 /* Failure timeout callback. If this is called then we will immediately
3504 process the received failure. We always process the failure with timeout
3505 since we do not want to blindly trust to received failure packets.
3506 This won't be called (the timeout is cancelled) if the failure was
3507 bogus (it is bogus if remote does not close the connection after sending
3510 SILC_TASK_CALLBACK(silc_server_failure_callback)
3512 SilcServerFailureContext f = (SilcServerFailureContext)context;
3514 if (f->sock->protocol) {
3515 f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
3516 silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
3522 /* Assembles user list and users mode list from the `channel'. */
3524 void silc_server_get_users_on_channel(SilcServer server,
3525 SilcChannelEntry channel,
3526 SilcBuffer *user_list,
3527 SilcBuffer *mode_list,
3530 SilcChannelClientEntry chl;
3531 SilcHashTableList htl;
3532 SilcBuffer client_id_list;
3533 SilcBuffer client_mode_list;
3535 uint32 list_count = 0, len = 0;
3537 silc_hash_table_list(channel->user_list, &htl);
3538 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
3539 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
3541 client_id_list = silc_buffer_alloc(len);
3543 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
3544 silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
3545 silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
3547 silc_hash_table_list(channel->user_list, &htl);
3548 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3550 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3551 silc_buffer_put(client_id_list, idp->data, idp->len);
3552 silc_buffer_pull(client_id_list, idp->len);
3553 silc_buffer_free(idp);
3555 /* Client's mode on channel */
3556 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
3557 silc_buffer_pull(client_mode_list, 4);
3561 silc_buffer_push(client_id_list,
3562 client_id_list->data - client_id_list->head);
3563 silc_buffer_push(client_mode_list,
3564 client_mode_list->data - client_mode_list->head);
3566 *user_list = client_id_list;
3567 *mode_list = client_mode_list;
3568 *user_count = list_count;
3571 /* Saves users and their modes to the `channel'. */
3573 void silc_server_save_users_on_channel(SilcServer server,
3574 SilcSocketConnection sock,
3575 SilcChannelEntry channel,
3576 SilcClientID *noadd,
3577 SilcBuffer user_list,
3578 SilcBuffer mode_list,
3583 for (i = 0; i < user_count; i++) {
3586 SilcClientID *client_id;
3587 SilcClientEntry client;
3590 SILC_GET16_MSB(idp_len, user_list->data + 2);
3592 client_id = silc_id_payload_parse_id(user_list->data, idp_len);
3593 silc_buffer_pull(user_list, idp_len);
3598 SILC_GET32_MSB(mode, mode_list->data);
3599 silc_buffer_pull(mode_list, 4);
3601 if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
3602 silc_free(client_id);
3606 /* Check if we have this client cached already. */
3607 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3608 server->server_type, NULL);
3610 client = silc_idlist_find_client_by_id(server->global_list,
3611 client_id, server->server_type,
3614 /* If router did not find such Client ID in its lists then this must
3615 be bogus client or some router in the net is buggy. */
3616 if (server->server_type == SILC_ROUTER) {
3617 silc_free(client_id);
3621 /* We don't have that client anywhere, add it. The client is added
3622 to global list since server didn't have it in the lists so it must be
3624 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
3625 silc_id_dup(client_id, SILC_ID_CLIENT),
3626 sock->user_data, NULL);
3628 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
3629 silc_free(client_id);
3633 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3636 silc_free(client_id);
3638 if (!silc_server_client_on_channel(client, channel)) {
3639 /* Client was not on the channel, add it. */
3640 SilcChannelClientEntry chl = silc_calloc(1, sizeof(*chl));
3641 chl->client = client;
3643 chl->channel = channel;
3644 silc_hash_table_add(channel->user_list, chl->client, chl);
3645 silc_hash_table_add(client->channels, chl->channel, chl);
3650 /* Lookups route to the client indicated by the `id_data'. The connection
3651 object and internal data object is returned. Returns NULL if route
3652 could not be found to the client. If the `client_id' is specified then
3653 it is used and the `id_data' is ignored. */
3655 SilcSocketConnection silc_server_get_client_route(SilcServer server,
3656 unsigned char *id_data,
3658 SilcClientID *client_id,
3659 SilcIDListData *idata)
3662 SilcClientEntry client;
3664 SILC_LOG_DEBUG(("Start"));
3666 /* Decode destination Client ID */
3668 id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
3670 SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
3674 id = silc_id_dup(client_id, SILC_ID_CLIENT);
3677 /* If the destination belongs to our server we don't have to route
3678 the packet anywhere but to send it to the local destination. */
3679 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
3683 /* If we are router and the client has router then the client is in
3684 our cell but not directly connected to us. */
3685 if (server->server_type == SILC_ROUTER && client->router) {
3686 /* We are of course in this case the client's router thus the route
3687 to the client is the server who owns the client. So, we will send
3688 the packet to that server. */
3690 *idata = (SilcIDListData)client->router;
3691 return client->router->connection;
3694 /* Seems that client really is directly connected to us */
3696 *idata = (SilcIDListData)client;
3697 return client->connection;
3700 /* Destination belongs to someone not in this server. If we are normal
3701 server our action is to send the packet to our router. */
3702 if (server->server_type != SILC_ROUTER && !server->standalone) {
3705 *idata = (SilcIDListData)server->router;
3706 return server->router->connection;
3709 /* We are router and we will perform route lookup for the destination
3710 and send the packet to fastest route. */
3711 if (server->server_type == SILC_ROUTER && !server->standalone) {
3712 /* Check first that the ID is valid */
3713 client = silc_idlist_find_client_by_id(server->global_list, id,
3716 SilcSocketConnection dst_sock;
3718 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
3722 *idata = (SilcIDListData)dst_sock->user_data;
3731 /* Encodes and returns channel list of channels the `client' has joined.
3732 Secret channels are not put to the list. */
3734 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
3735 SilcClientEntry client)
3737 SilcBuffer buffer = NULL;
3738 SilcChannelEntry channel;
3739 SilcChannelClientEntry chl;
3740 SilcHashTableList htl;
3746 silc_hash_table_list(client->channels, &htl);
3747 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3748 channel = chl->channel;
3750 if (channel->mode & SILC_CHANNEL_MODE_SECRET ||
3751 channel->mode & SILC_CHANNEL_MODE_PRIVATE)
3754 cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3755 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3756 name_len = strlen(channel->channel_name);
3758 len = 4 + name_len + id_len + 4;
3759 buffer = silc_buffer_realloc(buffer,
3760 (buffer ? (buffer)->truelen + len : len));
3761 silc_buffer_pull_tail(buffer, ((buffer)->end - (buffer)->data));
3762 silc_buffer_format(buffer,
3763 SILC_STR_UI_SHORT(name_len),
3764 SILC_STR_UI_XNSTRING(channel->channel_name,
3766 SILC_STR_UI_SHORT(id_len),
3767 SILC_STR_UI_XNSTRING(cid, id_len),
3768 SILC_STR_UI_INT(chl->mode), /* Client's mode */
3770 silc_buffer_pull(buffer, len);
3775 silc_buffer_push(buffer, buffer->data - buffer->head);
3780 /* Finds client entry by Client ID and if it is not found then resolves
3781 it using WHOIS command. */
3783 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
3784 SilcClientID *client_id)
3786 SilcClientEntry client;
3788 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3791 client = silc_idlist_find_client_by_id(server->global_list,
3792 client_id, TRUE, NULL);
3793 if (!client && server->server_type == SILC_ROUTER)
3797 if (!client && server->standalone)
3800 if (!client || !client->nickname || !client->username) {
3801 SilcBuffer buffer, idp;
3803 client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
3804 client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
3805 client->resolve_cmd_ident = ++server->cmd_ident;
3807 idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3808 buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
3809 server->cmd_ident, 1,
3810 3, idp->data, idp->len);
3811 silc_server_packet_send(server, client ? client->router->connection :
3812 server->router->connection,
3813 SILC_PACKET_COMMAND, 0,
3814 buffer->data, buffer->len, FALSE);
3815 silc_buffer_free(idp);
3816 silc_buffer_free(buffer);
3823 /* A timeout callback for the re-key. We will be the initiator of the
3826 SILC_TASK_CALLBACK(silc_server_rekey_callback)
3828 SilcSocketConnection sock = (SilcSocketConnection)context;
3829 SilcIDListData idata = (SilcIDListData)sock->user_data;
3830 SilcServer server = (SilcServer)idata->rekey->context;
3831 SilcProtocol protocol;
3832 SilcServerRekeyInternalContext *proto_ctx;
3834 SILC_LOG_DEBUG(("Start"));
3836 /* Allocate internal protocol context. This is sent as context
3838 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3839 proto_ctx->server = (void *)server;
3840 proto_ctx->sock = sock;
3841 proto_ctx->responder = FALSE;
3842 proto_ctx->pfs = idata->rekey->pfs;
3844 /* Perform rekey protocol. Will call the final callback after the
3845 protocol is over. */
3846 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3847 &protocol, proto_ctx, silc_server_rekey_final);
3848 sock->protocol = protocol;
3850 /* Run the protocol */
3851 silc_protocol_execute(protocol, server->schedule, 0, 0);
3853 /* Re-register re-key timeout */
3854 silc_schedule_task_add(server->schedule, sock->sock,
3855 silc_server_rekey_callback,
3856 context, idata->rekey->timeout, 0,
3857 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
3860 /* The final callback for the REKEY protocol. This will actually take the
3861 new key material into use. */
3863 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
3865 SilcProtocol protocol = (SilcProtocol)context;
3866 SilcServerRekeyInternalContext *ctx =
3867 (SilcServerRekeyInternalContext *)protocol->context;
3868 SilcServer server = (SilcServer)ctx->server;
3869 SilcSocketConnection sock = ctx->sock;
3871 SILC_LOG_DEBUG(("Start"));
3873 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
3874 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
3875 /* Error occured during protocol */
3876 SILC_LOG_ERROR(("Error occurred during rekey protocol"));
3877 silc_protocol_cancel(protocol, server->schedule);
3878 silc_protocol_free(protocol);
3879 sock->protocol = NULL;
3881 silc_packet_context_free(ctx->packet);
3883 silc_ske_free(ctx->ske);
3888 /* Purge the outgoing data queue to assure that all rekey packets really
3889 go to the network before we quit the protocol. */
3890 silc_server_packet_queue_purge(server, sock);
3893 silc_protocol_free(protocol);
3894 sock->protocol = NULL;
3896 silc_packet_context_free(ctx->packet);
3898 silc_ske_free(ctx->ske);