5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2007 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /************************* Types and definitions ****************************/
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
28 SILC_TASK_CALLBACK(silc_server_do_rekey);
29 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
30 static void silc_server_accept_new_connection(SilcNetStatus status,
33 static void silc_server_packet_parse_type(SilcServer server,
34 SilcPacketStream sock,
36 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
40 /************************ Static utility functions **************************/
42 /* SKE public key verification callback */
45 silc_server_verify_key(SilcSKE ske,
46 SilcPublicKey public_key,
48 SilcSKEVerifyCbCompletion completion,
49 void *completion_context)
51 SilcPacketStream sock = context;
52 SilcUnknownEntry entry = silc_packet_get_context(sock);
54 SILC_LOG_DEBUG(("Verifying public key"));
56 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
57 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
58 entry->hostname, entry->ip, entry->port,
59 silc_pkcs_get_type(public_key)));
60 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
65 /* We accept all keys without explicit verification */
66 completion(ske, SILC_SKE_STATUS_OK, completion_context);
70 /************************ Packet engine callbacks ***************************/
72 /* Packet engine callback to receive a packet */
74 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
75 SilcPacketStream stream,
77 void *callback_context,
80 SilcServer server = callback_context;
81 SilcIDListData idata = stream_context;
86 /* Packets we do not handle */
87 switch (packet->type) {
88 case SILC_PACKET_HEARTBEAT:
89 case SILC_PACKET_SUCCESS:
90 case SILC_PACKET_FAILURE:
91 case SILC_PACKET_REJECT:
92 case SILC_PACKET_KEY_EXCHANGE:
93 case SILC_PACKET_KEY_EXCHANGE_1:
94 case SILC_PACKET_KEY_EXCHANGE_2:
95 case SILC_PACKET_REKEY_DONE:
96 case SILC_PACKET_CONNECTION_AUTH:
101 /* Only specific packets can come without source ID present. */
102 if ((!packet->src_id ||
103 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
104 packet->type != SILC_PACKET_NEW_CLIENT &&
105 packet->type != SILC_PACKET_NEW_SERVER &&
106 packet->type != SILC_PACKET_RESUME_CLIENT &&
107 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
108 packet->type != SILC_PACKET_DISCONNECT)
111 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and
112 for unregistered connection. */
113 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
114 packet->type == SILC_PACKET_NEW_SERVER) &&
115 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
118 /* Ignore packets from disabled connection */
119 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
120 packet->type != SILC_PACKET_HEARTBEAT &&
121 packet->type != SILC_PACKET_RESUME_ROUTER &&
122 packet->type != SILC_PACKET_REKEY)
125 /* Check that the the current client ID is same as in the client's packet. */
126 if (idata->conn_type == SILC_CONN_CLIENT) {
127 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
128 SilcClientID client_id;
130 if (client->id && packet->src_id &&
131 silc_id_str2id(packet->src_id, packet->src_id_len,
132 packet->src_id_type, &client_id, sizeof(client_id))) {
133 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
134 SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
135 silc_get_packet_name(packet->type)));
141 if (server->server_type == SILC_ROUTER) {
142 /* Route the packet if it is not destined to us. Other ID types but
143 server are handled separately after processing them. */
144 if (packet->dst_id &&
145 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
146 packet->dst_id_type == SILC_ID_SERVER &&
147 idata->conn_type != SILC_CONN_CLIENT &&
148 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
149 SilcPacketStream conn;
150 SilcServerID server_id;
152 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
153 &server_id, sizeof(server_id));
155 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
157 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
158 silc_id_render(&server_id, SILC_ID_SERVER)));
162 silc_server_packet_route(server, conn, packet);
163 silc_packet_free(packet);
168 /* Broadcast packet if it is marked as broadcast packet and it is
169 originated from router and we are router. */
170 if (server->server_type == SILC_ROUTER &&
171 idata->conn_type == SILC_CONN_ROUTER &&
172 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
173 /* Broadcast to our primary route */
174 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
176 /* If we have backup routers then we need to feed all broadcast
177 data to those servers. */
178 silc_server_backup_broadcast(server, stream, packet);
182 silc_server_packet_parse_type(server, stream, packet);
187 /* Packet engine callback to indicate end of stream */
189 static void silc_server_packet_eos(SilcPacketEngine engine,
190 SilcPacketStream stream,
191 void *callback_context,
192 void *stream_context)
194 SilcServer server = callback_context;
195 SilcIDListData idata = silc_packet_get_context(stream);
197 SILC_LOG_DEBUG(("End of stream received"));
202 if (server->router_conn && server->router_conn->sock == stream &&
203 !server->router && server->standalone) {
204 silc_server_create_connections(server);
205 silc_server_free_sock_user_data(server, stream, NULL);
207 /* If backup disconnected then mark that resuming will not be allowed */
208 if (server->server_type == SILC_ROUTER && !server->backup_router &&
209 idata->conn_type == SILC_CONN_SERVER) {
210 SilcServerEntry server_entry = (SilcServerEntry)idata;
211 if (server_entry->server_type == SILC_BACKUP_ROUTER)
212 server->backup_closed = TRUE;
215 silc_server_free_sock_user_data(server, stream, NULL);
218 silc_server_close_connection(server, stream);
221 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
223 SilcServer server = app_context;
224 SilcPacketStream stream = context;
225 SilcIDListData idata = silc_packet_get_context(stream);
230 if (server->router_conn && server->router_conn->sock == stream &&
231 !server->router && server->standalone) {
232 silc_server_create_connections(server);
234 /* If backup disconnected then mark that resuming will not be allowed */
235 if (server->server_type == SILC_ROUTER && !server->backup_router &&
236 idata->conn_type == SILC_CONN_SERVER) {
237 SilcServerEntry server_entry = (SilcServerEntry)idata;
238 if (server_entry->server_type == SILC_BACKUP_ROUTER)
239 server->backup_closed = TRUE;
242 silc_server_free_sock_user_data(server, stream, NULL);
245 silc_server_close_connection(server, stream);
248 /* Packet engine callback to indicate error */
250 static void silc_server_packet_error(SilcPacketEngine engine,
251 SilcPacketStream stream,
252 SilcPacketError error,
253 void *callback_context,
254 void *stream_context)
256 SilcServer server = callback_context;
257 SilcIDListData idata = silc_packet_get_context(stream);
258 SilcStream sock = silc_packet_stream_get_stream(stream);
265 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
268 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
269 SILC_CONNTYPE_STRING(idata->conn_type),
270 silc_packet_error_string(error)));
272 silc_schedule_task_add_timeout(server->schedule,
273 silc_server_packet_error_timeout,
277 /* Packet stream callbacks */
278 static SilcPacketCallbacks silc_server_stream_cbs =
280 silc_server_packet_receive,
281 silc_server_packet_eos,
282 silc_server_packet_error
285 /* Parses the packet type and calls what ever routines the packet type
286 requires. This is done for all incoming packets. */
288 static void silc_server_packet_parse_type(SilcServer server,
289 SilcPacketStream sock,
292 SilcPacketType type = packet->type;
293 SilcIDListData idata = silc_packet_get_context(sock);
295 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
296 silc_get_packet_name(type), packet->flags));
298 /* Parse the packet type */
300 case SILC_PACKET_NOTIFY:
302 * Received notify packet. Server can receive notify packets from
303 * router. Server then relays the notify messages to clients if needed.
305 if (packet->flags & SILC_PACKET_FLAG_LIST)
306 silc_server_notify_list(server, sock, packet);
308 silc_server_notify(server, sock, packet);
312 * Private Message packets
314 case SILC_PACKET_PRIVATE_MESSAGE:
316 * Received private message packet. The packet is coming from either
319 if (packet->flags & SILC_PACKET_FLAG_LIST)
321 idata->last_receive = time(NULL);
322 silc_server_private_message(server, sock, packet);
328 case SILC_PACKET_CHANNEL_MESSAGE:
330 * Received channel message. Channel messages are special packets
331 * (although probably most common ones) thus they are handled
334 if (packet->flags & SILC_PACKET_FLAG_LIST)
336 idata->last_receive = time(NULL);
337 silc_server_channel_message(server, sock, packet);
343 case SILC_PACKET_COMMAND:
345 * Recived command. Processes the command request and allocates the
346 * command context and calls the command.
348 if (packet->flags & SILC_PACKET_FLAG_LIST)
350 server->stat.commands_received++;
351 silc_server_command_process(server, sock, packet);
354 case SILC_PACKET_COMMAND_REPLY:
356 * Received command reply packet. Received command reply to command. It
357 * may be reply to command sent by us or reply to command sent by client
358 * that we've routed further.
360 if (packet->flags & SILC_PACKET_FLAG_LIST)
362 server->stat.commands_received++;
363 silc_server_command_reply(server, sock, packet);
366 case SILC_PACKET_DISCONNECT:
369 char *message = NULL;
370 const char *hostname, *ip;
372 if (packet->flags & SILC_PACKET_FLAG_LIST)
374 if (silc_buffer_len(&packet->buffer) < 1)
377 status = (SilcStatus)packet->buffer.data[0];
378 if (silc_buffer_len(&packet->buffer) > 1 &&
379 silc_utf8_valid(packet->buffer.data + 1,
380 silc_buffer_len(&packet->buffer) - 1))
381 message = silc_memdup(packet->buffer.data + 1,
382 silc_buffer_len(&packet->buffer) - 1);
384 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
385 NULL, &hostname, &ip, NULL))
388 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
389 silc_get_status_message(status), status,
390 message ? message : ""));
394 /* Do not switch to backup in case of error */
395 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
397 /* If backup disconnected then mark that resuming will not be allowed */
398 if (server->server_type == SILC_ROUTER && !server->backup_router &&
399 idata->conn_type == SILC_CONN_SERVER) {
400 SilcServerEntry server_entry = (SilcServerEntry)idata;
401 if (server_entry->server_type == SILC_BACKUP_ROUTER)
402 server->backup_closed = TRUE;
405 /* Handle the disconnection from our end too */
406 if (SILC_IS_LOCAL(idata))
407 silc_server_free_sock_user_data(server, sock, NULL);
408 silc_server_close_connection(server, sock);
409 server->backup_noswitch = FALSE;
413 case SILC_PACKET_CHANNEL_KEY:
415 * Received key for channel. As channels are created by the router
416 * the keys are as well. We will distribute the key to all of our
417 * locally connected clients on the particular channel. Router
418 * never receives this channel and thus is ignored.
420 if (packet->flags & SILC_PACKET_FLAG_LIST)
422 silc_server_channel_key(server, sock, packet);
425 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
427 * Private message key packet.
429 if (packet->flags & SILC_PACKET_FLAG_LIST)
431 silc_server_private_message_key(server, sock, packet);
434 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
436 * Connection authentication request packet. When we receive this packet
437 * we will send to the other end information about our mandatory
438 * authentication method for the connection. This packet maybe received
441 if (packet->flags & SILC_PACKET_FLAG_LIST)
443 silc_server_connection_auth_request(server, sock, packet);
446 case SILC_PACKET_NEW_ID:
448 * Received New ID packet. This includes some new ID that has been
449 * created. It may be for client, server or channel. This is the way
450 * to distribute information about new registered entities in the
453 if (packet->flags & SILC_PACKET_FLAG_LIST)
454 silc_server_new_id_list(server, sock, packet);
456 silc_server_new_id(server, sock, packet);
459 case SILC_PACKET_NEW_CLIENT:
461 * Received new client packet. This includes client information that
462 * we will use to create initial client ID. After creating new
463 * ID we will send it to the client.
465 if (packet->flags & SILC_PACKET_FLAG_LIST)
467 silc_server_new_client(server, sock, packet);
470 case SILC_PACKET_NEW_SERVER:
472 * Received new server packet. This includes Server ID and some other
473 * information that we may save. This is received after server has
476 if (packet->flags & SILC_PACKET_FLAG_LIST)
478 silc_server_new_server(server, sock, packet);
481 case SILC_PACKET_NEW_CHANNEL:
483 * Received new channel packet. Information about new channel in the
484 * network are distributed using this packet.
486 if (packet->flags & SILC_PACKET_FLAG_LIST)
487 silc_server_new_channel_list(server, sock, packet);
489 silc_server_new_channel(server, sock, packet);
492 case SILC_PACKET_HEARTBEAT:
494 * Received heartbeat.
496 if (packet->flags & SILC_PACKET_FLAG_LIST)
500 case SILC_PACKET_KEY_AGREEMENT:
502 * Received heartbeat.
504 if (packet->flags & SILC_PACKET_FLAG_LIST)
506 silc_server_key_agreement(server, sock, packet);
509 case SILC_PACKET_REKEY:
511 * Received re-key packet. The sender wants to regenerate the session
514 if (packet->flags & SILC_PACKET_FLAG_LIST)
516 silc_server_rekey(server, sock, packet);
519 case SILC_PACKET_FTP:
521 if (packet->flags & SILC_PACKET_FLAG_LIST)
523 silc_server_ftp(server, sock, packet);
526 case SILC_PACKET_RESUME_CLIENT:
528 if (packet->flags & SILC_PACKET_FLAG_LIST)
530 silc_server_resume_client(server, sock, packet);
533 case SILC_PACKET_RESUME_ROUTER:
534 /* Resume router packet received. This packet is received for backup
535 router resuming protocol. */
536 if (packet->flags & SILC_PACKET_FLAG_LIST)
538 silc_server_backup_resume_router(server, sock, packet);
542 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
547 /****************************** Server API **********************************/
549 /* Allocates a new SILC server object. This has to be done before the server
550 can be used. After allocation one must call silc_server_init to initialize
551 the server. The new allocated server object is returned to the new_server
554 SilcBool silc_server_alloc(SilcServer *new_server)
558 SILC_LOG_DEBUG(("Allocating new server object"));
560 server = silc_calloc(1, sizeof(*server));
563 server->server_type = SILC_SERVER;
564 server->standalone = TRUE;
565 server->local_list = silc_calloc(1, sizeof(*server->local_list));
566 if (!server->local_list)
568 server->global_list = silc_calloc(1, sizeof(*server->global_list));
569 if (!server->global_list)
571 server->pending_commands = silc_dlist_init();
572 if (!server->pending_commands)
574 server->listeners = silc_dlist_init();
575 if (!server->listeners)
577 server->repository = silc_skr_alloc();
578 if (!server->repository)
580 server->conns = silc_dlist_init();
583 server->expired_clients = silc_dlist_init();
584 if (!server->expired_clients)
587 *new_server = server;
592 /* Free's the SILC server object. This is called at the very end before
595 void silc_server_free(SilcServer server)
598 SilcIDCacheEntry cache;
599 SilcIDListData idata;
601 SILC_LOG_DEBUG(("Free server %p", server));
606 silc_server_backup_free(server);
607 silc_server_config_unref(&server->config_ref);
609 silc_rng_free(server->rng);
610 if (server->public_key)
611 silc_pkcs_public_key_free(server->public_key);
612 if (server->private_key)
613 silc_pkcs_private_key_free(server->private_key);
614 if (server->pending_commands)
615 silc_dlist_uninit(server->pending_commands);
616 if (server->id_entry) {
617 if (server->id_entry->data.sconn)
618 silc_schedule_task_del_by_context(server->schedule,
619 server->id_entry->data.sconn->sock);
620 silc_idlist_del_server(server->local_list, server->id_entry);
623 /* Delete all channels */
624 if (silc_idcache_get_all(server->local_list->channels, &list)) {
625 silc_list_start(list);
626 while ((cache = silc_list_get(list)))
627 silc_idlist_del_channel(server->local_list, cache->context);
629 if (silc_idcache_get_all(server->global_list->channels, &list)) {
630 silc_list_start(list);
631 while ((cache = silc_list_get(list)))
632 silc_idlist_del_channel(server->global_list, cache->context);
635 /* Delete all clients */
636 if (silc_idcache_get_all(server->local_list->clients, &list)) {
637 silc_list_start(list);
638 while ((cache = silc_list_get(list))) {
639 silc_schedule_task_del_by_context(server->schedule, cache->context);
640 silc_idlist_del_client(server->local_list, cache->context);
643 if (silc_idcache_get_all(server->global_list->clients, &list)) {
644 silc_list_start(list);
645 while ((cache = silc_list_get(list))) {
646 silc_schedule_task_del_by_context(server->schedule, cache->context);
647 silc_idlist_del_client(server->global_list, cache->context);
651 /* Delete all servers */
652 if (silc_idcache_get_all(server->local_list->servers, &list)) {
653 silc_list_start(list);
654 while ((cache = silc_list_get(list))) {
655 idata = (SilcIDListData)cache->context;
657 silc_schedule_task_del_by_context(server->schedule,
659 silc_idlist_del_server(server->local_list, cache->context);
662 if (silc_idcache_get_all(server->global_list->servers, &list)) {
663 while ((cache = silc_list_get(list))) {
664 idata = (SilcIDListData)cache->context;
666 silc_schedule_task_del_by_context(server->schedule,
668 silc_idlist_del_server(server->global_list, cache->context);
672 silc_schedule_task_del_by_context(server->schedule, server);
673 silc_schedule_uninit(server->schedule);
674 server->schedule = NULL;
676 silc_idcache_free(server->local_list->clients);
677 silc_idcache_free(server->local_list->servers);
678 silc_idcache_free(server->local_list->channels);
679 silc_idcache_free(server->global_list->clients);
680 silc_idcache_free(server->global_list->servers);
681 silc_idcache_free(server->global_list->channels);
682 silc_hash_table_free(server->watcher_list);
683 silc_hash_table_free(server->watcher_list_pk);
684 silc_hash_free(server->md5hash);
685 silc_hash_free(server->sha1hash);
687 silc_dlist_uninit(server->listeners);
688 silc_dlist_uninit(server->conns);
689 silc_dlist_uninit(server->expired_clients);
690 silc_skr_free(server->repository);
691 silc_packet_engine_stop(server->packet_engine);
693 silc_free(server->local_list);
694 silc_free(server->global_list);
695 silc_free(server->server_name);
698 silc_hmac_unregister_all();
699 silc_hash_unregister_all();
700 silc_cipher_unregister_all();
701 silc_pkcs_unregister_all();
704 /* Creates a new server listener. */
706 static SilcNetListener
707 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
709 SilcNetListener listener;
712 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
713 server->config->require_reverse_lookup,
715 silc_server_accept_new_connection, server);
717 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
725 /* Adds a secondary listener. */
727 SilcBool silc_server_init_secondary(SilcServer server)
729 SilcServerConfigServerInfoInterface *interface;
730 SilcNetListener listener;
732 for (interface = server->config->server_info->secondary; interface;
733 interface = interface->next) {
734 listener = silc_server_listen(server, interface->server_ip,
738 silc_dlist_add(server->listeners, listener);
744 /* Initializes the entire SILC server. This is called always before running
745 the server. This is called only once at the initialization of the program.
746 This binds the server to its listenning port. After this function returns
747 one should call silc_server_run to start the server. This returns TRUE
748 when everything is ok to run the server. Configuration file must be
749 read and parsed before calling this. */
751 SilcBool silc_server_init(SilcServer server)
754 SilcServerEntry id_entry;
755 SilcNetListener listener;
759 SILC_LOG_DEBUG(("Initializing server"));
761 server->starttime = time(NULL);
763 /* Take config object for us */
764 silc_server_config_ref(&server->config_ref, server->config,
768 /* Set debugging on if configured */
769 if (server->config->debug_string) {
770 silc_log_debug(TRUE);
771 silc_log_set_debug_string(server->config->debug_string);
773 #endif /* SILC_DEBUG */
775 /* Steal public and private key from the config object */
776 server->public_key = server->config->server_info->public_key;
777 server->private_key = server->config->server_info->private_key;
778 server->config->server_info->public_key = NULL;
779 server->config->server_info->private_key = NULL;
781 /* Register all configured ciphers, PKCS and hash functions. */
782 if (!silc_server_config_register_ciphers(server))
783 silc_cipher_register_default();
784 if (!silc_server_config_register_pkcs(server))
785 silc_pkcs_register_default();
786 if (!silc_server_config_register_hashfuncs(server))
787 silc_hash_register_default();
788 if (!silc_server_config_register_hmacs(server))
789 silc_hmac_register_default();
791 /* Initialize random number generator for the server. */
792 server->rng = silc_rng_alloc();
793 silc_rng_init(server->rng);
794 silc_rng_global_init(server->rng);
796 /* Initialize hash functions for server to use */
797 silc_hash_alloc("md5", &server->md5hash);
798 silc_hash_alloc("sha1", &server->sha1hash);
800 /* Initialize the scheduler */
801 server->schedule = silc_schedule_init(server->config->param.connections_max,
803 if (!server->schedule)
806 /* First, register log files configuration for error output */
807 silc_server_config_setlogfiles(server);
809 /* Initialize ID caches */
810 server->local_list->clients =
811 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
813 server->local_list->servers =
814 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
816 server->local_list->channels =
817 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
820 /* These are allocated for normal server as well as these hold some
821 global information that the server has fetched from its router. For
822 router these are used as they are supposed to be used on router. */
823 server->global_list->clients =
824 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
826 server->global_list->servers =
827 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
829 server->global_list->channels =
830 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
833 /* Init watcher lists */
834 server->watcher_list =
835 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
836 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
838 if (!server->watcher_list)
840 server->watcher_list_pk =
841 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
842 silc_hash_public_key_compare, NULL,
844 if (!server->watcher_list_pk)
847 /* Create TCP listener */
848 listener = silc_server_listen(
850 server->config->server_info->primary == NULL ? NULL :
851 server->config->server_info->primary->server_ip,
852 server->config->server_info->primary == NULL ? 0 :
853 server->config->server_info->primary->port);
856 silc_dlist_add(server->listeners, listener);
858 /* Create a Server ID for the server. */
859 port = silc_net_listener_get_port(listener, NULL);
860 ip = silc_net_listener_get_ip(listener, NULL);
861 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
862 server->config->server_info->primary->public_ip :
863 ip[0], port[0], server->rng, &id);
872 server->server_name = server->config->server_info->server_name;
873 server->config->server_info->server_name = NULL;
874 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
875 sizeof(server->id_string), &server->id_string_len);
877 /* Add ourselves to the server list. We don't have a router yet
878 beacuse we haven't established a route yet. It will be done later.
879 For now, NULL is sent as router. This allocates new entry to
882 silc_idlist_add_server(server->local_list, strdup(server->server_name),
884 silc_id_dup(server->id, SILC_ID_SERVER),
887 SILC_LOG_ERROR(("Could not add local server to cache"));
890 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
891 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
892 SILC_CONN_SERVER : SILC_CONN_ROUTER);
893 server->id_entry = id_entry;
895 /* Create secondary TCP listeners */
896 if (silc_server_init_secondary(server) == FALSE)
899 server->listenning = TRUE;
901 /* Create connections to configured routers. */
902 silc_server_create_connections(server);
904 /* If server connections has been configured then we must be router as
905 normal server cannot have server connections, only router connections. */
906 if (server->config->servers) {
907 SilcServerConfigServer *ptr = server->config->servers;
909 server->server_type = SILC_ROUTER;
911 if (ptr->backup_router) {
912 server->server_type = SILC_BACKUP_ROUTER;
913 server->backup_router = TRUE;
914 server->id_entry->server_type = SILC_BACKUP_ROUTER;
921 if (server->server_type != SILC_ROUTER) {
922 server->stat.servers = 1;
923 server->stat.cell_servers = 1;
925 server->stat.routers = 1;
928 /* If we are normal server we'll retrieve network statisticial information
929 once in a while from the router. */
930 if (server->server_type != SILC_ROUTER)
931 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
934 /* Start packet engine */
935 server->packet_engine =
936 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
937 &silc_server_stream_cbs, server);
938 if (!server->packet_engine)
941 /* Register client entry expiration timeout */
942 silc_schedule_task_add_timeout(server->schedule,
943 silc_server_purge_expired_clients, server,
946 /* Initialize HTTP server */
947 silc_server_http_init(server);
949 SILC_LOG_DEBUG(("Server initialized"));
951 /* We are done here, return succesfully */
955 silc_server_config_unref(&server->config_ref);
959 /* Task callback to close a socket connection after rehash */
961 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
963 SilcServer server = app_context;
964 SilcPacketStream sock = context;
965 SilcIDListData idata = silc_packet_get_context(sock);
966 const char *hostname;
969 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
970 NULL, &hostname, NULL, &port);
972 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
973 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
974 silc_schedule_task_del_by_context(server->schedule, sock);
975 silc_server_disconnect_remote(server, sock,
976 SILC_STATUS_ERR_BANNED_FROM_SERVER,
977 "This connection is removed from "
979 silc_server_free_sock_user_data(server, sock, NULL);
982 /* This function basically reads the config file again and switches the config
983 object pointed by the server object. After that, we have to fix various
984 things such as the server_name and the listening ports.
985 Keep in mind that we no longer have the root privileges at this point. */
987 SilcBool silc_server_rehash(SilcServer server)
989 SilcServerConfig newconfig;
991 SILC_LOG_INFO(("Rehashing server"));
993 /* Reset the logging system */
994 silc_log_quick(TRUE);
995 silc_log_flush_all();
997 /* Start the main rehash phase (read again the config file) */
998 newconfig = silc_server_config_alloc(server->config_file, server);
1000 SILC_LOG_ERROR(("Rehash FAILED."));
1004 /* Fix the server_name field */
1005 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1006 silc_free(server->server_name);
1008 /* Check server name */
1009 server->server_name =
1010 silc_identifier_check(newconfig->server_info->server_name,
1011 strlen(newconfig->server_info->server_name),
1012 SILC_STRING_LOCALE, 256, NULL);
1013 if (!server->server_name) {
1014 SILC_LOG_ERROR(("Malformed server name string '%s'",
1015 server->config->server_info->server_name));
1019 /* Update the idcache list with a fresh pointer */
1020 silc_free(server->id_entry->server_name);
1021 server->id_entry->server_name = strdup(server->server_name);
1022 silc_idcache_update_by_context(server->local_list->servers,
1023 server->id_entry, NULL,
1024 strdup(server->id_entry->server_name),
1029 silc_server_config_setlogfiles(server);
1031 /* Change new key pair if necessary */
1032 if (newconfig->server_info->public_key &&
1033 !silc_pkcs_public_key_compare(server->public_key,
1034 newconfig->server_info->public_key)) {
1035 silc_pkcs_public_key_free(server->public_key);
1036 silc_pkcs_private_key_free(server->private_key);
1037 server->public_key = newconfig->server_info->public_key;
1038 server->private_key = newconfig->server_info->private_key;
1039 newconfig->server_info->public_key = NULL;
1040 newconfig->server_info->private_key = NULL;
1043 /* Check for unconfigured server and router connections and close
1044 connections that were unconfigured. */
1046 if (server->config->routers) {
1047 SilcServerConfigRouter *ptr;
1048 SilcServerConfigRouter *newptr;
1051 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1054 /* Check whether new config has this one too */
1055 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1056 if (silc_string_compare(newptr->host, ptr->host) &&
1057 newptr->port == ptr->port &&
1058 newptr->initiator == ptr->initiator) {
1064 if (!found && ptr->host) {
1065 /* Remove this connection */
1066 SilcPacketStream sock;
1067 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1068 ptr->host, ptr->port);
1070 silc_schedule_task_add_timeout(server->schedule,
1071 silc_server_rehash_close_connection,
1077 if (server->config->servers) {
1078 SilcServerConfigServer *ptr;
1079 SilcServerConfigServer *newptr;
1082 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1085 /* Check whether new config has this one too */
1086 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1087 if (silc_string_compare(newptr->host, ptr->host)) {
1093 if (!found && ptr->host) {
1094 /* Remove this connection */
1095 SilcPacketStream sock;
1096 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1099 silc_schedule_task_add_timeout(server->schedule,
1100 silc_server_rehash_close_connection,
1106 if (server->config->clients) {
1107 SilcServerConfigClient *ptr;
1108 SilcServerConfigClient *newptr;
1111 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1114 /* Check whether new config has this one too */
1115 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1116 if (silc_string_compare(newptr->host, ptr->host)) {
1122 if (!found && ptr->host) {
1123 /* Remove this connection */
1124 SilcPacketStream sock;
1125 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1128 silc_schedule_task_add_timeout(server->schedule,
1129 silc_server_rehash_close_connection,
1135 /* Create connections after rehash */
1136 silc_server_create_connections(server);
1138 /* Check whether our router status has changed */
1139 if (newconfig->servers) {
1140 SilcServerConfigServer *ptr = newconfig->servers;
1142 server->server_type = SILC_ROUTER;
1144 if (ptr->backup_router) {
1145 server->server_type = SILC_BACKUP_ROUTER;
1146 server->backup_router = TRUE;
1147 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1154 /* Our old config is gone now. We'll unreference our reference made in
1155 silc_server_init and then destroy it since we are destroying it
1156 underneath the application (layer which called silc_server_init). */
1157 silc_server_config_unref(&server->config_ref);
1158 silc_server_config_destroy(server->config);
1160 /* Take new config context */
1161 server->config = newconfig;
1162 silc_server_config_ref(&server->config_ref, server->config, server->config);
1165 /* Set debugging on if configured */
1166 if (server->config->debug_string) {
1167 silc_log_debug(TRUE);
1168 silc_log_set_debug_string(server->config->debug_string);
1170 #endif /* SILC_DEBUG */
1172 SILC_LOG_DEBUG(("Server rehashed"));
1177 /* The heart of the server. This runs the scheduler thus runs the server.
1178 When this returns the server has been stopped and the program will
1181 void silc_server_run(SilcServer server)
1183 SILC_LOG_INFO(("SILC Server started"));
1185 /* Start the scheduler, the heart of the SILC server. When this returns
1186 the program will be terminated. */
1187 silc_schedule(server->schedule);
1190 /* Stops the SILC server. This function is used to shutdown the server.
1191 This is usually called after the scheduler has returned. After stopping
1192 the server one should call silc_server_free. */
1194 void silc_server_stop(SilcServer server)
1197 SilcPacketStream ps;
1198 SilcNetListener listener;
1200 SILC_LOG_INFO(("SILC Server shutting down"));
1202 server->server_shutdown = TRUE;
1204 /* Close all connections */
1205 if (server->packet_engine) {
1206 list = silc_packet_engine_get_streams(server->packet_engine);
1208 silc_dlist_start(list);
1209 while ((ps = silc_dlist_get(list))) {
1210 SilcIDListData idata = silc_packet_get_context(ps);
1212 if (!silc_packet_stream_is_valid(ps))
1216 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1218 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1219 "Server is shutting down");
1220 silc_server_free_sock_user_data(server, ps,
1221 "Server is shutting down");
1223 silc_packet_engine_free_streams_list(list);
1226 /* We are not connected to network anymore */
1227 server->standalone = TRUE;
1229 silc_dlist_start(server->listeners);
1230 while ((listener = silc_dlist_get(server->listeners)))
1231 silc_net_close_listener(listener);
1233 silc_server_http_uninit(server);
1235 /* Cancel any possible retry timeouts */
1236 silc_schedule_task_del_by_callback(server->schedule,
1237 silc_server_connect_router);
1238 silc_schedule_task_del_by_callback(server->schedule,
1239 silc_server_connect_to_router_retry);
1240 silc_schedule_task_del_by_callback(server->schedule,
1241 silc_server_connect_to_router);
1243 silc_schedule_stop(server->schedule);
1245 SILC_LOG_DEBUG(("Server stopped"));
1248 /* Purge expired client entries from the server */
1250 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1252 SilcServer server = context;
1253 SilcClientEntry client;
1255 SilcUInt64 curtime = silc_time();
1257 SILC_LOG_DEBUG(("Expire timeout"));
1259 silc_dlist_start(server->expired_clients);
1260 while ((client = silc_dlist_get(server->expired_clients))) {
1261 if (client->data.status & SILC_IDLIST_STATUS_REGISTERED)
1264 /* For unregistered clients the created timestamp is actually
1265 unregistered timestamp. Make sure client remains in history
1266 at least 500 seconds. */
1267 if (curtime - client->data.created < 500)
1270 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1271 server->local_list : server->global_list);
1273 silc_idlist_del_data(client);
1274 silc_idlist_del_client(id_list, client);
1275 silc_dlist_del(server->expired_clients, client);
1278 silc_schedule_task_add_timeout(server->schedule,
1279 silc_server_purge_expired_clients, server,
1284 /******************************* Connecting *********************************/
1286 /* Free connection context */
1288 void silc_server_connection_free(SilcServerConnection sconn)
1290 SILC_LOG_DEBUG(("Free connection %p", sconn));
1291 silc_dlist_del(sconn->server->conns, sconn);
1292 silc_server_config_unref(&sconn->conn);
1293 silc_free(sconn->remote_host);
1294 silc_free(sconn->backup_replace_ip);
1298 /* Creates connection to a remote router. */
1300 void silc_server_create_connection(SilcServer server,
1303 const char *remote_host, SilcUInt32 port,
1304 SilcServerConnectCallback callback,
1307 SilcServerConnection sconn;
1309 /* Allocate connection object for hold connection specific stuff. */
1310 sconn = silc_calloc(1, sizeof(*sconn));
1313 sconn->remote_host = strdup(remote_host);
1314 sconn->remote_port = port;
1315 sconn->no_reconnect = reconnect == FALSE;
1316 sconn->callback = callback;
1317 sconn->callback_context = context;
1318 sconn->no_conf = dynamic;
1319 sconn->server = server;
1321 SILC_LOG_DEBUG(("Created connection %p", sconn));
1323 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1327 /* Connection authentication completion callback */
1330 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1333 SilcServerConnection sconn = context;
1334 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1335 SilcServer server = entry->server;
1336 SilcServerConfigServer *conn;
1337 SilcServerConfigConnParams *param;
1338 SilcIDListData idata;
1339 SilcServerEntry id_entry = NULL;
1340 unsigned char id[32];
1345 SILC_LOG_DEBUG(("Connection %p authentication completed", sconn));
1349 if (success == FALSE) {
1350 /* Authentication failed */
1351 /* XXX retry connecting */
1353 silc_server_disconnect_remote(server, sconn->sock,
1354 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1355 if (sconn->callback)
1356 (*sconn->callback)(server, NULL, sconn->callback_context);
1357 silc_server_connection_free(sconn);
1361 /* XXX For now remote is router always */
1362 entry->data.conn_type = SILC_CONN_ROUTER;
1364 SILC_LOG_INFO(("Connected to %s %s",
1365 SILC_CONNTYPE_STRING(entry->data.conn_type),
1366 sconn->remote_host));
1368 /* Create the actual entry for remote entity */
1369 switch (entry->data.conn_type) {
1370 case SILC_CONN_SERVER:
1371 SILC_LOG_DEBUG(("Remote is SILC server"));
1373 /* Add new server. The server must register itself to us before it
1374 becomes registered to SILC network. */
1375 id_entry = silc_idlist_add_server(server->local_list,
1376 strdup(sconn->remote_host),
1377 SILC_SERVER, NULL, NULL, sconn->sock);
1379 silc_server_disconnect_remote(server, sconn->sock,
1380 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1381 if (sconn->callback)
1382 (*sconn->callback)(server, NULL, sconn->callback_context);
1383 silc_server_connection_free(sconn);
1389 server->stat.my_servers++;
1390 if (server->server_type == SILC_ROUTER)
1391 server->stat.servers++;
1392 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1394 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1397 case SILC_CONN_ROUTER:
1398 SILC_LOG_DEBUG(("Remote is SILC router"));
1400 /* Register to network */
1401 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1402 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1403 SILC_STR_UI_SHORT(id_len),
1404 SILC_STR_DATA(id, id_len),
1405 SILC_STR_UI_SHORT(strlen(server->server_name)),
1406 SILC_STR_DATA(server->server_name,
1407 strlen(server->server_name)),
1409 silc_server_disconnect_remote(server, sconn->sock,
1410 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1411 if (sconn->callback)
1412 (*sconn->callback)(server, NULL, sconn->callback_context);
1413 silc_server_connection_free(sconn);
1419 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1421 /* Check that we do not have this ID already */
1422 id_entry = silc_idlist_find_server_by_id(server->local_list,
1423 &remote_id.u.server_id,
1426 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1428 id_entry = silc_idlist_find_server_by_id(server->global_list,
1429 &remote_id.u.server_id,
1432 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1436 SILC_LOG_DEBUG(("New server id(%s)",
1437 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1439 /* Add the connected router to global server list. Router is sent
1440 as NULL since it's local to us. */
1441 id_entry = silc_idlist_add_server(server->global_list,
1442 strdup(sconn->remote_host),
1444 silc_id_dup(&remote_id.u.server_id,
1448 silc_server_disconnect_remote(server, sconn->sock,
1449 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1450 if (sconn->callback)
1451 (*sconn->callback)(server, NULL, sconn->callback_context);
1452 silc_server_connection_free(sconn);
1458 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1459 idata = (SilcIDListData)id_entry;
1460 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1461 SILC_IDLIST_STATUS_LOCAL);
1462 idata->sconn = sconn;
1465 server->stat.my_routers++;
1466 if (server->server_type == SILC_ROUTER)
1467 server->stat.routers++;
1468 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1470 if (!sconn->backup) {
1471 /* Mark this router our primary router if we're still standalone */
1472 if (server->standalone) {
1473 SILC_LOG_DEBUG(("This connection is our primary router"));
1474 server->id_entry->router = id_entry;
1475 server->router = id_entry;
1476 server->router->server_type = SILC_ROUTER;
1477 server->standalone = FALSE;
1478 server->backup_primary = FALSE;
1480 /* Announce data if we are not backup router (unless not as primary
1481 currently). Backup router announces later at the end of
1482 resuming protocol. */
1483 if (server->backup_router && server->server_type == SILC_ROUTER) {
1484 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1486 /* If we are router then announce our possible servers. Backup
1487 router announces also global servers. */
1488 if (server->server_type == SILC_ROUTER)
1489 silc_server_announce_servers(server,
1490 server->backup_router ? TRUE : FALSE,
1491 0, SILC_PRIMARY_ROUTE(server));
1493 /* Announce our clients and channels to the router */
1494 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1495 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1498 /* If we are backup router then this primary router is whom we are
1500 if (server->server_type == SILC_BACKUP_ROUTER) {
1501 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1503 NULL, NULL, &ip, NULL);
1504 silc_server_backup_add(server, server->id_entry, ip,
1505 sconn->remote_port, TRUE);
1509 /* We already have primary router. Disconnect this connection */
1510 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1511 silc_idlist_del_server(server->global_list, id_entry);
1512 silc_server_disconnect_remote(server, sconn->sock,
1513 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1514 if (sconn->callback)
1515 (*sconn->callback)(server, NULL, sconn->callback_context);
1516 silc_server_connection_free(sconn);
1522 /* Add this server to be our backup router */
1523 id_entry->server_type = SILC_BACKUP_ROUTER;
1524 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1525 sconn->backup_replace_port, FALSE);
1531 silc_server_disconnect_remote(server, sconn->sock,
1532 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1533 if (sconn->callback)
1534 (*sconn->callback)(server, NULL, sconn->callback_context);
1535 silc_server_connection_free(sconn);
1540 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1542 conn = sconn->conn.ref_ptr;
1543 param = &server->config->param;
1544 if (conn && conn->param)
1545 param = conn->param;
1547 /* Register rekey timeout */
1548 sconn->rekey_timeout = param->key_exchange_rekey;
1549 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1550 sconn->sock, sconn->rekey_timeout, 0);
1552 /* Set the entry as packet stream context */
1553 silc_packet_set_context(sconn->sock, id_entry);
1555 /* Call the completion callback to indicate that we've connected to
1557 if (sconn && sconn->callback)
1558 (*sconn->callback)(server, id_entry, sconn->callback_context);
1560 if (sconn == server->router_conn)
1561 server->router_conn = NULL;
1566 /* SKE completion callback */
1568 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1569 SilcSKESecurityProperties prop,
1570 SilcSKEKeyMaterial keymat,
1571 SilcSKERekeyMaterial rekey,
1574 SilcPacketStream sock = context;
1575 SilcUnknownEntry entry = silc_packet_get_context(sock);
1576 SilcServerConnection sconn = silc_ske_get_context(ske);
1577 SilcServer server = entry->server;
1578 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1579 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1580 void *auth_data = NULL;
1581 SilcUInt32 auth_data_len = 0;
1582 SilcConnAuth connauth;
1583 SilcCipher send_key, receive_key;
1584 SilcHmac hmac_send, hmac_receive;
1587 SILC_LOG_DEBUG(("Connection %p, SKE completed", sconn));
1591 if (status != SILC_SKE_STATUS_OK) {
1593 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1594 silc_ske_map_status(status), entry->hostname, entry->ip));
1596 /* XXX retry connecting */
1598 silc_server_disconnect_remote(server, sconn->sock,
1599 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1600 if (sconn->callback)
1601 (*sconn->callback)(server, NULL, sconn->callback_context);
1602 silc_server_connection_free(sconn);
1606 SILC_LOG_DEBUG(("Setting keys into use"));
1608 /* Set the keys into use. The data will be encrypted after this. */
1609 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1610 &hmac_send, &hmac_receive, &hash)) {
1612 /* XXX retry connecting */
1614 /* Error setting keys */
1616 silc_server_disconnect_remote(server, sconn->sock,
1617 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1618 if (sconn->callback)
1619 (*sconn->callback)(server, NULL, sconn->callback_context);
1620 silc_server_connection_free(sconn);
1623 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1624 hmac_receive, FALSE);
1626 SILC_LOG_DEBUG(("Starting connection authentication"));
1628 connauth = silc_connauth_alloc(server->schedule, ske,
1629 server->config->conn_auth_timeout);
1631 /* XXX retry connecting */
1633 /** Error allocating auth protocol */
1635 silc_server_disconnect_remote(server, sconn->sock,
1636 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1637 if (sconn->callback)
1638 (*sconn->callback)(server, NULL, sconn->callback_context);
1639 silc_server_connection_free(sconn);
1643 /* Get authentication method */
1645 if (conn->passphrase) {
1646 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1647 auth_meth = SILC_AUTH_PUBLIC_KEY;
1648 auth_data = server->private_key;
1650 auth_meth = SILC_AUTH_PASSWORD;
1651 auth_data = conn->passphrase;
1652 auth_data_len = conn->passphrase_len;
1655 auth_meth = SILC_AUTH_PUBLIC_KEY;
1656 auth_data = server->private_key;
1660 entry->data.rekey = rekey;
1662 /* Start connection authentication */
1664 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1665 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1666 auth_data, auth_data_len,
1667 silc_server_ke_auth_compl, sconn);
1670 /* Function that is called when the network connection to a router has
1671 been established. This will continue with the key exchange protocol
1672 with the remote router. */
1674 void silc_server_start_key_exchange(SilcServerConnection sconn)
1676 SilcServer server = sconn->server;
1677 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1678 SilcUnknownEntry entry;
1679 SilcSKEParamsStruct params;
1682 /* Cancel any possible retry timeouts */
1683 silc_schedule_task_del_by_context(server->schedule, sconn);
1685 /* Create packet stream */
1686 sconn->sock = silc_packet_stream_create(server->packet_engine,
1687 server->schedule, sconn->stream);
1689 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1690 silc_stream_destroy(sconn->stream);
1691 if (sconn->callback)
1692 (*sconn->callback)(server, NULL, sconn->callback_context);
1693 silc_server_connection_free(sconn);
1696 server->stat.conn_num++;
1698 /* Set source ID to packet stream */
1699 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1701 silc_packet_stream_destroy(sconn->sock);
1702 if (sconn->callback)
1703 (*sconn->callback)(server, NULL, sconn->callback_context);
1704 silc_server_connection_free(sconn);
1708 /* Create entry for remote entity */
1709 entry = silc_calloc(1, sizeof(*entry));
1711 silc_packet_stream_destroy(sconn->sock);
1712 silc_server_connection_free(sconn);
1715 entry->server = server;
1716 silc_packet_set_context(sconn->sock, entry);
1718 /* Set Key Exchange flags from configuration, but fall back to global
1720 memset(¶ms, 0, sizeof(params));
1721 SILC_GET_SKE_FLAGS(conn, params.flags);
1722 if (server->config->param.key_exchange_pfs)
1723 params.flags |= SILC_SKE_SP_FLAG_PFS;
1725 /* Start SILC Key Exchange protocol */
1726 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1727 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1728 server->public_key, server->private_key, sconn);
1731 silc_packet_stream_destroy(sconn->sock);
1732 if (sconn->callback)
1733 (*sconn->callback)(server, NULL, sconn->callback_context);
1734 silc_server_connection_free(sconn);
1737 silc_ske_set_callbacks(ske, silc_server_verify_key,
1738 silc_server_ke_completed, sconn->sock);
1740 /* Start key exchange protocol */
1741 params.version = silc_version_string;
1742 params.timeout_secs = server->config->key_exchange_timeout;
1743 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1746 /* Timeout callback that will be called to retry connecting to remote
1747 router. This is used by both normal and router server. This will wait
1748 before retrying the connecting. The timeout is generated by exponential
1749 backoff algorithm. */
1751 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1753 SilcServerConnection sconn = context;
1754 SilcServer server = sconn->server;
1755 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1756 SilcServerConfigConnParams *param =
1757 (conn->param ? conn->param : &server->config->param);
1759 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1760 sconn->remote_port));
1762 /* Calculate next timeout */
1763 if (sconn->retry_count >= 1) {
1764 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1765 if (sconn->retry_timeout > param->reconnect_interval_max)
1766 sconn->retry_timeout = param->reconnect_interval_max;
1768 sconn->retry_timeout = param->reconnect_interval;
1770 sconn->retry_count++;
1771 sconn->retry_timeout = sconn->retry_timeout +
1772 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1774 /* If we've reached max retry count, give up. */
1775 if ((sconn->retry_count > param->reconnect_count) &&
1776 !param->reconnect_keep_trying) {
1777 SILC_LOG_ERROR(("Could not connect, giving up"));
1779 if (sconn->callback)
1780 (*sconn->callback)(server, NULL, sconn->callback_context);
1781 silc_server_connection_free(sconn);
1785 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1787 /* We will lookup a fresh pointer later */
1788 silc_server_config_unref(&sconn->conn);
1790 /* Wait before retrying */
1791 silc_schedule_task_del_by_context(server->schedule, sconn);
1792 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1793 sconn, sconn->retry_timeout, 0);
1796 /* Callback for async connection to remote router */
1798 static void silc_server_connection_established(SilcNetStatus status,
1802 SilcServerConnection sconn = context;
1803 SilcServer server = sconn->server;
1805 silc_schedule_task_del_by_context(server->schedule, sconn);
1810 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1811 sconn->remote_host, sconn->remote_port));
1813 /* Continue with key exchange protocol */
1814 sconn->stream = stream;
1815 silc_server_start_key_exchange(sconn);
1818 case SILC_NET_UNKNOWN_IP:
1819 case SILC_NET_UNKNOWN_HOST:
1820 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1821 sconn->remote_host, sconn->remote_port,
1822 silc_net_get_error_string(status)));
1824 if (sconn->callback)
1825 (*sconn->callback)(server, NULL, sconn->callback_context);
1826 silc_server_connection_free(sconn);
1830 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1831 sconn->remote_host, sconn->remote_port,
1832 silc_net_get_error_string(status)));
1833 if (!sconn->no_reconnect) {
1834 silc_schedule_task_add_timeout(sconn->server->schedule,
1835 silc_server_connect_to_router_retry,
1837 silc_dlist_del(server->conns, sconn);
1839 if (sconn->callback)
1840 (*sconn->callback)(server, NULL, sconn->callback_context);
1841 silc_server_connection_free(sconn);
1847 /* Generic routine to use connect to a router. */
1849 SILC_TASK_CALLBACK(silc_server_connect_router)
1851 SilcServerConnection sconn = context;
1852 SilcServer server = sconn->server;
1853 SilcServerConfigRouter *rconn;
1855 silc_schedule_task_del_by_context(server->schedule, sconn);
1857 /* Don't connect if we are shutting down. */
1858 if (server->server_shutdown) {
1859 if (sconn->callback)
1860 (*sconn->callback)(server, NULL, sconn->callback_context);
1861 silc_server_connection_free(sconn);
1865 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1866 (sconn->backup ? "backup router" : "router"),
1867 sconn->remote_host, sconn->remote_port));
1869 if (!sconn->no_conf) {
1870 /* Find connection configuration */
1871 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1872 sconn->remote_port);
1874 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1875 (sconn->backup ? "backup router" : "router"),
1876 sconn->remote_host, sconn->remote_port));
1877 silc_server_connection_free(sconn);
1880 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1883 /* Connect to remote host */
1885 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1886 server->config->server_info->primary->server_ip),
1887 sconn->remote_host, sconn->remote_port,
1888 server->schedule, silc_server_connection_established,
1891 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1892 sconn->remote_host, sconn->remote_port));
1893 silc_server_connection_free(sconn);
1897 /* Add to connection list */
1898 silc_dlist_add(server->conns, sconn);
1901 /* This function connects to our primary router or if we are a router this
1902 establishes all our primary routes. This is called at the start of the
1903 server to do authentication and key exchange with our router - called
1906 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1908 SilcServer server = context;
1909 SilcServerConnection sconn;
1910 SilcServerConfigRouter *ptr;
1912 /* Don't connect if we are shutting down. */
1913 if (server->server_shutdown)
1916 SILC_LOG_DEBUG(("We are %s",
1917 (server->server_type == SILC_SERVER ?
1918 "normal server" : server->server_type == SILC_ROUTER ?
1919 "router" : "backup router/normal server")));
1921 if (!server->config->routers) {
1922 /* There wasn't a configured router, we will continue but we don't
1923 have a connection to outside world. We will be standalone server. */
1924 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1925 server->standalone = TRUE;
1929 /* Cancel any possible retry timeouts */
1930 silc_schedule_task_del_by_callback(server->schedule,
1931 silc_server_connect_router);
1932 silc_schedule_task_del_by_callback(server->schedule,
1933 silc_server_connect_to_router_retry);
1935 /* Create the connections to all our routes */
1936 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1938 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1939 ptr->backup_router ? "Backup router" : "Router",
1940 ptr->initiator ? "Initiator" : "Responder",
1941 ptr->host, ptr->port));
1943 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1944 ptr->initiator == FALSE && !server->backup_router &&
1945 !silc_server_config_get_backup_router(server))
1946 server->wait_backup = TRUE;
1948 if (!ptr->initiator)
1950 if (ptr->dynamic_connection)
1953 /* Check whether we are connecting or connected to this host already */
1954 if (silc_server_num_sockets_by_remote(server,
1955 silc_net_is_ip(ptr->host) ?
1957 silc_net_is_ip(ptr->host) ?
1958 NULL : ptr->host, ptr->port,
1959 SILC_CONN_ROUTER)) {
1960 SILC_LOG_DEBUG(("We are already connected to %s:%d",
1961 ptr->host, ptr->port));
1963 /* If we don't have primary router and this connection is our
1964 primary router we are in desync. Reconnect to the primary. */
1965 if (server->standalone && !server->router) {
1967 SilcPacketStream sock;
1968 SilcServerConfigRouter *primary =
1969 silc_server_config_get_primary_router(server);
1972 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1973 ptr->host, ptr->port);
1976 server->backup_noswitch = TRUE;
1977 silc_server_free_sock_user_data(server, sock, NULL);
1978 silc_server_disconnect_remote(server, sock, 0, NULL);
1979 server->backup_noswitch = FALSE;
1980 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1986 /* Allocate connection object for hold connection specific stuff. */
1987 sconn = silc_calloc(1, sizeof(*sconn));
1990 sconn->server = server;
1991 sconn->remote_host = strdup(ptr->host);
1992 sconn->remote_port = ptr->port;
1993 sconn->backup = ptr->backup_router;
1994 if (sconn->backup) {
1995 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1996 sconn->backup_replace_port = ptr->backup_replace_port;
1999 SILC_LOG_DEBUG(("Created connection %p", sconn));
2001 if (!server->router_conn && !sconn->backup)
2002 server->router_conn = sconn;
2005 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2011 /************************ Accepting new connection **************************/
2013 /* After this is called, server don't wait for backup router anymore.
2014 This gets called automatically even after we have backup router
2015 connection established. */
2017 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2019 SilcServer server = context;
2020 server->wait_backup = FALSE;
2023 /* Authentication data callback */
2026 silc_server_accept_get_auth(SilcConnAuth connauth,
2027 SilcConnectionType conn_type,
2028 unsigned char **passphrase,
2029 SilcUInt32 *passphrase_len,
2030 SilcSKR *repository,
2033 SilcPacketStream sock = context;
2034 SilcUnknownEntry entry = silc_packet_get_context(sock);
2035 SilcServer server = entry->server;
2037 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2039 /* Remote end is client */
2040 if (conn_type == SILC_CONN_CLIENT) {
2041 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2045 *passphrase = cconfig->passphrase;
2046 *passphrase_len = cconfig->passphrase_len;
2047 if (cconfig->publickeys)
2048 *repository = server->repository;
2050 if (cconfig->publickeys) {
2051 if (server->config->prefer_passphrase_auth) {
2055 *passphrase_len = 0;
2059 entry->conn_type = conn_type;
2063 /* Remote end is server */
2064 if (conn_type == SILC_CONN_SERVER) {
2065 SilcServerConfigServer *sconfig;
2067 /* If we are normal server, don't accept the connection */
2068 if (server->server_type == SILC_SERVER)
2071 sconfig = entry->sconfig.ref_ptr;
2075 *passphrase = sconfig->passphrase;
2076 *passphrase_len = sconfig->passphrase_len;
2077 if (sconfig->publickeys)
2078 *repository = server->repository;
2080 if (sconfig->publickeys) {
2081 if (server->config->prefer_passphrase_auth) {
2085 *passphrase_len = 0;
2089 entry->conn_type = conn_type;
2093 /* Remote end is router */
2094 if (conn_type == SILC_CONN_ROUTER) {
2095 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2099 *passphrase = rconfig->passphrase;
2100 *passphrase_len = rconfig->passphrase_len;
2101 if (rconfig->publickeys)
2102 *repository = server->repository;
2104 if (rconfig->publickeys) {
2105 if (server->config->prefer_passphrase_auth) {
2109 *passphrase_len = 0;
2113 entry->conn_type = conn_type;
2120 /* Authentication completion callback. */
2123 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2126 SilcPacketStream sock = context;
2127 SilcUnknownEntry entry = silc_packet_get_context(sock);
2128 SilcIDListData idata = (SilcIDListData)entry;
2129 SilcServer server = entry->server;
2130 SilcServerConfigConnParams *param = &server->config->param;
2131 SilcServerConnection sconn;
2133 const char *hostname, *ip;
2137 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2138 NULL, &hostname, &ip, &port);
2140 if (success == FALSE) {
2141 /* Authentication failed */
2142 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2143 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2144 server->stat.auth_failures++;
2145 silc_server_disconnect_remote(server, sock,
2146 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2150 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2152 switch (entry->conn_type) {
2153 case SILC_CONN_CLIENT:
2155 SilcClientEntry client;
2156 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2158 /* Verify whether this connection is after all allowed to connect */
2159 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2160 &server->config->param,
2162 silc_connauth_get_ske(connauth))) {
2163 server->stat.auth_failures++;
2167 /* If we are primary router and we have backup router configured
2168 but it has not connected to use yet, do not accept any other
2170 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2171 !server->backup_router) {
2172 SilcServerConfigRouter *router;
2173 router = silc_server_config_get_backup_router(server);
2174 if (router && strcmp(server->config->server_info->primary->server_ip,
2176 silc_server_find_socket_by_host(server,
2178 router->backup_replace_ip, 0)) {
2179 SILC_LOG_INFO(("Will not accept connections because we do "
2180 "not have backup router connection established"));
2181 silc_server_disconnect_remote(server, sock,
2182 SILC_STATUS_ERR_PERM_DENIED,
2183 "We do not have connection to backup "
2184 "router established, try later");
2185 server->stat.auth_failures++;
2187 /* From here on, wait 20 seconds for the backup router to appear. */
2188 silc_schedule_task_add_timeout(server->schedule,
2189 silc_server_backup_router_wait,
2190 (void *)server, 20, 0);
2195 SILC_LOG_DEBUG(("Remote host is client"));
2196 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2199 /* Add the client to the client ID cache. The nickname and Client ID
2200 and other information is created after we have received NEW_CLIENT
2201 packet from client. */
2202 client = silc_idlist_add_client(server->local_list,
2203 NULL, NULL, NULL, NULL, NULL, sock);
2205 SILC_LOG_ERROR(("Could not add new client to cache"));
2206 server->stat.auth_failures++;
2207 silc_server_disconnect_remote(server, sock,
2208 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2211 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2212 entry->data.conn_type = SILC_CONN_CLIENT;
2215 server->stat.my_clients++;
2216 server->stat.clients++;
2217 server->stat.cell_clients++;
2219 /* Get connection parameters */
2221 param = conn->param;
2223 if (!param->keepalive_secs)
2224 param->keepalive_secs = server->config->param.keepalive_secs;
2226 if (!param->qos && server->config->param.qos) {
2227 param->qos = server->config->param.qos;
2228 param->qos_rate_limit = server->config->param.qos_rate_limit;
2229 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2230 param->qos_limit_sec = server->config->param.qos_limit_sec;
2231 param->qos_limit_usec = server->config->param.qos_limit_usec;
2234 /* Check if to be anonymous connection */
2235 if (param->anonymous)
2236 client->mode |= SILC_UMODE_ANONYMOUS;
2239 /* Add public key to repository */
2240 SILC_LOG_DEBUG(("Add client public key to repository"));
2241 if (!silc_server_get_public_key_by_client(server, client, NULL))
2242 silc_skr_add_public_key_simple(server->repository,
2243 entry->data.public_key,
2244 SILC_SKR_USAGE_IDENTIFICATION, client,
2247 id_entry = (void *)client;
2251 case SILC_CONN_SERVER:
2252 case SILC_CONN_ROUTER:
2254 SilcServerEntry new_server;
2255 SilcBool initiator = FALSE;
2256 SilcBool backup_local = FALSE;
2257 SilcBool backup_router = FALSE;
2258 char *backup_replace_ip = NULL;
2259 SilcUInt16 backup_replace_port = 0;
2260 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2261 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2263 /* If we are backup router and this is incoming server connection
2264 and we do not have connection to primary router, do not allow
2266 if (server->server_type == SILC_BACKUP_ROUTER &&
2267 entry->conn_type == SILC_CONN_SERVER &&
2268 !SILC_PRIMARY_ROUTE(server)) {
2269 SILC_LOG_INFO(("Will not accept server connection because we do "
2270 "not have primary router connection established"));
2271 silc_server_disconnect_remote(server, sock,
2272 SILC_STATUS_ERR_PERM_DENIED,
2273 "We do not have connection to primary "
2274 "router established, try later");
2275 server->stat.auth_failures++;
2279 if (entry->conn_type == SILC_CONN_ROUTER) {
2280 /* Verify whether this connection is after all allowed to connect */
2281 if (!silc_server_connection_allowed(server, sock,
2283 &server->config->param,
2284 rconn ? rconn->param : NULL,
2285 silc_connauth_get_ske(connauth))) {
2286 server->stat.auth_failures++;
2292 param = rconn->param;
2294 if (!param->keepalive_secs)
2295 param->keepalive_secs = server->config->param.keepalive_secs;
2297 if (!param->qos && server->config->param.qos) {
2298 param->qos = server->config->param.qos;
2299 param->qos_rate_limit = server->config->param.qos_rate_limit;
2300 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2301 param->qos_limit_sec = server->config->param.qos_limit_sec;
2302 param->qos_limit_usec = server->config->param.qos_limit_usec;
2306 initiator = rconn->initiator;
2307 backup_local = rconn->backup_local;
2308 backup_router = rconn->backup_router;
2309 backup_replace_ip = rconn->backup_replace_ip;
2310 backup_replace_port = rconn->backup_replace_port;
2314 if (entry->conn_type == SILC_CONN_SERVER) {
2315 /* Verify whether this connection is after all allowed to connect */
2316 if (!silc_server_connection_allowed(server, sock,
2318 &server->config->param,
2319 srvconn ? srvconn->param : NULL,
2320 silc_connauth_get_ske(connauth))) {
2321 server->stat.auth_failures++;
2325 if (srvconn->param) {
2326 param = srvconn->param;
2328 if (!param->keepalive_secs)
2329 param->keepalive_secs = server->config->param.keepalive_secs;
2331 if (!param->qos && server->config->param.qos) {
2332 param->qos = server->config->param.qos;
2333 param->qos_rate_limit = server->config->param.qos_rate_limit;
2334 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2335 param->qos_limit_sec = server->config->param.qos_limit_sec;
2336 param->qos_limit_usec = server->config->param.qos_limit_usec;
2340 backup_router = srvconn->backup_router;
2344 /* If we are primary router and we have backup router configured
2345 but it has not connected to use yet, do not accept any other
2347 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2348 !server->backup_router && !backup_router) {
2349 SilcServerConfigRouter *router;
2350 router = silc_server_config_get_backup_router(server);
2351 if (router && strcmp(server->config->server_info->primary->server_ip,
2353 silc_server_find_socket_by_host(server,
2355 router->backup_replace_ip, 0)) {
2356 SILC_LOG_INFO(("Will not accept connections because we do "
2357 "not have backup router connection established"));
2358 silc_server_disconnect_remote(server, sock,
2359 SILC_STATUS_ERR_PERM_DENIED,
2360 "We do not have connection to backup "
2361 "router established, try later");
2362 server->stat.auth_failures++;
2364 /* From here on, wait 20 seconds for the backup router to appear. */
2365 silc_schedule_task_add_timeout(server->schedule,
2366 silc_server_backup_router_wait,
2367 (void *)server, 20, 0);
2372 SILC_LOG_DEBUG(("Remote host is %s",
2373 entry->conn_type == SILC_CONN_SERVER ?
2374 "server" : (backup_router ?
2375 "backup router" : "router")));
2376 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2377 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2378 "server" : (backup_router ?
2379 "backup router" : "router")));
2381 /* Add the server into server cache. The server name and Server ID
2382 is updated after we have received NEW_SERVER packet from the
2383 server. We mark ourselves as router for this server if we really
2386 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2387 server->local_list : (backup_router ?
2388 server->local_list :
2389 server->global_list)),
2391 (entry->conn_type == SILC_CONN_SERVER ?
2392 SILC_SERVER : SILC_ROUTER),
2394 (entry->conn_type == SILC_CONN_SERVER ?
2395 server->id_entry : (backup_router ?
2396 server->id_entry : NULL)),
2399 SILC_LOG_ERROR(("Could not add new server to cache"));
2400 silc_server_disconnect_remote(server, sock,
2401 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2402 server->stat.auth_failures++;
2405 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2406 entry->data.conn_type = entry->conn_type;
2408 id_entry = (void *)new_server;
2410 /* If the incoming connection is router and marked as backup router
2411 then add it to be one of our backups */
2412 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2413 /* Change it back to SERVER type since that's what it really is. */
2415 entry->data.conn_type = SILC_CONN_SERVER;
2416 new_server->server_type = SILC_BACKUP_ROUTER;
2418 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2419 ("Backup router %s is now online",
2422 /* Remove the backup waiting with timeout */
2423 silc_schedule_task_add_timeout(server->schedule,
2424 silc_server_backup_router_wait,
2425 (void *)server, 10, 0);
2429 if (entry->data.conn_type == SILC_CONN_SERVER) {
2430 server->stat.my_servers++;
2431 server->stat.servers++;
2432 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2434 server->stat.my_routers++;
2435 server->stat.routers++;
2436 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2439 /* Check whether this connection is to be our primary router connection
2440 if we do not already have the primary route. */
2441 if (!backup_router &&
2442 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2443 if (silc_server_config_is_primary_route(server) && !initiator)
2446 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2447 server->standalone = FALSE;
2448 if (!server->id_entry->router) {
2449 server->id_entry->router = id_entry;
2450 server->router = id_entry;
2462 /* Add connection to server->conns so that we know we have connection
2464 sconn = silc_calloc(1, sizeof(*sconn));
2465 sconn->server = server;
2467 sconn->remote_host = strdup(hostname);
2468 sconn->remote_port = port;
2469 silc_dlist_add(server->conns, sconn);
2470 idata->sconn = sconn;
2471 idata->last_receive = time(NULL);
2473 /* Add the common data structure to the ID entry. */
2474 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2475 silc_packet_set_context(sock, id_entry);
2477 /* Connection has been fully established now. Everything is ok. */
2478 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2480 /* Perform Quality of Service */
2482 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2483 param->qos_rate_limit, param->qos_bytes_limit,
2484 param->qos_limit_sec, param->qos_limit_usec);
2486 silc_server_config_unref(&entry->cconfig);
2487 silc_server_config_unref(&entry->sconfig);
2488 silc_server_config_unref(&entry->rconfig);
2492 silc_ske_free(silc_connauth_get_ske(connauth));
2493 silc_connauth_free(connauth);
2496 /* SKE completion callback. We set the new keys into use here. */
2499 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2500 SilcSKESecurityProperties prop,
2501 SilcSKEKeyMaterial keymat,
2502 SilcSKERekeyMaterial rekey,
2505 SilcPacketStream sock = context;
2506 SilcUnknownEntry entry = silc_packet_get_context(sock);
2507 SilcIDListData idata = (SilcIDListData)entry;
2508 SilcServer server = entry->server;
2509 SilcConnAuth connauth;
2510 SilcCipher send_key, receive_key;
2511 SilcHmac hmac_send, hmac_receive;
2518 if (status != SILC_SKE_STATUS_OK) {
2520 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2521 silc_ske_map_status(status), entry->hostname, entry->ip));
2523 silc_server_disconnect_remote(server, sock,
2524 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2528 SILC_LOG_DEBUG(("Setting keys into use"));
2530 /* Set the keys into use. The data will be encrypted after this. */
2531 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2532 &hmac_send, &hmac_receive, &hash)) {
2533 /* Error setting keys */
2535 silc_server_disconnect_remote(server, sock,
2536 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2539 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2540 hmac_receive, FALSE);
2542 idata->rekey = rekey;
2543 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2544 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2545 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2547 silc_hash_alloc(silc_hash_get_name(prop->hash), &idata->hash);
2549 SILC_LOG_DEBUG(("Starting connection authentication"));
2550 server->stat.auth_attempts++;
2552 connauth = silc_connauth_alloc(server->schedule, ske,
2553 server->config->conn_auth_timeout);
2555 /** Error allocating auth protocol */
2557 silc_server_disconnect_remote(server, sock,
2558 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2562 /* Start connection authentication */
2564 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2565 silc_server_accept_auth_compl, sock);
2568 /* Accept new TCP connection */
2570 static void silc_server_accept_new_connection(SilcNetStatus status,
2574 SilcServer server = context;
2575 SilcPacketStream packet_stream;
2576 SilcServerConfigClient *cconfig = NULL;
2577 SilcServerConfigServer *sconfig = NULL;
2578 SilcServerConfigRouter *rconfig = NULL;
2579 SilcServerConfigDeny *deny;
2580 SilcUnknownEntry entry;
2582 SilcSKEParamsStruct params;
2583 char *hostname, *ip;
2586 SILC_LOG_DEBUG(("Accepting new connection"));
2588 /* Check for maximum allowed connections */
2589 server->stat.conn_attempts++;
2590 if (silc_dlist_count(server->conns) >
2591 server->config->param.connections_max) {
2592 SILC_LOG_ERROR(("Refusing connection, server is full"));
2593 server->stat.conn_failures++;
2594 silc_stream_destroy(stream);
2598 /* Get hostname, IP and port */
2599 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2600 (const char **)&ip, &port)) {
2601 /* Bad socket stream */
2602 server->stat.conn_failures++;
2603 silc_stream_destroy(stream);
2607 /* Create packet stream */
2608 packet_stream = silc_packet_stream_create(server->packet_engine,
2609 server->schedule, stream);
2610 if (!packet_stream) {
2611 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2612 server->stat.conn_failures++;
2613 silc_stream_destroy(stream);
2616 server->stat.conn_num++;
2618 /* Set source ID to packet stream */
2619 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2622 server->stat.conn_failures++;
2623 silc_packet_stream_destroy(packet_stream);
2627 /* Check whether this connection is denied to connect to us. */
2628 deny = silc_server_config_find_denied(server, ip);
2630 deny = silc_server_config_find_denied(server, hostname);
2632 /* The connection is denied */
2633 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2634 silc_server_disconnect_remote(server, packet_stream,
2635 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2640 /* Check whether we have configured this sort of connection at all. We
2641 have to check all configurations since we don't know what type of
2642 connection this is. */
2643 if (!(cconfig = silc_server_config_find_client(server, ip)))
2644 cconfig = silc_server_config_find_client(server, hostname);
2645 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2646 sconfig = silc_server_config_find_server_conn(server, hostname);
2647 if (server->server_type == SILC_ROUTER)
2648 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2649 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2650 if (!cconfig && !sconfig && !rconfig) {
2651 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2652 server->stat.conn_failures++;
2653 silc_server_disconnect_remote(server, packet_stream,
2654 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2658 /* The connection is allowed */
2659 entry = silc_calloc(1, sizeof(*entry));
2661 server->stat.conn_failures++;
2662 silc_server_disconnect_remote(server, packet_stream,
2663 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2666 entry->hostname = hostname;
2669 entry->server = server;
2670 entry->data.conn_type = SILC_CONN_UNKNOWN;
2671 silc_packet_set_context(packet_stream, entry);
2673 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2674 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2675 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2677 /* Take flags for key exchange. Since we do not know what type of connection
2678 this is, we go through all found configurations and use the global ones
2679 as well. This will result always into strictest key exchange flags. */
2680 memset(¶ms, 0, sizeof(params));
2681 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2682 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2683 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2684 if (server->config->param.key_exchange_pfs)
2685 params.flags |= SILC_SKE_SP_FLAG_PFS;
2687 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2688 server->stat.conn_attempts++;
2690 /* Start SILC Key Exchange protocol */
2691 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2692 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2693 server->public_key, server->private_key,
2696 server->stat.conn_failures++;
2697 silc_server_disconnect_remote(server, packet_stream,
2698 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2701 silc_ske_set_callbacks(ske, silc_server_verify_key,
2702 silc_server_accept_completed, packet_stream);
2704 /* Start key exchange protocol */
2705 params.version = silc_version_string;
2706 params.timeout_secs = server->config->key_exchange_timeout;
2707 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2711 /********************************** Rekey ***********************************/
2713 /* Initiator rekey completion callback */
2715 static void silc_server_rekey_completion(SilcSKE ske,
2716 SilcSKEStatus status,
2717 const SilcSKESecurityProperties prop,
2718 const SilcSKEKeyMaterial keymat,
2719 SilcSKERekeyMaterial rekey,
2722 SilcPacketStream sock = context;
2723 SilcIDListData idata = silc_packet_get_context(sock);
2724 SilcServer server = idata->sconn->server;
2726 idata->sconn->op = NULL;
2727 if (status != SILC_SKE_STATUS_OK) {
2728 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2729 idata->sconn->remote_host));
2733 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2734 idata->sconn->remote_host, idata->sconn->remote_port,
2735 SILC_CONNTYPE_STRING(idata->conn_type)));
2737 /* Save rekey data for next rekey */
2738 idata->rekey = rekey;
2740 /* Register new rekey timeout */
2741 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2742 sock, idata->sconn->rekey_timeout, 0);
2745 /* Rekey callback. Start rekey as initiator */
2747 SILC_TASK_CALLBACK(silc_server_do_rekey)
2749 SilcServer server = app_context;
2750 SilcPacketStream sock = context;
2751 SilcIDListData idata = silc_packet_get_context(sock);
2754 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2756 /* Do not execute rekey with disabled connections */
2757 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2760 /* If another protocol is active do not start rekey */
2761 if (idata->sconn->op) {
2762 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2763 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2768 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2769 idata->sconn->remote_host, idata->sconn->remote_port,
2770 SILC_CONNTYPE_STRING(idata->conn_type)));
2773 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2774 server->public_key, NULL, sock);
2778 /* Set SKE callbacks */
2779 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2782 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2785 /* Responder rekey completion callback */
2788 silc_server_rekey_resp_completion(SilcSKE ske,
2789 SilcSKEStatus status,
2790 const SilcSKESecurityProperties prop,
2791 const SilcSKEKeyMaterial keymat,
2792 SilcSKERekeyMaterial rekey,
2795 SilcPacketStream sock = context;
2796 SilcIDListData idata = silc_packet_get_context(sock);
2798 idata->sconn->op = NULL;
2799 if (status != SILC_SKE_STATUS_OK) {
2800 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2801 idata->sconn->remote_host));
2805 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2806 idata->sconn->remote_host, idata->sconn->remote_port,
2807 SILC_CONNTYPE_STRING(idata->conn_type)));
2809 /* Save rekey data for next rekey */
2810 idata->rekey = rekey;
2813 /* Start rekey as responder */
2815 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2818 SilcIDListData idata = silc_packet_get_context(sock);
2821 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2822 idata->sconn->remote_host, idata->sconn->remote_port,
2823 SILC_CONNTYPE_STRING(idata->conn_type)));
2826 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2827 server->public_key, NULL, sock);
2829 silc_packet_free(packet);
2833 /* Set SKE callbacks */
2834 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2837 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2842 /****************************** Disconnection *******************************/
2844 /* Destroys packet stream. */
2846 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2848 silc_packet_stream_destroy(context);
2851 /* Closes connection to socket connection */
2853 void silc_server_close_connection(SilcServer server,
2854 SilcPacketStream sock)
2856 SilcIDListData idata = silc_packet_get_context(sock);
2858 const char *hostname;
2861 memset(tmp, 0, sizeof(tmp));
2862 // silc_socket_get_error(sock, tmp, sizeof(tmp));
2863 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2864 NULL, &hostname, NULL, &port);
2865 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2866 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
2867 tmp[0] ? tmp : ""));
2869 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2871 if (idata && idata->sconn) {
2872 silc_server_connection_free(idata->sconn);
2873 idata->sconn = NULL;
2876 /* Close connection with timeout */
2877 server->stat.conn_num--;
2878 silc_schedule_task_del_by_all(server->schedule, 0,
2879 silc_server_close_connection_final, sock);
2880 silc_schedule_task_add_timeout(server->schedule,
2881 silc_server_close_connection_final,
2885 /* Sends disconnect message to remote connection and disconnects the
2888 void silc_server_disconnect_remote(SilcServer server,
2889 SilcPacketStream sock,
2890 SilcStatus status, ...)
2892 unsigned char buf[512];
2899 SILC_LOG_DEBUG(("Disconnecting remote host"));
2901 va_start(ap, status);
2902 cp = va_arg(ap, char *);
2904 silc_vsnprintf(buf, sizeof(buf), cp, ap);
2907 /* Send SILC_PACKET_DISCONNECT */
2908 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2909 SILC_STR_UI_CHAR(status),
2910 SILC_STR_UI8_STRING(cp ? buf : NULL),
2913 /* Close connection */
2914 silc_server_close_connection(server, sock);
2917 /* Frees client data and notifies about client's signoff. */
2919 void silc_server_free_client_data(SilcServer server,
2920 SilcPacketStream sock,
2921 SilcClientEntry client,
2923 const char *signoff)
2925 SILC_LOG_DEBUG(("Freeing client %p data", client));
2928 /* Check if anyone is watching this nickname */
2929 if (server->server_type == SILC_ROUTER)
2930 silc_server_check_watcher_list(server, client, NULL,
2931 SILC_NOTIFY_TYPE_SIGNOFF);
2933 /* Send SIGNOFF notify to routers. */
2935 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2936 SILC_BROADCAST(server), client->id,
2940 /* Remove client from all channels */
2942 silc_server_remove_from_channels(server, NULL, client,
2943 TRUE, (char *)signoff, TRUE, FALSE);
2945 silc_server_remove_from_channels(server, NULL, client,
2946 FALSE, NULL, FALSE, FALSE);
2948 /* Remove this client from watcher list if it is */
2949 silc_server_del_from_watcher_list(server, client);
2951 /* Remove client's public key from repository, this will free it too. */
2952 if (client->data.public_key) {
2953 silc_skr_del_public_key(server->repository, client->data.public_key,
2955 client->data.public_key = NULL;
2958 /* Update statistics */
2959 server->stat.my_clients--;
2960 server->stat.clients--;
2961 if (server->stat.cell_clients)
2962 server->stat.cell_clients--;
2963 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2964 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2965 silc_schedule_task_del_by_context(server->schedule, client);
2967 if (client->data.sconn)
2968 silc_server_connection_free(client->data.sconn);
2970 /* We will not delete the client entry right away. We will take it
2971 into history (for WHOWAS command) for 5 minutes, unless we're
2972 shutting down server. */
2973 if (!server->server_shutdown) {
2974 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2976 client->router = NULL;
2977 client->connection = NULL;
2978 client->data.created = silc_time();
2979 silc_dlist_add(server->expired_clients, client);
2981 /* Delete directly since we're shutting down server */
2982 SILC_LOG_DEBUG(("Delete client directly"));
2983 silc_idlist_del_data(client);
2984 silc_idlist_del_client(server->local_list, client);
2988 /* Frees user_data pointer from socket connection object. This also sends
2989 appropriate notify packets to the network to inform about leaving
2992 void silc_server_free_sock_user_data(SilcServer server,
2993 SilcPacketStream sock,
2994 const char *signoff_message)
2996 SilcIDListData idata = silc_packet_get_context(sock);
3000 SILC_LOG_DEBUG(("Start"));
3005 silc_schedule_task_del_by_context(server->schedule, sock);
3007 /* Cancel active protocols */
3009 if (idata->sconn && idata->sconn->op) {
3010 SILC_LOG_DEBUG(("Abort active protocol"));
3011 silc_async_abort(idata->sconn->op, NULL, NULL);
3013 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3014 ((SilcUnknownEntry)idata)->op) {
3015 SILC_LOG_DEBUG(("Abort active protocol"));
3016 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3020 switch (idata->conn_type) {
3021 case SILC_CONN_CLIENT:
3023 SilcClientEntry client_entry = (SilcClientEntry)idata;
3024 silc_server_free_client_data(server, sock, client_entry, TRUE,
3026 silc_packet_set_context(sock, NULL);
3030 case SILC_CONN_SERVER:
3031 case SILC_CONN_ROUTER:
3033 SilcServerEntry user_data = (SilcServerEntry)idata;
3034 SilcServerEntry backup_router = NULL;
3036 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3039 backup_router = silc_server_backup_get(server, user_data->id);
3041 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3042 backup_router == server->id_entry &&
3043 idata->conn_type != SILC_CONN_ROUTER)
3044 backup_router = NULL;
3046 if (server->server_shutdown || server->backup_noswitch)
3047 backup_router = NULL;
3049 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3050 NULL, NULL, &ip, &port);
3052 /* If this was our primary router connection then we're lost to
3053 the outside world. */
3054 if (server->router == user_data) {
3055 /* Check whether we have a backup router connection */
3056 if (!backup_router || backup_router == user_data) {
3057 if (!server->no_reconnect)
3058 silc_server_create_connections(server);
3059 server->id_entry->router = NULL;
3060 server->router = NULL;
3061 server->standalone = TRUE;
3062 server->backup_primary = FALSE;
3063 backup_router = NULL;
3065 if (server->id_entry != backup_router) {
3066 SILC_LOG_INFO(("New primary router is backup router %s",
3067 backup_router->server_name));
3068 server->id_entry->router = backup_router;
3069 server->router = backup_router;
3070 server->router_connect = time(0);
3071 server->backup_primary = TRUE;
3072 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3074 /* Send START_USE to backup router to indicate we have switched */
3075 silc_server_backup_send_start_use(server,
3076 backup_router->connection,
3079 SILC_LOG_INFO(("We are now new primary router in this cell"));
3080 server->id_entry->router = NULL;
3081 server->router = NULL;
3082 server->standalone = TRUE;
3085 /* We stop here to take a breath */
3088 if (server->backup_router) {
3089 server->server_type = SILC_ROUTER;
3091 /* We'll need to constantly try to reconnect to the primary
3092 router so that we'll see when it comes back online. */
3093 silc_server_create_connection(server, FALSE, FALSE, ip, port,
3094 silc_server_backup_connected,
3098 /* Mark this connection as replaced */
3099 silc_server_backup_replaced_add(server, user_data->id,
3102 } else if (backup_router) {
3103 SILC_LOG_INFO(("Enabling the use of backup router %s",
3104 backup_router->server_name));
3106 /* Mark this connection as replaced */
3107 silc_server_backup_replaced_add(server, user_data->id,
3109 } else if (server->server_type == SILC_SERVER &&
3110 idata->conn_type == SILC_CONN_ROUTER) {
3111 /* Reconnect to the router (backup) */
3112 if (!server->no_reconnect)
3113 silc_server_create_connections(server);
3116 if (user_data->server_name)
3117 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3118 ("Server %s signoff", user_data->server_name));
3120 if (!backup_router) {
3121 /* Remove all servers that are originated from this server, and
3122 remove the clients of those servers too. */
3123 silc_server_remove_servers_by_server(server, user_data, TRUE);
3126 /* Remove the clients that this server owns as they will become
3127 invalid now too. For backup router the server is actually
3128 coming from the primary router, so mark that as the owner
3130 if (server->server_type == SILC_BACKUP_ROUTER &&
3131 sock->type == SILC_CONN_SERVER)
3132 silc_server_remove_clients_by_server(server, server->router,
3136 silc_server_remove_clients_by_server(server, user_data,
3139 /* Remove channels owned by this server */
3140 if (server->server_type == SILC_SERVER)
3141 silc_server_remove_channels_by_server(server, user_data);
3143 /* Enable local server connections that may be disabled */
3144 silc_server_local_servers_toggle_enabled(server, TRUE);
3146 /* Update the client entries of this server to the new backup
3147 router. If we are the backup router we also resolve the real
3148 servers for the clients. After updating is over this also
3149 removes the clients that this server explicitly owns. */
3150 silc_server_update_clients_by_server(server, user_data,
3151 backup_router, TRUE);
3153 /* If we are router and just lost our primary router (now standlaone)
3154 we remove everything that was behind it, since we don't know
3156 if (server->server_type == SILC_ROUTER && server->standalone)
3157 /* Remove all servers that are originated from this server, and
3158 remove the clients of those servers too. */
3159 silc_server_remove_servers_by_server(server, user_data, TRUE);
3161 /* Finally remove the clients that are explicitly owned by this
3162 server. They go down with the server. */
3163 silc_server_remove_clients_by_server(server, user_data,
3166 /* Update our server cache to use the new backup router too. */
3167 silc_server_update_servers_by_server(server, user_data, backup_router);
3168 if (server->server_type == SILC_SERVER)
3169 silc_server_update_channels_by_server(server, user_data,
3172 /* Send notify about primary router going down to local operators */
3173 if (server->backup_router)
3174 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3175 SILC_NOTIFY_TYPE_NONE,
3176 ("%s switched to backup router %s "
3177 "(we are primary router now)",
3178 server->server_name, server->server_name));
3179 else if (server->router)
3180 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3181 SILC_NOTIFY_TYPE_NONE,
3182 ("%s switched to backup router %s",
3183 server->server_name,
3184 server->router->server_name));
3186 server->backup_noswitch = FALSE;
3189 silc_server_connection_free(idata->sconn);
3192 if (idata->conn_type == SILC_CONN_SERVER) {
3193 server->stat.my_servers--;
3194 server->stat.servers--;
3195 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3196 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3197 server->stat.my_routers--;
3198 server->stat.routers--;
3199 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3201 if (server->server_type == SILC_ROUTER)
3202 server->stat.cell_servers--;
3204 /* Free the server entry */
3205 silc_server_backup_del(server, user_data);
3206 silc_server_backup_replaced_del(server, user_data);
3207 silc_idlist_del_data(user_data);
3208 if (!silc_idlist_del_server(server->local_list, user_data))
3209 silc_idlist_del_server(server->global_list, user_data);
3211 if (backup_router && backup_router != server->id_entry) {
3212 /* Announce all of our stuff that was created about 5 minutes ago.
3213 The backup router knows all the other stuff already. */
3214 if (server->server_type == SILC_ROUTER)
3215 silc_server_announce_servers(server, FALSE, time(0) - 300,
3216 backup_router->connection);
3218 /* Announce our clients and channels to the router */
3219 silc_server_announce_clients(server, time(0) - 300,
3220 backup_router->connection);
3221 silc_server_announce_channels(server, time(0) - 300,
3222 backup_router->connection);
3225 silc_packet_set_context(sock, NULL);
3231 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3233 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3236 silc_server_connection_free(idata->sconn);
3237 silc_idlist_del_data(idata);
3239 silc_packet_set_context(sock, NULL);
3245 /* Removes client from all channels it has joined. This is used when client
3246 connection is disconnected. If the client on a channel is last, the
3247 channel is removed as well. This sends the SIGNOFF notify types. */
3249 void silc_server_remove_from_channels(SilcServer server,
3250 SilcPacketStream sock,
3251 SilcClientEntry client,
3253 const char *signoff_message,
3257 SilcChannelEntry channel;
3258 SilcChannelClientEntry chl;
3259 SilcHashTableList htl;
3260 SilcBuffer clidp = NULL;
3265 if (notify && !client->id)
3268 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3269 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3272 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3277 /* Remove the client from all channels. The client is removed from
3278 the channels' user list. */
3279 silc_hash_table_list(client->channels, &htl);
3280 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3281 channel = chl->channel;
3283 /* Remove channel if this is last client leaving the channel, unless
3284 the channel is permanent. */
3285 if (server->server_type != SILC_SERVER &&
3286 silc_hash_table_count(channel->user_list) < 2) {
3287 silc_server_channel_delete(server, channel);
3291 silc_hash_table_del(client->channels, channel);
3292 silc_hash_table_del(channel->user_list, client);
3293 channel->user_count--;
3295 /* If there is no global users on the channel anymore mark the channel
3296 as local channel. Do not check if the removed client is local client. */
3297 if (server->server_type == SILC_SERVER && channel->global_users &&
3298 chl->client->router && !silc_server_channel_has_global(channel))
3299 channel->global_users = FALSE;
3301 memset(chl, 'A', sizeof(*chl));
3304 /* Update statistics */
3305 if (SILC_IS_LOCAL(client))
3306 server->stat.my_chanclients--;
3307 if (server->server_type == SILC_ROUTER) {
3308 server->stat.cell_chanclients--;
3309 server->stat.chanclients--;
3312 /* If there is not at least one local user on the channel then we don't
3313 need the channel entry anymore, we can remove it safely, unless the
3314 channel is permanent channel */
3315 if (server->server_type == SILC_SERVER &&
3316 !silc_server_channel_has_local(channel)) {
3317 /* Notify about leaving client if this channel has global users. */
3318 if (notify && channel->global_users)
3319 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3320 SILC_NOTIFY_TYPE_SIGNOFF,
3321 signoff_message ? 2 : 1,
3322 clidp->data, silc_buffer_len(clidp),
3323 signoff_message, signoff_message ?
3324 strlen(signoff_message) : 0);
3326 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3327 silc_server_channel_delete(server, channel);
3331 /* Send notify to channel about client leaving SILC and channel too */
3333 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3334 SILC_NOTIFY_TYPE_SIGNOFF,
3335 signoff_message ? 2 : 1,
3336 clidp->data, silc_buffer_len(clidp),
3337 signoff_message, signoff_message ?
3338 strlen(signoff_message) : 0);
3340 if (killed && clidp) {
3341 /* Remove the client from channel's invite list */
3342 if (channel->invite_list &&
3343 silc_hash_table_count(channel->invite_list)) {
3345 SilcArgumentPayload iargs;
3346 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3347 silc_buffer_len(clidp), 3);
3348 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3349 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3350 silc_buffer_free(ab);
3351 silc_argument_payload_free(iargs);
3355 /* Don't create keys if we are shutting down */
3356 if (server->server_shutdown)
3359 /* Re-generate channel key if needed */
3360 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3361 if (!silc_server_create_channel_key(server, channel, 0))
3364 /* Send the channel key to the channel. The key of course is not sent
3365 to the client who was removed from the channel. */
3366 silc_server_send_channel_key(server, client->connection, channel,
3367 server->server_type == SILC_ROUTER ?
3368 FALSE : !server->standalone);
3372 silc_hash_table_list_reset(&htl);
3374 silc_buffer_free(clidp);
3377 /* Removes client from one channel. This is used for example when client
3378 calls LEAVE command to remove itself from the channel. Returns TRUE
3379 if channel still exists and FALSE if the channel is removed when
3380 last client leaves the channel. If `notify' is FALSE notify messages
3383 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3384 SilcPacketStream sock,
3385 SilcChannelEntry channel,
3386 SilcClientEntry client,
3389 SilcChannelClientEntry chl;
3392 SILC_LOG_DEBUG(("Removing %s from channel %s",
3393 silc_id_render(client->id, SILC_ID_CLIENT),
3394 channel->channel_name));
3396 /* Get the entry to the channel, if this client is not on the channel
3398 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3401 /* Remove channel if this is last client leaving the channel, unless
3402 the channel is permanent. */
3403 if (server->server_type != SILC_SERVER &&
3404 silc_hash_table_count(channel->user_list) < 2) {
3405 silc_server_channel_delete(server, channel);
3409 silc_hash_table_del(client->channels, channel);
3410 silc_hash_table_del(channel->user_list, client);
3411 channel->user_count--;
3413 /* If there is no global users on the channel anymore mark the channel
3414 as local channel. Do not check if the client is local client. */
3415 if (server->server_type == SILC_SERVER && channel->global_users &&
3416 chl->client->router && !silc_server_channel_has_global(channel))
3417 channel->global_users = FALSE;
3419 memset(chl, 'O', sizeof(*chl));
3422 /* Update statistics */
3423 if (SILC_IS_LOCAL(client))
3424 server->stat.my_chanclients--;
3425 if (server->server_type == SILC_ROUTER) {
3426 server->stat.cell_chanclients--;
3427 server->stat.chanclients--;
3430 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3434 /* If there is not at least one local user on the channel then we don't
3435 need the channel entry anymore, we can remove it safely, unless the
3436 channel is permanent channel */
3437 if (server->server_type == SILC_SERVER &&
3438 !silc_server_channel_has_local(channel)) {
3439 /* Notify about leaving client if this channel has global users. */
3440 if (notify && channel->global_users)
3441 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3442 SILC_NOTIFY_TYPE_LEAVE, 1,
3443 clidp->data, silc_buffer_len(clidp));
3445 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3446 silc_server_channel_delete(server, channel);
3447 silc_buffer_free(clidp);
3451 /* Send notify to channel about client leaving the channel */
3453 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3454 SILC_NOTIFY_TYPE_LEAVE, 1,
3455 clidp->data, silc_buffer_len(clidp));
3457 silc_buffer_free(clidp);
3461 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3462 function may be used only by router. In real SILC network all channels
3463 are created by routers thus this function is never used by normal
3466 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3467 SilcServerID *router_id,
3473 SilcChannelID *channel_id;
3474 SilcChannelEntry entry;
3475 SilcCipher send_key, receive_key;
3478 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3481 cipher = SILC_DEFAULT_CIPHER;
3483 hmac = SILC_DEFAULT_HMAC;
3485 /* Allocate cipher */
3486 if (!silc_cipher_alloc(cipher, &send_key))
3488 if (!silc_cipher_alloc(cipher, &receive_key)) {
3489 silc_cipher_free(send_key);
3494 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3495 silc_cipher_free(send_key);
3496 silc_cipher_free(receive_key);
3500 channel_name = strdup(channel_name);
3502 /* Create the channel ID */
3503 if (!silc_id_create_channel_id(server, router_id, server->rng,
3505 silc_free(channel_name);
3506 silc_cipher_free(send_key);
3507 silc_cipher_free(receive_key);
3508 silc_hmac_free(newhmac);
3512 /* Create the channel */
3513 entry = silc_idlist_add_channel(server->local_list, channel_name,
3514 SILC_CHANNEL_MODE_NONE, channel_id,
3515 NULL, send_key, receive_key, newhmac);
3517 silc_free(channel_name);
3518 silc_cipher_free(send_key);
3519 silc_cipher_free(receive_key);
3520 silc_hmac_free(newhmac);
3521 silc_free(channel_id);
3525 entry->cipher = strdup(cipher);
3526 entry->hmac_name = strdup(hmac);
3528 /* Now create the actual key material */
3529 if (!silc_server_create_channel_key(server, entry,
3530 silc_cipher_get_key_len(send_key) / 8)) {
3531 silc_idlist_del_channel(server->local_list, entry);
3535 /* Notify other routers about the new channel. We send the packet
3536 to our primary route. */
3538 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3539 channel_name, entry->id,
3540 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3543 /* Distribute to backup routers */
3544 if (broadcast && server->server_type == SILC_ROUTER) {
3546 unsigned char cid[32];
3547 SilcUInt32 name_len = strlen(channel_name);
3550 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3551 packet = silc_channel_payload_encode(channel_name, name_len,
3552 cid, id_len, entry->mode);
3553 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3554 packet->data, silc_buffer_len(packet), FALSE,
3556 silc_buffer_free(packet);
3559 server->stat.my_channels++;
3560 if (server->server_type == SILC_ROUTER) {
3561 server->stat.channels++;
3562 server->stat.cell_channels++;
3563 entry->users_resolved = TRUE;
3569 /* Same as above but creates the channel with Channel ID `channel_id. */
3572 silc_server_create_new_channel_with_id(SilcServer server,
3576 SilcChannelID *channel_id,
3579 SilcChannelEntry entry;
3580 SilcCipher send_key, receive_key;
3583 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3586 cipher = SILC_DEFAULT_CIPHER;
3588 hmac = SILC_DEFAULT_HMAC;
3590 /* Allocate cipher */
3591 if (!silc_cipher_alloc(cipher, &send_key))
3593 if (!silc_cipher_alloc(cipher, &receive_key)) {
3594 silc_cipher_free(send_key);
3599 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3600 silc_cipher_free(send_key);
3601 silc_cipher_free(receive_key);
3605 channel_name = strdup(channel_name);
3607 /* Create the channel */
3608 entry = silc_idlist_add_channel(server->local_list, channel_name,
3609 SILC_CHANNEL_MODE_NONE, channel_id,
3610 NULL, send_key, receive_key, newhmac);
3612 silc_cipher_free(send_key);
3613 silc_cipher_free(receive_key);
3614 silc_hmac_free(newhmac);
3615 silc_free(channel_name);
3619 /* Now create the actual key material */
3620 if (!silc_server_create_channel_key(server, entry,
3621 silc_cipher_get_key_len(send_key) / 8)) {
3622 silc_idlist_del_channel(server->local_list, entry);
3626 /* Notify other routers about the new channel. We send the packet
3627 to our primary route. */
3629 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3630 channel_name, entry->id,
3631 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3634 /* Distribute to backup routers */
3635 if (broadcast && server->server_type == SILC_ROUTER) {
3637 unsigned char cid[32];
3638 SilcUInt32 name_len = strlen(channel_name);
3641 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3642 packet = silc_channel_payload_encode(channel_name, name_len,
3643 cid, id_len, entry->mode);
3644 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3645 packet->data, silc_buffer_len(packet), FALSE,
3647 silc_buffer_free(packet);
3650 server->stat.my_channels++;
3651 if (server->server_type == SILC_ROUTER) {
3652 server->stat.channels++;
3653 server->stat.cell_channels++;
3654 entry->users_resolved = TRUE;
3660 /* Channel's key re-key timeout callback. */
3662 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3664 SilcServer server = app_context;
3665 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3669 /* Return now if we are shutting down */
3670 if (server->server_shutdown)
3673 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3676 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3679 /* Generates new channel key. This is used to create the initial channel key
3680 but also to re-generate new key for channel. If `key_len' is provided
3681 it is the bytes of the key length. */
3683 SilcBool silc_server_create_channel_key(SilcServer server,
3684 SilcChannelEntry channel,
3688 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3691 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3692 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3696 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3698 if (!channel->send_key)
3699 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3700 channel->send_key = NULL;
3703 if (!channel->receive_key)
3704 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3705 silc_cipher_free(channel->send_key);
3706 channel->send_key = channel->receive_key = NULL;
3712 else if (channel->key_len)
3713 len = channel->key_len / 8;
3715 len = silc_cipher_get_key_len(channel->send_key) / 8;
3717 /* Create channel key */
3718 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3721 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3722 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3724 /* Remove old key if exists */
3726 memset(channel->key, 0, channel->key_len / 8);
3727 silc_free(channel->key);
3731 channel->key_len = len * 8;
3732 channel->key = silc_memdup(channel_key, len);
3733 memset(channel_key, 0, sizeof(channel_key));
3735 /* Generate HMAC key from the channel key data and set it */
3737 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3738 memset(channel->key, 0, channel->key_len / 8);
3739 silc_free(channel->key);
3740 silc_cipher_free(channel->send_key);
3741 silc_cipher_free(channel->receive_key);
3742 channel->send_key = channel->receive_key = NULL;
3745 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3746 silc_hmac_set_key(channel->hmac, hash,
3747 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3748 memset(hash, 0, sizeof(hash));
3750 if (server->server_type == SILC_ROUTER) {
3751 if (!channel->rekey)
3752 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3753 channel->rekey->channel = channel;
3754 channel->rekey->key_len = key_len;
3755 if (channel->rekey->task)
3756 silc_schedule_task_del(server->schedule, channel->rekey->task);
3758 channel->rekey->task =
3759 silc_schedule_task_add_timeout(server->schedule,
3760 silc_server_channel_key_rekey,
3761 (void *)channel->rekey,
3762 server->config->channel_rekey_secs, 0);
3768 /* Saves the channel key found in the encoded `key_payload' buffer. This
3769 function is used when we receive Channel Key Payload and also when we're
3770 processing JOIN command reply. Returns entry to the channel. */
3772 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3773 SilcBuffer key_payload,
3774 SilcChannelEntry channel)
3776 SilcChannelKeyPayload payload = NULL;
3778 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3782 /* Decode channel key payload */
3783 payload = silc_channel_key_payload_parse(key_payload->data,
3784 silc_buffer_len(key_payload));
3786 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3791 /* Get the channel entry */
3794 /* Get channel ID */
3795 tmp = silc_channel_key_get_id(payload, &tmp_len);
3796 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3801 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3803 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3805 if (server->server_type == SILC_ROUTER)
3806 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3807 silc_id_render(&id, SILC_ID_CHANNEL)));
3813 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3815 tmp = silc_channel_key_get_key(payload, &tmp_len);
3821 cipher = silc_channel_key_get_cipher(payload, NULL);
3827 /* Remove old key if exists */
3829 memset(channel->key, 0, channel->key_len / 8);
3830 silc_free(channel->key);
3831 silc_cipher_free(channel->send_key);
3832 silc_cipher_free(channel->receive_key);
3835 /* Create new cipher */
3836 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3837 channel->send_key = NULL;
3841 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3842 silc_cipher_free(channel->send_key);
3843 channel->send_key = channel->receive_key = NULL;
3848 if (channel->cipher)
3849 silc_free(channel->cipher);
3850 channel->cipher = strdup(cipher);
3853 channel->key_len = tmp_len * 8;
3854 channel->key = silc_memdup(tmp, tmp_len);
3855 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3856 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3858 /* Generate HMAC key from the channel key data and set it */
3860 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3861 memset(channel->key, 0, channel->key_len / 8);
3862 silc_free(channel->key);
3863 silc_cipher_free(channel->send_key);
3864 silc_cipher_free(channel->receive_key);
3865 channel->send_key = channel->receive_key = NULL;
3868 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3869 silc_hmac_set_key(channel->hmac, hash,
3870 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3872 memset(hash, 0, sizeof(hash));
3873 memset(tmp, 0, tmp_len);
3875 if (server->server_type == SILC_ROUTER) {
3876 if (!channel->rekey)
3877 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3878 channel->rekey->channel = channel;
3879 if (channel->rekey->task)
3880 silc_schedule_task_del(server->schedule, channel->rekey->task);
3882 channel->rekey->task =
3883 silc_schedule_task_add_timeout(server->schedule,
3884 silc_server_channel_key_rekey,
3885 (void *)channel->rekey,
3886 server->config->channel_rekey_secs, 0);
3891 silc_channel_key_payload_free(payload);
3896 /* Returns assembled of all servers in the given ID list. The packet's
3897 form is dictated by the New ID payload. */
3899 static void silc_server_announce_get_servers(SilcServer server,
3900 SilcServerEntry remote,
3902 SilcBuffer *servers,
3903 unsigned long creation_time)
3906 SilcIDCacheEntry id_cache;
3907 SilcServerEntry entry;
3910 /* Go through all clients in the list */
3911 if (silc_idcache_get_all(id_list->servers, &list)) {
3912 silc_list_start(list);
3913 while ((id_cache = silc_list_get(list))) {
3914 entry = (SilcServerEntry)id_cache->context;
3916 /* Do not announce the one we've sending our announcements and
3917 do not announce ourself. Also check the creation time if it's
3919 if ((entry == remote) || (entry == server->id_entry) ||
3920 (creation_time && entry->data.created < creation_time))
3923 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3925 *servers = silc_buffer_realloc(*servers,
3927 silc_buffer_truelen((*servers)) +
3928 silc_buffer_len(idp) :
3929 silc_buffer_len(idp)));
3930 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3931 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3932 silc_buffer_pull(*servers, silc_buffer_len(idp));
3933 silc_buffer_free(idp);
3939 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3945 p = silc_notify_payload_encode(notify, argc, ap);
3951 /* This function is used by router to announce existing servers to our
3952 primary router when we've connected to it. If `creation_time' is non-zero
3953 then only the servers that has been created after the `creation_time'
3954 will be announced. */
3956 void silc_server_announce_servers(SilcServer server, SilcBool global,
3957 unsigned long creation_time,
3958 SilcPacketStream remote)
3960 SilcBuffer servers = NULL;
3962 SILC_LOG_DEBUG(("Announcing servers"));
3964 /* Get servers in local list */
3965 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3966 server->local_list, &servers,
3970 /* Get servers in global list */
3971 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3972 server->global_list, &servers,
3976 silc_buffer_push(servers, servers->data - servers->head);
3977 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
3979 /* Send the packet */
3980 silc_server_packet_send(server, remote,
3981 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3982 servers->data, silc_buffer_len(servers));
3984 silc_buffer_free(servers);
3988 /* Returns assembled packet of all clients in the given ID list. The
3989 packet's form is dictated by the New ID Payload. */
3991 static void silc_server_announce_get_clients(SilcServer server,
3993 SilcBuffer *clients,
3995 unsigned long creation_time)
3998 SilcIDCacheEntry id_cache;
3999 SilcClientEntry client;
4002 unsigned char mode[4];
4004 /* Go through all clients in the list */
4005 if (silc_idcache_get_all(id_list->clients, &list)) {
4006 silc_list_start(list);
4007 while ((id_cache = silc_list_get(list))) {
4008 client = (SilcClientEntry)id_cache->context;
4010 if (creation_time && client->data.created < creation_time)
4012 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4014 if (!client->connection && !client->router)
4017 SILC_LOG_DEBUG(("Announce Client ID %s",
4018 silc_id_render(client->id, SILC_ID_CLIENT)));
4020 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4022 *clients = silc_buffer_realloc(*clients,
4024 silc_buffer_truelen((*clients)) +
4025 silc_buffer_len(idp) :
4026 silc_buffer_len(idp)));
4027 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4028 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4029 silc_buffer_pull(*clients, silc_buffer_len(idp));
4031 SILC_PUT32_MSB(client->mode, mode);
4033 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4034 2, idp->data, silc_buffer_len(idp),
4036 *umodes = silc_buffer_realloc(*umodes,
4038 silc_buffer_truelen((*umodes)) +
4039 silc_buffer_len(tmp) :
4040 silc_buffer_len(tmp)));
4041 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4042 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4043 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4044 silc_buffer_free(tmp);
4046 silc_buffer_free(idp);
4051 /* This function is used to announce our existing clients to our router
4052 when we've connected to it. If `creation_time' is non-zero then only
4053 the clients that has been created after the `creation_time' will be
4056 void silc_server_announce_clients(SilcServer server,
4057 unsigned long creation_time,
4058 SilcPacketStream remote)
4060 SilcBuffer clients = NULL;
4061 SilcBuffer umodes = NULL;
4063 SILC_LOG_DEBUG(("Announcing clients"));
4065 /* Get clients in local list */
4066 silc_server_announce_get_clients(server, server->local_list,
4067 &clients, &umodes, creation_time);
4069 /* As router we announce our global list as well */
4070 if (server->server_type == SILC_ROUTER)
4071 silc_server_announce_get_clients(server, server->global_list,
4072 &clients, &umodes, creation_time);
4075 silc_buffer_push(clients, clients->data - clients->head);
4076 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4078 /* Send the packet */
4079 silc_server_packet_send(server, remote,
4080 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4081 clients->data, silc_buffer_len(clients));
4083 silc_buffer_free(clients);
4087 silc_buffer_push(umodes, umodes->data - umodes->head);
4088 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4090 /* Send the packet */
4091 silc_server_packet_send(server, remote,
4092 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4093 umodes->data, silc_buffer_len(umodes));
4095 silc_buffer_free(umodes);
4099 /* Returns channel's topic for announcing it */
4101 void silc_server_announce_get_channel_topic(SilcServer server,
4102 SilcChannelEntry channel,
4107 if (channel->topic) {
4108 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4109 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4111 silc_buffer_len(chidp),
4113 strlen(channel->topic));
4114 silc_buffer_free(chidp);
4118 /* Returns channel's invite and ban lists */
4120 void silc_server_announce_get_inviteban(SilcServer server,
4121 SilcChannelEntry channel,
4125 SilcBuffer list, idp, idp2, tmp2;
4127 SilcHashTableList htl;
4128 const unsigned char a[1] = { 0x03 };
4130 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4132 /* Encode invite list */
4133 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4134 list = silc_buffer_alloc_size(2);
4135 type = silc_hash_table_count(channel->invite_list);
4136 SILC_PUT16_MSB(type, list->data);
4137 silc_hash_table_list(channel->invite_list, &htl);
4138 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4139 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4141 silc_hash_table_list_reset(&htl);
4143 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4145 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4146 idp->data, silc_buffer_len(idp),
4147 channel->channel_name,
4148 strlen(channel->channel_name),
4149 idp2->data, silc_buffer_len(idp2),
4151 list->data, silc_buffer_len(list));
4152 silc_buffer_free(idp2);
4153 silc_buffer_free(list);
4156 /* Encode ban list */
4157 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4158 list = silc_buffer_alloc_size(2);
4159 type = silc_hash_table_count(channel->ban_list);
4160 SILC_PUT16_MSB(type, list->data);
4161 silc_hash_table_list(channel->ban_list, &htl);
4162 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4163 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4165 silc_hash_table_list_reset(&htl);
4168 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4169 idp->data, silc_buffer_len(idp),
4171 list->data, silc_buffer_len(list));
4172 silc_buffer_free(list);
4175 silc_buffer_free(idp);
4178 /* Returns assembled packets for channel users of the `channel'. */
4180 void silc_server_announce_get_channel_users(SilcServer server,
4181 SilcChannelEntry channel,
4182 SilcBuffer *channel_modes,
4183 SilcBuffer *channel_users,
4184 SilcBuffer *channel_users_modes)
4186 SilcChannelClientEntry chl;
4187 SilcHashTableList htl;
4188 SilcBuffer chidp, clidp, csidp;
4189 SilcBuffer tmp, fkey = NULL, chpklist;
4191 unsigned char mode[4], ulimit[4];
4194 SILC_LOG_DEBUG(("Start"));
4196 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4197 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4198 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4201 SILC_PUT32_MSB(channel->mode, mode);
4202 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4203 SILC_PUT32_MSB(channel->user_limit, ulimit);
4204 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4205 if (channel->founder_key)
4206 fkey = silc_public_key_payload_encode(channel->founder_key);
4208 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4210 silc_buffer_len(csidp),
4213 hmac, hmac ? strlen(hmac) : 0,
4214 channel->passphrase,
4215 channel->passphrase ?
4216 strlen(channel->passphrase) : 0,
4217 fkey ? fkey->data : NULL,
4218 fkey ? silc_buffer_len(fkey) : 0,
4219 chpklist ? chpklist->data : NULL,
4221 silc_buffer_len(chpklist) : 0,
4223 SILC_CHANNEL_MODE_ULIMIT ?
4226 SILC_CHANNEL_MODE_ULIMIT ?
4227 sizeof(ulimit) : 0));
4228 len = silc_buffer_len(tmp);
4230 silc_buffer_realloc(*channel_modes,
4232 silc_buffer_truelen((*channel_modes)) + len : len));
4233 silc_buffer_pull_tail(*channel_modes,
4234 ((*channel_modes)->end -
4235 (*channel_modes)->data));
4236 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4237 silc_buffer_pull(*channel_modes, len);
4238 silc_buffer_free(tmp);
4239 silc_buffer_free(fkey);
4242 /* Now find all users on the channel */
4243 silc_hash_table_list(channel->user_list, &htl);
4244 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4245 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4247 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4251 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4253 silc_buffer_len(clidp),
4255 silc_buffer_len(chidp));
4256 len = silc_buffer_len(tmp);
4258 silc_buffer_realloc(*channel_users,
4260 silc_buffer_truelen((*channel_users)) + len : len));
4261 silc_buffer_pull_tail(*channel_users,
4262 ((*channel_users)->end -
4263 (*channel_users)->data));
4265 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4266 silc_buffer_pull(*channel_users, len);
4267 silc_buffer_free(tmp);
4269 /* CUMODE notify for mode change on the channel */
4270 SILC_PUT32_MSB(chl->mode, mode);
4271 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4272 fkey = silc_public_key_payload_encode(channel->founder_key);
4273 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4275 silc_buffer_len(csidp),
4278 silc_buffer_len(clidp),
4279 fkey ? fkey->data : NULL,
4280 fkey ? silc_buffer_len(fkey) : 0);
4281 len = silc_buffer_len(tmp);
4282 *channel_users_modes =
4283 silc_buffer_realloc(*channel_users_modes,
4284 (*channel_users_modes ?
4285 silc_buffer_truelen((*channel_users_modes)) +
4287 silc_buffer_pull_tail(*channel_users_modes,
4288 ((*channel_users_modes)->end -
4289 (*channel_users_modes)->data));
4291 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4292 silc_buffer_pull(*channel_users_modes, len);
4293 silc_buffer_free(tmp);
4294 silc_buffer_free(fkey);
4296 silc_buffer_free(clidp);
4298 silc_hash_table_list_reset(&htl);
4299 silc_buffer_free(chidp);
4300 silc_buffer_free(csidp);
4303 /* Returns assembled packets for all channels and users on those channels
4304 from the given ID List. The packets are in the form dictated by the
4305 New Channel and New Channel User payloads. */
4307 void silc_server_announce_get_channels(SilcServer server,
4309 SilcBuffer *channels,
4310 SilcBuffer **channel_modes,
4311 SilcBuffer *channel_users,
4312 SilcBuffer **channel_users_modes,
4313 SilcUInt32 *channel_users_modes_c,
4314 SilcBuffer **channel_topics,
4315 SilcBuffer **channel_invites,
4316 SilcBuffer **channel_bans,
4317 SilcChannelID ***channel_ids,
4318 unsigned long creation_time)
4321 SilcIDCacheEntry id_cache;
4322 SilcChannelEntry channel;
4323 unsigned char cid[32];
4325 SilcUInt16 name_len;
4327 int i = *channel_users_modes_c;
4330 SILC_LOG_DEBUG(("Start"));
4332 /* Go through all channels in the list */
4333 if (silc_idcache_get_all(id_list->channels, &list)) {
4334 silc_list_start(list);
4335 while ((id_cache = silc_list_get(list))) {
4336 channel = (SilcChannelEntry)id_cache->context;
4338 if (creation_time && channel->created < creation_time)
4343 SILC_LOG_DEBUG(("Announce Channel ID %s",
4344 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4346 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4347 name_len = strlen(channel->channel_name);
4350 len = 4 + name_len + id_len + 4;
4352 silc_buffer_realloc(*channels,
4354 silc_buffer_truelen((*channels)) +
4356 silc_buffer_pull_tail(*channels,
4357 ((*channels)->end - (*channels)->data));
4358 silc_buffer_format(*channels,
4359 SILC_STR_UI_SHORT(name_len),
4360 SILC_STR_UI_XNSTRING(channel->channel_name,
4362 SILC_STR_UI_SHORT(id_len),
4363 SILC_STR_UI_XNSTRING(cid, id_len),
4364 SILC_STR_UI_INT(channel->mode),
4366 silc_buffer_pull(*channels, len);
4369 if (creation_time && channel->updated < creation_time)
4375 /* Channel user modes */
4376 *channel_users_modes = silc_realloc(*channel_users_modes,
4377 sizeof(**channel_users_modes) *
4379 (*channel_users_modes)[i] = NULL;
4380 *channel_modes = silc_realloc(*channel_modes,
4381 sizeof(**channel_modes) * (i + 1));
4382 (*channel_modes)[i] = NULL;
4383 *channel_ids = silc_realloc(*channel_ids,
4384 sizeof(**channel_ids) * (i + 1));
4385 (*channel_ids)[i] = NULL;
4386 silc_server_announce_get_channel_users(server, channel,
4387 &(*channel_modes)[i],
4389 &(*channel_users_modes)[i]);
4390 (*channel_ids)[i] = channel->id;
4392 /* Channel's topic */
4393 *channel_topics = silc_realloc(*channel_topics,
4394 sizeof(**channel_topics) * (i + 1));
4395 (*channel_topics)[i] = NULL;
4396 silc_server_announce_get_channel_topic(server, channel,
4397 &(*channel_topics)[i]);
4399 /* Channel's invite and ban list */
4400 *channel_invites = silc_realloc(*channel_invites,
4401 sizeof(**channel_invites) * (i + 1));
4402 (*channel_invites)[i] = NULL;
4403 *channel_bans = silc_realloc(*channel_bans,
4404 sizeof(**channel_bans) * (i + 1));
4405 (*channel_bans)[i] = NULL;
4406 silc_server_announce_get_inviteban(server, channel,
4407 &(*channel_invites)[i],
4408 &(*channel_bans)[i]);
4410 (*channel_users_modes_c)++;
4418 /* This function is used to announce our existing channels to our router
4419 when we've connected to it. This also announces the users on the
4420 channels to the router. If the `creation_time' is non-zero only the
4421 channels that was created after the `creation_time' are announced.
4422 Note that the channel users are still announced even if the `creation_time'
4425 void silc_server_announce_channels(SilcServer server,
4426 unsigned long creation_time,
4427 SilcPacketStream remote)
4429 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4430 SilcBuffer *channel_users_modes = NULL;
4431 SilcBuffer *channel_topics = NULL;
4432 SilcBuffer *channel_invites = NULL;
4433 SilcBuffer *channel_bans = NULL;
4434 SilcUInt32 channel_users_modes_c = 0;
4435 SilcChannelID **channel_ids = NULL;
4437 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4439 /* Get channels and channel users in local list */
4440 silc_server_announce_get_channels(server, server->local_list,
4441 &channels, &channel_modes,
4443 &channel_users_modes,
4444 &channel_users_modes_c,
4448 &channel_ids, creation_time);
4450 /* Get channels and channel users in global list */
4451 if (server->server_type != SILC_SERVER)
4452 silc_server_announce_get_channels(server, server->global_list,
4453 &channels, &channel_modes,
4455 &channel_users_modes,
4456 &channel_users_modes_c,
4460 &channel_ids, creation_time);
4463 silc_buffer_push(channels, channels->data - channels->head);
4464 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4466 /* Send the packet */
4467 silc_server_packet_send(server, remote,
4468 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4469 channels->data, silc_buffer_len(channels));
4471 silc_buffer_free(channels);
4474 if (channel_users) {
4475 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4476 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4477 silc_buffer_len(channel_users));
4479 /* Send the packet */
4480 silc_server_packet_send(server, remote,
4481 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4482 channel_users->data, silc_buffer_len(channel_users));
4484 silc_buffer_free(channel_users);
4487 if (channel_modes) {
4490 for (i = 0; i < channel_users_modes_c; i++) {
4491 if (!channel_modes[i])
4493 silc_buffer_push(channel_modes[i],
4494 channel_modes[i]->data -
4495 channel_modes[i]->head);
4496 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4497 silc_buffer_len(channel_modes[i]));
4498 silc_server_packet_send_dest(server, remote,
4499 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4500 channel_ids[i], SILC_ID_CHANNEL,
4501 channel_modes[i]->data,
4502 silc_buffer_len(channel_modes[i]));
4503 silc_buffer_free(channel_modes[i]);
4505 silc_free(channel_modes);
4508 if (channel_users_modes) {
4511 for (i = 0; i < channel_users_modes_c; i++) {
4512 if (!channel_users_modes[i])
4514 silc_buffer_push(channel_users_modes[i],
4515 channel_users_modes[i]->data -
4516 channel_users_modes[i]->head);
4517 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4518 silc_buffer_len(channel_users_modes[i]));
4519 silc_server_packet_send_dest(server, remote,
4520 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4521 channel_ids[i], SILC_ID_CHANNEL,
4522 channel_users_modes[i]->data,
4523 silc_buffer_len(channel_users_modes[i]));
4524 silc_buffer_free(channel_users_modes[i]);
4526 silc_free(channel_users_modes);
4529 if (channel_topics) {
4532 for (i = 0; i < channel_users_modes_c; i++) {
4533 if (!channel_topics[i])
4536 silc_buffer_push(channel_topics[i],
4537 channel_topics[i]->data -
4538 channel_topics[i]->head);
4539 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4540 silc_buffer_len(channel_topics[i]));
4541 silc_server_packet_send_dest(server, remote,
4542 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4543 channel_ids[i], SILC_ID_CHANNEL,
4544 channel_topics[i]->data,
4545 silc_buffer_len(channel_topics[i]));
4546 silc_buffer_free(channel_topics[i]);
4548 silc_free(channel_topics);
4551 if (channel_invites) {
4554 for (i = 0; i < channel_users_modes_c; i++) {
4555 if (!channel_invites[i])
4558 silc_buffer_push(channel_invites[i],
4559 channel_invites[i]->data -
4560 channel_invites[i]->head);
4561 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4562 silc_buffer_len(channel_invites[i]));
4563 silc_server_packet_send_dest(server, remote,
4564 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4565 channel_ids[i], SILC_ID_CHANNEL,
4566 channel_invites[i]->data,
4567 silc_buffer_len(channel_invites[i]));
4568 silc_buffer_free(channel_invites[i]);
4570 silc_free(channel_invites);
4576 for (i = 0; i < channel_users_modes_c; i++) {
4577 if (!channel_bans[i])
4580 silc_buffer_push(channel_bans[i],
4581 channel_bans[i]->data -
4582 channel_bans[i]->head);
4583 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4584 silc_buffer_len(channel_bans[i]));
4585 silc_server_packet_send_dest(server, remote,
4586 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4587 channel_ids[i], SILC_ID_CHANNEL,
4588 channel_bans[i]->data,
4589 silc_buffer_len(channel_bans[i]));
4590 silc_buffer_free(channel_bans[i]);
4592 silc_free(channel_bans);
4595 silc_free(channel_ids);
4598 /* Announces WATCH list. */
4600 void silc_server_announce_watches(SilcServer server,
4601 SilcPacketStream remote)
4603 SilcHashTableList htl;
4604 SilcBuffer buffer, idp, args, pkp;
4605 SilcClientEntry client;
4608 SILC_LOG_DEBUG(("Announcing watch list"));
4610 /* XXX because way we save the nicks (hash) we cannot announce them. */
4612 /* XXX we should send all public keys in one command if client is
4613 watching more than one key */
4614 silc_hash_table_list(server->watcher_list_pk, &htl);
4615 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4616 if (!client || !client->id)
4619 server->stat.commands_sent++;
4621 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4622 args = silc_buffer_alloc_size(2);
4623 silc_buffer_format(args,
4624 SILC_STR_UI_SHORT(1),
4626 pkp = silc_public_key_payload_encode(key);
4627 args = silc_argument_payload_encode_one(args, pkp->data,
4628 silc_buffer_len(pkp), 0x00);
4629 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4630 ++server->cmd_ident, 2,
4631 1, idp->data, silc_buffer_len(idp),
4633 silc_buffer_len(args));
4636 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4637 buffer->data, silc_buffer_len(buffer));
4639 silc_buffer_free(pkp);
4640 silc_buffer_free(args);
4641 silc_buffer_free(idp);
4642 silc_buffer_free(buffer);
4644 silc_hash_table_list_reset(&htl);
4647 /* Assembles user list and users mode list from the `channel'. */
4649 SilcBool silc_server_get_users_on_channel(SilcServer server,
4650 SilcChannelEntry channel,
4651 SilcBuffer *user_list,
4652 SilcBuffer *mode_list,
4653 SilcUInt32 *user_count)
4655 SilcChannelClientEntry chl;
4656 SilcHashTableList htl;
4657 SilcBuffer client_id_list;
4658 SilcBuffer client_mode_list;
4660 SilcUInt32 list_count = 0, len = 0;
4662 if (!silc_hash_table_count(channel->user_list))
4665 silc_hash_table_list(channel->user_list, &htl);
4666 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4667 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4668 silc_hash_table_list_reset(&htl);
4670 client_id_list = silc_buffer_alloc(len);
4672 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4673 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4674 silc_buffer_pull_tail(client_mode_list,
4675 silc_buffer_truelen(client_mode_list));
4677 silc_hash_table_list(channel->user_list, &htl);
4678 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4680 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4681 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4682 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4683 silc_buffer_free(idp);
4685 /* Client's mode on channel */
4686 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4687 silc_buffer_pull(client_mode_list, 4);
4691 silc_hash_table_list_reset(&htl);
4692 silc_buffer_push(client_id_list,
4693 client_id_list->data - client_id_list->head);
4694 silc_buffer_push(client_mode_list,
4695 client_mode_list->data - client_mode_list->head);
4697 *user_list = client_id_list;
4698 *mode_list = client_mode_list;
4699 *user_count = list_count;
4703 /* Saves users and their modes to the `channel'. */
4705 void silc_server_save_users_on_channel(SilcServer server,
4706 SilcPacketStream sock,
4707 SilcChannelEntry channel,
4708 SilcClientID *noadd,
4709 SilcBuffer user_list,
4710 SilcBuffer mode_list,
4711 SilcUInt32 user_count)
4717 SilcClientEntry client;
4718 SilcIDCacheEntry cache;
4719 SilcChannelClientEntry chl;
4721 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4722 channel->channel_name));
4724 for (i = 0; i < user_count; i++) {
4726 SILC_GET16_MSB(idp_len, user_list->data + 2);
4728 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4730 silc_buffer_pull(user_list, idp_len);
4733 SILC_GET32_MSB(mode, mode_list->data);
4734 silc_buffer_pull(mode_list, 4);
4736 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4741 /* Check if we have this client cached already. */
4742 client = silc_idlist_find_client_by_id(server->local_list,
4744 server->server_type, &cache);
4746 client = silc_idlist_find_client_by_id(server->global_list,
4748 server->server_type, &cache);
4750 /* If router did not find such Client ID in its lists then this must
4751 be bogus client or some router in the net is buggy. */
4752 if (server->server_type != SILC_SERVER)
4755 /* We don't have that client anywhere, add it. The client is added
4756 to global list since server didn't have it in the lists so it must be
4758 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4759 silc_id_dup(&id.u.client_id,
4761 silc_packet_get_context(sock),
4764 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4768 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4771 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4772 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4773 "%s", channel->channel_name));
4777 if (!silc_server_client_on_channel(client, channel, &chl)) {
4778 /* Client was not on the channel, add it. */
4779 chl = silc_calloc(1, sizeof(*chl));
4780 chl->client = client;
4782 chl->channel = channel;
4783 silc_hash_table_add(channel->user_list, chl->client, chl);
4784 silc_hash_table_add(client->channels, chl->channel, chl);
4785 channel->user_count++;
4793 /* Saves channels and channels user modes to the `client'. Removes
4794 the client from those channels that are not sent in the list but
4797 void silc_server_save_user_channels(SilcServer server,
4798 SilcPacketStream sock,
4799 SilcClientEntry client,
4800 SilcBuffer channels,
4801 SilcBuffer channels_user_modes)
4804 SilcUInt32 *chumodes;
4805 SilcChannelPayload entry;
4806 SilcChannelEntry channel;
4807 SilcChannelID channel_id;
4808 SilcChannelClientEntry chl;
4809 SilcHashTable ht = NULL;
4810 SilcHashTableList htl;
4814 if (!channels || !channels_user_modes ||
4815 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4818 ch = silc_channel_payload_parse_list(channels->data,
4819 silc_buffer_len(channels));
4820 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4822 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4823 NULL, NULL, NULL, TRUE);
4824 silc_dlist_start(ch);
4825 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4826 /* Check if we have this channel, and add it if we don't have it.
4827 Also add the client on the channel unless it is there already. */
4828 if (!silc_channel_get_id_parse(entry, &channel_id))
4830 channel = silc_idlist_find_channel_by_id(server->local_list,
4833 channel = silc_idlist_find_channel_by_id(server->global_list,
4836 if (server->server_type != SILC_SERVER) {
4841 /* We don't have that channel anywhere, add it. */
4842 name = silc_channel_get_name(entry, NULL);
4843 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4844 silc_id_dup(&channel_id,
4846 server->router, NULL, NULL, 0);
4853 channel->mode = silc_channel_get_mode(entry);
4855 /* Add the client on the channel */
4856 if (!silc_server_client_on_channel(client, channel, &chl)) {
4857 chl = silc_calloc(1, sizeof(*chl));
4858 chl->client = client;
4859 chl->mode = chumodes[i++];
4860 chl->channel = channel;
4861 silc_hash_table_add(channel->user_list, chl->client, chl);
4862 silc_hash_table_add(client->channels, chl->channel, chl);
4863 channel->user_count++;
4866 chl->mode = chumodes[i++];
4869 silc_hash_table_add(ht, channel, channel);
4871 silc_channel_payload_list_free(ch);
4872 silc_free(chumodes);
4876 /* Go through the list again and remove client from channels that
4877 are no part of the list. */
4879 silc_hash_table_list(client->channels, &htl);
4880 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4881 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4882 silc_hash_table_del(chl->channel->user_list, chl->client);
4883 silc_hash_table_del(chl->client->channels, chl->channel);
4887 silc_hash_table_list_reset(&htl);
4888 silc_hash_table_free(ht);
4890 silc_hash_table_list(client->channels, &htl);
4891 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4892 silc_hash_table_del(chl->channel->user_list, chl->client);
4893 silc_hash_table_del(chl->client->channels, chl->channel);
4896 silc_hash_table_list_reset(&htl);
4900 /* Lookups route to the client indicated by the `id_data'. The connection
4901 object and internal data object is returned. Returns NULL if route
4902 could not be found to the client. If the `client_id' is specified then
4903 it is used and the `id_data' is ignored. */
4906 silc_server_get_client_route(SilcServer server,
4907 unsigned char *id_data,
4909 SilcClientID *client_id,
4910 SilcIDListData *idata,
4911 SilcClientEntry *client_entry)
4913 SilcClientID *id, clid;
4914 SilcClientEntry client;
4916 SILC_LOG_DEBUG(("Start"));
4919 *client_entry = NULL;
4921 /* Decode destination Client ID */
4923 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
4925 id = silc_id_dup(&clid, SILC_ID_CLIENT);
4927 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4930 /* If the destination belongs to our server we don't have to route
4931 the packet anywhere but to send it to the local destination. */
4932 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4936 /* If we are router and the client has router then the client is in
4937 our cell but not directly connected to us. */
4938 if (server->server_type == SILC_ROUTER && client->router) {
4939 /* We are of course in this case the client's router thus the route
4940 to the client is the server who owns the client. So, we will send
4941 the packet to that server. */
4943 *idata = (SilcIDListData)client->router;
4944 return client->router->connection;
4947 /* Seems that client really is directly connected to us */
4949 *idata = (SilcIDListData)client;
4951 *client_entry = client;
4952 return client->connection;
4955 /* Destination belongs to someone not in this server. If we are normal
4956 server our action is to send the packet to our router. */
4957 if (server->server_type != SILC_ROUTER && !server->standalone) {
4960 *idata = (SilcIDListData)server->router;
4961 return SILC_PRIMARY_ROUTE(server);
4964 /* We are router and we will perform route lookup for the destination
4965 and send the packet to fastest route. */
4966 if (server->server_type == SILC_ROUTER && !server->standalone) {
4967 /* Check first that the ID is valid */
4968 client = silc_idlist_find_client_by_id(server->global_list, id,
4971 SilcPacketStream dst_sock;
4973 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4976 if (idata && dst_sock)
4977 *idata = silc_packet_get_context(dst_sock);
4986 /* Encodes and returns channel list of channels the `client' has joined.
4987 Secret channels are not put to the list. */
4989 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4990 SilcClientEntry client,
4991 SilcBool get_private,
4992 SilcBool get_secret,
4993 SilcBuffer *user_mode_list)
4995 SilcBuffer buffer = NULL;
4996 SilcChannelEntry channel;
4997 SilcChannelClientEntry chl;
4998 SilcHashTableList htl;
4999 unsigned char cid[32];
5001 SilcUInt16 name_len;
5005 *user_mode_list = NULL;
5007 silc_hash_table_list(client->channels, &htl);
5008 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5009 channel = chl->channel;
5011 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5013 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5016 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5017 name_len = strlen(channel->channel_name);
5019 len = 4 + name_len + id_len + 4;
5020 buffer = silc_buffer_realloc(buffer,
5022 silc_buffer_truelen(buffer) + len : len));
5023 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5024 silc_buffer_format(buffer,
5025 SILC_STR_UI_SHORT(name_len),
5026 SILC_STR_DATA(channel->channel_name, name_len),
5027 SILC_STR_UI_SHORT(id_len),
5028 SILC_STR_DATA(cid, id_len),
5029 SILC_STR_UI_INT(chl->channel->mode),
5031 silc_buffer_pull(buffer, len);
5033 if (user_mode_list) {
5035 silc_buffer_realloc(*user_mode_list,
5037 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5038 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5039 (*user_mode_list)->data));
5040 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5041 silc_buffer_pull(*user_mode_list, 4);
5044 silc_hash_table_list_reset(&htl);
5047 silc_buffer_push(buffer, buffer->data - buffer->head);
5048 if (user_mode_list && *user_mode_list)
5049 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5050 (*user_mode_list)->head));
5055 /* Task callback used to retrieve network statistical information from
5056 router server once in a while. */
5058 SILC_TASK_CALLBACK(silc_server_get_stats)
5060 SilcServer server = (SilcServer)context;
5061 SilcBuffer idp, packet;
5063 if (!server->standalone) {
5064 SILC_LOG_DEBUG(("Retrieving stats from router"));
5065 server->stat.commands_sent++;
5066 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5068 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5069 ++server->cmd_ident, 1,
5071 silc_buffer_len(idp));
5072 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5073 SILC_PACKET_COMMAND, 0, packet->data,
5074 silc_buffer_len(packet));
5075 silc_buffer_free(packet);
5076 silc_buffer_free(idp);
5080 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,