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_CONNECTION_AUTH_REQUEST &&
107 packet->type != SILC_PACKET_DISCONNECT)
110 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID
111 and for unregistered connection. */
112 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
113 packet->type == SILC_PACKET_NEW_SERVER) &&
114 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
117 /* Ignore packets from disabled connection */
118 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
119 packet->type != SILC_PACKET_HEARTBEAT &&
120 packet->type != SILC_PACKET_RESUME_ROUTER &&
121 packet->type != SILC_PACKET_REKEY)
124 /* Check that the the current client ID is same as in the client's packet. */
125 if (idata->conn_type == SILC_CONN_CLIENT) {
126 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
127 SilcClientID client_id;
129 if (client->id && packet->src_id &&
130 silc_id_str2id(packet->src_id, packet->src_id_len,
131 packet->src_id_type, &client_id, sizeof(client_id))) {
132 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
133 SILC_LOG_DEBUG(("Packet source is not same as sender"));
139 if (server->server_type == SILC_ROUTER) {
140 /* Route the packet if it is not destined to us. Other ID types but
141 server are handled separately after processing them. */
142 if (packet->dst_id &&
143 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
144 packet->dst_id_type == SILC_ID_SERVER &&
145 idata->conn_type != SILC_CONN_CLIENT &&
146 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
147 SilcPacketStream conn;
148 SilcServerID server_id;
150 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
151 &server_id, sizeof(server_id));
153 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
155 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
156 silc_id_render(&server_id, SILC_ID_SERVER)));
160 silc_server_packet_route(server, conn, packet);
161 silc_packet_free(packet);
166 /* Broadcast packet if it is marked as broadcast packet and it is
167 originated from router and we are router. */
168 if (server->server_type == SILC_ROUTER &&
169 idata->conn_type == SILC_CONN_ROUTER &&
170 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
171 /* Broadcast to our primary route */
172 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
174 /* If we have backup routers then we need to feed all broadcast
175 data to those servers. */
176 silc_server_backup_broadcast(server, stream, packet);
180 silc_server_packet_parse_type(server, stream, packet);
185 /* Packet engine callback to indicate end of stream */
187 static void silc_server_packet_eos(SilcPacketEngine engine,
188 SilcPacketStream stream,
189 void *callback_context,
190 void *stream_context)
192 SilcServer server = callback_context;
193 SilcIDListData idata = silc_packet_get_context(stream);
195 SILC_LOG_DEBUG(("End of stream received"));
200 if (server->router_conn && server->router_conn->sock == stream &&
201 !server->router && server->standalone) {
202 silc_server_create_connections(server);
204 /* If backup disconnected then mark that resuming will not be allowed */
205 if (server->server_type == SILC_ROUTER && !server->backup_router &&
206 idata->conn_type == SILC_CONN_SERVER) {
207 SilcServerEntry server_entry = (SilcServerEntry)idata;
208 if (server_entry->server_type == SILC_BACKUP_ROUTER)
209 server->backup_closed = TRUE;
212 silc_server_free_sock_user_data(server, stream, NULL);
215 silc_server_close_connection(server, stream);
218 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
220 SilcServer server = app_context;
221 SilcPacketStream stream = context;
222 SilcIDListData idata = silc_packet_get_context(stream);
227 if (server->router_conn && server->router_conn->sock == stream &&
228 !server->router && server->standalone) {
229 silc_server_create_connections(server);
231 /* If backup disconnected then mark that resuming will not be allowed */
232 if (server->server_type == SILC_ROUTER && !server->backup_router &&
233 idata->conn_type == SILC_CONN_SERVER) {
234 SilcServerEntry server_entry = (SilcServerEntry)idata;
235 if (server_entry->server_type == SILC_BACKUP_ROUTER)
236 server->backup_closed = TRUE;
239 silc_server_free_sock_user_data(server, stream, NULL);
242 silc_server_close_connection(server, stream);
245 /* Packet engine callback to indicate error */
247 static void silc_server_packet_error(SilcPacketEngine engine,
248 SilcPacketStream stream,
249 SilcPacketError error,
250 void *callback_context,
251 void *stream_context)
253 SilcServer server = callback_context;
254 SilcIDListData idata = silc_packet_get_context(stream);
255 SilcStream sock = silc_packet_stream_get_stream(stream);
262 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
265 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
266 SILC_CONNTYPE_STRING(idata->conn_type),
267 silc_packet_error_string(error)));
269 silc_schedule_task_add_timeout(server->schedule,
270 silc_server_packet_error_timeout,
274 /* Packet stream callbacks */
275 static SilcPacketCallbacks silc_server_stream_cbs =
277 silc_server_packet_receive,
278 silc_server_packet_eos,
279 silc_server_packet_error
282 /* Parses the packet type and calls what ever routines the packet type
283 requires. This is done for all incoming packets. */
285 static void silc_server_packet_parse_type(SilcServer server,
286 SilcPacketStream sock,
289 SilcPacketType type = packet->type;
290 SilcIDListData idata = silc_packet_get_context(sock);
292 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
293 silc_get_packet_name(type), packet->flags));
295 /* Parse the packet type */
297 case SILC_PACKET_NOTIFY:
299 * Received notify packet. Server can receive notify packets from
300 * router. Server then relays the notify messages to clients if needed.
302 if (packet->flags & SILC_PACKET_FLAG_LIST)
303 silc_server_notify_list(server, sock, packet);
305 silc_server_notify(server, sock, packet);
309 * Private Message packets
311 case SILC_PACKET_PRIVATE_MESSAGE:
313 * Received private message packet. The packet is coming from either
316 if (packet->flags & SILC_PACKET_FLAG_LIST)
318 idata->last_receive = time(NULL);
319 silc_server_private_message(server, sock, packet);
325 case SILC_PACKET_CHANNEL_MESSAGE:
327 * Received channel message. Channel messages are special packets
328 * (although probably most common ones) thus they are handled
331 if (packet->flags & SILC_PACKET_FLAG_LIST)
333 idata->last_receive = time(NULL);
334 silc_server_channel_message(server, sock, packet);
340 case SILC_PACKET_COMMAND:
342 * Recived command. Processes the command request and allocates the
343 * command context and calls the command.
345 if (packet->flags & SILC_PACKET_FLAG_LIST)
347 server->stat.commands_received++;
348 silc_server_command_process(server, sock, packet);
351 case SILC_PACKET_COMMAND_REPLY:
353 * Received command reply packet. Received command reply to command. It
354 * may be reply to command sent by us or reply to command sent by client
355 * that we've routed further.
357 if (packet->flags & SILC_PACKET_FLAG_LIST)
359 server->stat.commands_received++;
360 silc_server_command_reply(server, sock, packet);
363 case SILC_PACKET_DISCONNECT:
366 char *message = NULL;
367 const char *hostname, *ip;
369 if (packet->flags & SILC_PACKET_FLAG_LIST)
371 if (silc_buffer_len(&packet->buffer) < 1)
374 status = (SilcStatus)packet->buffer.data[0];
375 if (silc_buffer_len(&packet->buffer) > 1 &&
376 silc_utf8_valid(packet->buffer.data + 1,
377 silc_buffer_len(&packet->buffer) - 1))
378 message = silc_memdup(packet->buffer.data + 1,
379 silc_buffer_len(&packet->buffer) - 1);
381 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
382 NULL, &hostname, &ip, NULL))
385 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
386 silc_get_status_message(status), status,
387 message ? message : ""));
391 /* Do not switch to backup in case of error */
392 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
394 /* If backup disconnected then mark that resuming will not be allowed */
395 if (server->server_type == SILC_ROUTER && !server->backup_router &&
396 idata->conn_type == SILC_CONN_SERVER) {
397 SilcServerEntry server_entry = (SilcServerEntry)idata;
398 if (server_entry->server_type == SILC_BACKUP_ROUTER)
399 server->backup_closed = TRUE;
402 /* Handle the disconnection from our end too */
403 if (SILC_IS_LOCAL(idata))
404 silc_server_free_sock_user_data(server, sock, NULL);
405 silc_server_close_connection(server, sock);
406 server->backup_noswitch = FALSE;
410 case SILC_PACKET_CHANNEL_KEY:
412 * Received key for channel. As channels are created by the router
413 * the keys are as well. We will distribute the key to all of our
414 * locally connected clients on the particular channel. Router
415 * never receives this channel and thus is ignored.
417 if (packet->flags & SILC_PACKET_FLAG_LIST)
419 silc_server_channel_key(server, sock, packet);
422 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
424 * Private message key packet.
426 if (packet->flags & SILC_PACKET_FLAG_LIST)
428 silc_server_private_message_key(server, sock, packet);
431 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
433 * Connection authentication request packet. When we receive this packet
434 * we will send to the other end information about our mandatory
435 * authentication method for the connection. This packet maybe received
438 if (packet->flags & SILC_PACKET_FLAG_LIST)
440 silc_server_connection_auth_request(server, sock, packet);
443 case SILC_PACKET_NEW_ID:
445 * Received New ID packet. This includes some new ID that has been
446 * created. It may be for client, server or channel. This is the way
447 * to distribute information about new registered entities in the
450 if (packet->flags & SILC_PACKET_FLAG_LIST)
451 silc_server_new_id_list(server, sock, packet);
453 silc_server_new_id(server, sock, packet);
456 case SILC_PACKET_NEW_CLIENT:
458 * Received new client packet. This includes client information that
459 * we will use to create initial client ID. After creating new
460 * ID we will send it to the client.
462 if (packet->flags & SILC_PACKET_FLAG_LIST)
464 silc_server_new_client(server, sock, packet);
467 case SILC_PACKET_NEW_SERVER:
469 * Received new server packet. This includes Server ID and some other
470 * information that we may save. This is received after server has
473 if (packet->flags & SILC_PACKET_FLAG_LIST)
475 silc_server_new_server(server, sock, packet);
478 case SILC_PACKET_NEW_CHANNEL:
480 * Received new channel packet. Information about new channel in the
481 * network are distributed using this packet.
483 if (packet->flags & SILC_PACKET_FLAG_LIST)
484 silc_server_new_channel_list(server, sock, packet);
486 silc_server_new_channel(server, sock, packet);
489 case SILC_PACKET_HEARTBEAT:
491 * Received heartbeat.
493 if (packet->flags & SILC_PACKET_FLAG_LIST)
497 case SILC_PACKET_KEY_AGREEMENT:
499 * Received heartbeat.
501 if (packet->flags & SILC_PACKET_FLAG_LIST)
503 silc_server_key_agreement(server, sock, packet);
506 case SILC_PACKET_REKEY:
508 * Received re-key packet. The sender wants to regenerate the session
511 if (packet->flags & SILC_PACKET_FLAG_LIST)
513 silc_server_rekey(server, sock, packet);
516 case SILC_PACKET_FTP:
518 if (packet->flags & SILC_PACKET_FLAG_LIST)
520 silc_server_ftp(server, sock, packet);
523 case SILC_PACKET_RESUME_CLIENT:
525 if (packet->flags & SILC_PACKET_FLAG_LIST)
527 silc_server_resume_client(server, sock, packet);
530 case SILC_PACKET_RESUME_ROUTER:
531 /* Resume router packet received. This packet is received for backup
532 router resuming protocol. */
533 if (packet->flags & SILC_PACKET_FLAG_LIST)
535 silc_server_backup_resume_router(server, sock, packet);
539 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
544 /****************************** Server API **********************************/
546 /* Allocates a new SILC server object. This has to be done before the server
547 can be used. After allocation one must call silc_server_init to initialize
548 the server. The new allocated server object is returned to the new_server
551 SilcBool silc_server_alloc(SilcServer *new_server)
555 SILC_LOG_DEBUG(("Allocating new server object"));
557 server = silc_calloc(1, sizeof(*server));
560 server->server_type = SILC_SERVER;
561 server->standalone = TRUE;
562 server->local_list = silc_calloc(1, sizeof(*server->local_list));
563 if (!server->local_list)
565 server->global_list = silc_calloc(1, sizeof(*server->global_list));
566 if (!server->global_list)
568 server->pending_commands = silc_dlist_init();
569 if (!server->pending_commands)
571 server->listeners = silc_dlist_init();
572 if (!server->listeners)
574 server->repository = silc_skr_alloc();
575 if (!server->repository)
577 server->conns = silc_dlist_init();
580 server->expired_clients = silc_dlist_init();
581 if (!server->expired_clients)
584 *new_server = server;
589 /* Free's the SILC server object. This is called at the very end before
592 void silc_server_free(SilcServer server)
595 SilcIDCacheEntry cache;
596 SilcIDListData idata;
598 SILC_LOG_DEBUG(("Free server %p", server));
603 silc_server_backup_free(server);
604 silc_server_config_unref(&server->config_ref);
606 silc_rng_free(server->rng);
607 if (server->public_key)
608 silc_pkcs_public_key_free(server->public_key);
609 if (server->private_key)
610 silc_pkcs_private_key_free(server->private_key);
611 if (server->pending_commands)
612 silc_dlist_uninit(server->pending_commands);
613 if (server->id_entry) {
614 if (server->id_entry->data.sconn)
615 silc_schedule_task_del_by_context(server->schedule,
616 server->id_entry->data.sconn->sock);
617 silc_idlist_del_server(server->local_list, server->id_entry);
620 /* Delete all channels */
621 if (silc_idcache_get_all(server->local_list->channels, &list)) {
622 silc_list_start(list);
623 while ((cache = silc_list_get(list)))
624 silc_idlist_del_channel(server->local_list, cache->context);
626 if (silc_idcache_get_all(server->global_list->channels, &list)) {
627 silc_list_start(list);
628 while ((cache = silc_list_get(list)))
629 silc_idlist_del_channel(server->global_list, cache->context);
632 /* Delete all clients */
633 if (silc_idcache_get_all(server->local_list->clients, &list)) {
634 silc_list_start(list);
635 while ((cache = silc_list_get(list))) {
636 silc_schedule_task_del_by_context(server->schedule, cache->context);
637 silc_idlist_del_client(server->local_list, cache->context);
640 if (silc_idcache_get_all(server->global_list->clients, &list)) {
641 silc_list_start(list);
642 while ((cache = silc_list_get(list))) {
643 silc_schedule_task_del_by_context(server->schedule, cache->context);
644 silc_idlist_del_client(server->global_list, cache->context);
648 /* Delete all servers */
649 if (silc_idcache_get_all(server->local_list->servers, &list)) {
650 silc_list_start(list);
651 while ((cache = silc_list_get(list))) {
652 idata = (SilcIDListData)cache->context;
654 silc_schedule_task_del_by_context(server->schedule,
656 silc_idlist_del_server(server->local_list, cache->context);
659 if (silc_idcache_get_all(server->global_list->servers, &list)) {
660 while ((cache = silc_list_get(list))) {
661 idata = (SilcIDListData)cache->context;
663 silc_schedule_task_del_by_context(server->schedule,
665 silc_idlist_del_server(server->global_list, cache->context);
669 silc_idcache_free(server->local_list->clients);
670 silc_idcache_free(server->local_list->servers);
671 silc_idcache_free(server->local_list->channels);
672 silc_idcache_free(server->global_list->clients);
673 silc_idcache_free(server->global_list->servers);
674 silc_idcache_free(server->global_list->channels);
675 silc_hash_table_free(server->watcher_list);
676 silc_hash_table_free(server->watcher_list_pk);
677 silc_hash_free(server->md5hash);
678 silc_hash_free(server->sha1hash);
680 silc_dlist_uninit(server->listeners);
681 silc_dlist_uninit(server->conns);
682 silc_dlist_uninit(server->expired_clients);
683 silc_skr_free(server->repository);
684 silc_packet_engine_stop(server->packet_engine);
686 silc_schedule_task_del_by_context(server->schedule, server);
687 silc_schedule_uninit(server->schedule);
688 server->schedule = NULL;
690 silc_free(server->local_list);
691 silc_free(server->global_list);
692 silc_free(server->server_name);
695 silc_hmac_unregister_all();
696 silc_hash_unregister_all();
697 silc_cipher_unregister_all();
698 silc_pkcs_unregister_all();
701 /* Creates a new server listener. */
703 static SilcNetListener
704 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
706 SilcNetListener listener;
709 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
710 server->config->require_reverse_lookup,
712 silc_server_accept_new_connection, server);
714 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
722 /* Adds a secondary listener. */
724 SilcBool silc_server_init_secondary(SilcServer server)
726 SilcServerConfigServerInfoInterface *interface;
727 SilcNetListener listener;
729 for (interface = server->config->server_info->secondary; interface;
730 interface = interface->next) {
731 listener = silc_server_listen(server, interface->server_ip,
735 silc_dlist_add(server->listeners, listener);
741 /* Initializes the entire SILC server. This is called always before running
742 the server. This is called only once at the initialization of the program.
743 This binds the server to its listenning port. After this function returns
744 one should call silc_server_run to start the server. This returns TRUE
745 when everything is ok to run the server. Configuration file must be
746 read and parsed before calling this. */
748 SilcBool silc_server_init(SilcServer server)
751 SilcServerEntry id_entry;
752 SilcNetListener listener;
756 SILC_LOG_DEBUG(("Initializing server"));
758 server->starttime = time(NULL);
760 /* Take config object for us */
761 silc_server_config_ref(&server->config_ref, server->config,
765 /* Set debugging on if configured */
766 if (server->config->debug_string) {
767 silc_log_debug(TRUE);
768 silc_log_set_debug_string(server->config->debug_string);
770 #endif /* SILC_DEBUG */
772 /* Steal public and private key from the config object */
773 server->public_key = server->config->server_info->public_key;
774 server->private_key = server->config->server_info->private_key;
775 server->config->server_info->public_key = NULL;
776 server->config->server_info->private_key = NULL;
778 /* Register all configured ciphers, PKCS and hash functions. */
779 if (!silc_server_config_register_ciphers(server))
780 silc_cipher_register_default();
781 if (!silc_server_config_register_pkcs(server))
782 silc_pkcs_register_default();
783 if (!silc_server_config_register_hashfuncs(server))
784 silc_hash_register_default();
785 if (!silc_server_config_register_hmacs(server))
786 silc_hmac_register_default();
788 /* Initialize random number generator for the server. */
789 server->rng = silc_rng_alloc();
790 silc_rng_init(server->rng);
791 silc_rng_global_init(server->rng);
793 /* Initialize hash functions for server to use */
794 silc_hash_alloc("md5", &server->md5hash);
795 silc_hash_alloc("sha1", &server->sha1hash);
797 /* Initialize the scheduler */
798 server->schedule = silc_schedule_init(server->config->param.connections_max,
800 if (!server->schedule)
803 /* First, register log files configuration for error output */
804 silc_server_config_setlogfiles(server);
806 /* Initialize ID caches */
807 server->local_list->clients =
808 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
810 server->local_list->servers =
811 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
813 server->local_list->channels =
814 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
817 /* These are allocated for normal server as well as these hold some
818 global information that the server has fetched from its router. For
819 router these are used as they are supposed to be used on router. */
820 server->global_list->clients =
821 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
823 server->global_list->servers =
824 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
826 server->global_list->channels =
827 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
830 /* Init watcher lists */
831 server->watcher_list =
832 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
833 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
835 if (!server->watcher_list)
837 server->watcher_list_pk =
838 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
839 silc_hash_public_key_compare, NULL,
841 if (!server->watcher_list_pk)
844 /* Create TCP listener */
845 listener = silc_server_listen(
847 server->config->server_info->primary == NULL ? NULL :
848 server->config->server_info->primary->server_ip,
849 server->config->server_info->primary == NULL ? 0 :
850 server->config->server_info->primary->port);
853 silc_dlist_add(server->listeners, listener);
855 /* Create a Server ID for the server. */
856 port = silc_net_listener_get_port(listener, NULL);
857 ip = silc_net_listener_get_ip(listener, NULL);
858 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
859 server->config->server_info->primary->public_ip :
860 ip[0], port[0], server->rng, &id);
869 server->server_name = server->config->server_info->server_name;
870 server->config->server_info->server_name = NULL;
871 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
872 sizeof(server->id_string), &server->id_string_len);
874 /* Add ourselves to the server list. We don't have a router yet
875 beacuse we haven't established a route yet. It will be done later.
876 For now, NULL is sent as router. This allocates new entry to
879 silc_idlist_add_server(server->local_list, strdup(server->server_name),
881 silc_id_dup(server->id, SILC_ID_SERVER),
884 SILC_LOG_ERROR(("Could not add local server to cache"));
887 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
888 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
889 SILC_CONN_SERVER : SILC_CONN_ROUTER);
890 server->id_entry = id_entry;
892 /* Create secondary TCP listeners */
893 if (silc_server_init_secondary(server) == FALSE)
896 server->listenning = TRUE;
898 /* Create connections to configured routers. */
899 silc_server_create_connections(server);
901 /* If server connections has been configured then we must be router as
902 normal server cannot have server connections, only router connections. */
903 if (server->config->servers) {
904 SilcServerConfigServer *ptr = server->config->servers;
906 server->server_type = SILC_ROUTER;
908 if (ptr->backup_router) {
909 server->server_type = SILC_BACKUP_ROUTER;
910 server->backup_router = TRUE;
911 server->id_entry->server_type = SILC_BACKUP_ROUTER;
918 /* If we are normal server we'll retrieve network statisticial information
919 once in a while from the router. */
920 if (server->server_type != SILC_ROUTER)
921 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
924 if (server->server_type == SILC_ROUTER)
925 server->stat.routers++;
927 /* Start packet engine */
928 server->packet_engine =
929 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
930 &silc_server_stream_cbs, server);
931 if (!server->packet_engine)
934 /* Register client entry expiration timeout */
935 silc_schedule_task_add_timeout(server->schedule,
936 silc_server_purge_expired_clients, server,
939 /* Initialize HTTP server */
940 silc_server_http_init(server);
942 SILC_LOG_DEBUG(("Server initialized"));
944 /* We are done here, return succesfully */
948 silc_server_config_unref(&server->config_ref);
952 /* Task callback to close a socket connection after rehash */
954 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
956 SilcServer server = app_context;
957 SilcPacketStream sock = context;
958 SilcIDListData idata = silc_packet_get_context(sock);
959 const char *hostname;
962 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
963 NULL, &hostname, NULL, &port);
965 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
966 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
967 silc_schedule_task_del_by_context(server->schedule, sock);
968 silc_server_disconnect_remote(server, sock,
969 SILC_STATUS_ERR_BANNED_FROM_SERVER,
970 "This connection is removed from "
972 silc_server_free_sock_user_data(server, sock, NULL);
975 /* This function basically reads the config file again and switches the config
976 object pointed by the server object. After that, we have to fix various
977 things such as the server_name and the listening ports.
978 Keep in mind that we no longer have the root privileges at this point. */
980 SilcBool silc_server_rehash(SilcServer server)
982 SilcServerConfig newconfig;
984 SILC_LOG_INFO(("Rehashing server"));
986 /* Reset the logging system */
987 silc_log_quick(TRUE);
988 silc_log_flush_all();
990 /* Start the main rehash phase (read again the config file) */
991 newconfig = silc_server_config_alloc(server->config_file, server);
993 SILC_LOG_ERROR(("Rehash FAILED."));
997 /* Fix the server_name field */
998 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
999 silc_free(server->server_name);
1001 /* Check server name */
1002 server->server_name =
1003 silc_identifier_check(newconfig->server_info->server_name,
1004 strlen(newconfig->server_info->server_name),
1005 SILC_STRING_LOCALE, 256, NULL);
1006 if (!server->server_name) {
1007 SILC_LOG_ERROR(("Malformed server name string '%s'",
1008 server->config->server_info->server_name));
1012 /* Update the idcache list with a fresh pointer */
1013 silc_free(server->id_entry->server_name);
1014 server->id_entry->server_name = strdup(server->server_name);
1015 silc_idcache_update_by_context(server->local_list->servers,
1016 server->id_entry, NULL,
1017 strdup(server->id_entry->server_name),
1022 silc_server_config_setlogfiles(server);
1024 /* Change new key pair if necessary */
1025 if (newconfig->server_info->public_key &&
1026 !silc_pkcs_public_key_compare(server->public_key,
1027 newconfig->server_info->public_key)) {
1028 silc_pkcs_public_key_free(server->public_key);
1029 silc_pkcs_private_key_free(server->private_key);
1030 server->public_key = newconfig->server_info->public_key;
1031 server->private_key = newconfig->server_info->private_key;
1032 newconfig->server_info->public_key = NULL;
1033 newconfig->server_info->private_key = NULL;
1036 /* Check for unconfigured server and router connections and close
1037 connections that were unconfigured. */
1039 if (server->config->routers) {
1040 SilcServerConfigRouter *ptr;
1041 SilcServerConfigRouter *newptr;
1044 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1047 /* Check whether new config has this one too */
1048 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1049 if (silc_string_compare(newptr->host, ptr->host) &&
1050 newptr->port == ptr->port &&
1051 newptr->initiator == ptr->initiator) {
1057 if (!found && ptr->host) {
1058 /* Remove this connection */
1059 SilcPacketStream sock;
1060 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1061 ptr->host, ptr->port);
1063 silc_schedule_task_add_timeout(server->schedule,
1064 silc_server_rehash_close_connection,
1070 if (server->config->servers) {
1071 SilcServerConfigServer *ptr;
1072 SilcServerConfigServer *newptr;
1075 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1078 /* Check whether new config has this one too */
1079 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1080 if (silc_string_compare(newptr->host, ptr->host)) {
1086 if (!found && ptr->host) {
1087 /* Remove this connection */
1088 SilcPacketStream sock;
1089 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1092 silc_schedule_task_add_timeout(server->schedule,
1093 silc_server_rehash_close_connection,
1099 if (server->config->clients) {
1100 SilcServerConfigClient *ptr;
1101 SilcServerConfigClient *newptr;
1104 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1107 /* Check whether new config has this one too */
1108 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1109 if (silc_string_compare(newptr->host, ptr->host)) {
1115 if (!found && ptr->host) {
1116 /* Remove this connection */
1117 SilcPacketStream sock;
1118 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1121 silc_schedule_task_add_timeout(server->schedule,
1122 silc_server_rehash_close_connection,
1128 /* Create connections after rehash */
1129 silc_server_create_connections(server);
1131 /* Check whether our router status has changed */
1132 if (newconfig->servers) {
1133 SilcServerConfigServer *ptr = newconfig->servers;
1135 server->server_type = SILC_ROUTER;
1137 if (ptr->backup_router) {
1138 server->server_type = SILC_BACKUP_ROUTER;
1139 server->backup_router = TRUE;
1140 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1147 /* Our old config is gone now. We'll unreference our reference made in
1148 silc_server_init and then destroy it since we are destroying it
1149 underneath the application (layer which called silc_server_init). */
1150 silc_server_config_unref(&server->config_ref);
1151 silc_server_config_destroy(server->config);
1153 /* Take new config context */
1154 server->config = newconfig;
1155 silc_server_config_ref(&server->config_ref, server->config, server->config);
1158 /* Set debugging on if configured */
1159 if (server->config->debug_string) {
1160 silc_log_debug(TRUE);
1161 silc_log_set_debug_string(server->config->debug_string);
1163 #endif /* SILC_DEBUG */
1165 SILC_LOG_DEBUG(("Server rehashed"));
1170 /* The heart of the server. This runs the scheduler thus runs the server.
1171 When this returns the server has been stopped and the program will
1174 void silc_server_run(SilcServer server)
1176 SILC_LOG_INFO(("SILC Server started"));
1178 /* Start the scheduler, the heart of the SILC server. When this returns
1179 the program will be terminated. */
1180 silc_schedule(server->schedule);
1183 /* Stops the SILC server. This function is used to shutdown the server.
1184 This is usually called after the scheduler has returned. After stopping
1185 the server one should call silc_server_free. */
1187 void silc_server_stop(SilcServer server)
1190 SilcPacketStream ps;
1191 SilcNetListener listener;
1193 SILC_LOG_INFO(("SILC Server shutting down"));
1195 server->server_shutdown = TRUE;
1197 /* Close all connections */
1198 if (server->packet_engine) {
1199 list = silc_packet_engine_get_streams(server->packet_engine);
1201 silc_dlist_start(list);
1202 while ((ps = silc_dlist_get(list))) {
1203 SilcIDListData idata = silc_packet_get_context(ps);
1206 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1208 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1209 "Server is shutting down");
1210 silc_server_free_sock_user_data(server, ps,
1211 "Server is shutting down");
1213 silc_packet_engine_free_streams_list(list);
1216 /* We are not connected to network anymore */
1217 server->standalone = TRUE;
1219 silc_dlist_start(server->listeners);
1220 while ((listener = silc_dlist_get(server->listeners)))
1221 silc_net_close_listener(listener);
1223 silc_server_http_uninit(server);
1225 /* Cancel any possible retry timeouts */
1226 silc_schedule_task_del_by_callback(server->schedule,
1227 silc_server_connect_router);
1228 silc_schedule_task_del_by_callback(server->schedule,
1229 silc_server_connect_to_router_retry);
1231 silc_schedule_stop(server->schedule);
1233 SILC_LOG_DEBUG(("Server stopped"));
1236 /* Purge expired client entries from the server */
1238 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1240 SilcServer server = context;
1241 SilcClientEntry client;
1243 SilcUInt64 curtime = silc_time();
1245 SILC_LOG_DEBUG(("Expire timeout"));
1247 silc_dlist_start(server->expired_clients);
1248 while ((client = silc_dlist_get(server->expired_clients))) {
1249 if (client->data.status & SILC_IDLIST_STATUS_REGISTERED)
1252 /* For unregistered clients the created timestamp is actually
1253 unregistered timestamp. Make sure client remains in history
1254 at least 500 seconds. */
1255 if (curtime - client->data.created < 500)
1258 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1259 server->local_list : server->global_list);
1261 silc_idlist_del_data(client);
1262 silc_idlist_del_client(id_list, client);
1263 silc_dlist_del(server->expired_clients, client);
1266 silc_schedule_task_add_timeout(server->schedule,
1267 silc_server_purge_expired_clients, server,
1272 /******************************* Connecting *********************************/
1274 /* Free connection context */
1276 void silc_server_connection_free(SilcServerConnection sconn)
1278 SILC_LOG_DEBUG(("Free connection %p", sconn));
1279 silc_dlist_del(sconn->server->conns, sconn);
1280 silc_server_config_unref(&sconn->conn);
1281 silc_free(sconn->remote_host);
1282 silc_free(sconn->backup_replace_ip);
1286 /* Creates connection to a remote router. */
1288 void silc_server_create_connection(SilcServer server,
1291 const char *remote_host, SilcUInt32 port,
1292 SilcServerConnectCallback callback,
1295 SilcServerConnection sconn;
1297 /* Allocate connection object for hold connection specific stuff. */
1298 sconn = silc_calloc(1, sizeof(*sconn));
1301 sconn->remote_host = strdup(remote_host);
1302 sconn->remote_port = port;
1303 sconn->no_reconnect = reconnect == FALSE;
1304 sconn->callback = callback;
1305 sconn->callback_context = context;
1306 sconn->no_conf = dynamic;
1307 sconn->server = server;
1309 SILC_LOG_DEBUG(("Created connection %p", sconn));
1311 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1315 /* Connection authentication completion callback */
1318 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1321 SilcServerConnection sconn = context;
1322 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1323 SilcServer server = entry->server;
1324 SilcServerConfigServer *conn;
1325 SilcServerConfigConnParams *param;
1326 SilcIDListData idata;
1327 SilcServerEntry id_entry = NULL;
1328 unsigned char id[32];
1333 SILC_LOG_DEBUG(("Connection authentication completed"));
1337 if (success == FALSE) {
1338 /* Authentication failed */
1339 /* XXX retry connecting */
1341 silc_server_disconnect_remote(server, sconn->sock,
1342 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1343 if (sconn->callback)
1344 (*sconn->callback)(server, NULL, sconn->callback_context);
1345 silc_server_connection_free(sconn);
1349 /* XXX For now remote is router always */
1350 entry->data.conn_type = SILC_CONN_ROUTER;
1352 SILC_LOG_INFO(("Connected to %s %s",
1353 SILC_CONNTYPE_STRING(entry->data.conn_type),
1354 sconn->remote_host));
1356 /* Create the actual entry for remote entity */
1357 switch (entry->data.conn_type) {
1358 case SILC_CONN_SERVER:
1359 SILC_LOG_DEBUG(("Remote is SILC server"));
1361 /* Add new server. The server must register itself to us before it
1362 becomes registered to SILC network. */
1363 id_entry = silc_idlist_add_server(server->local_list,
1364 strdup(sconn->remote_host),
1365 SILC_SERVER, NULL, NULL, sconn->sock);
1367 silc_server_disconnect_remote(server, sconn->sock,
1368 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1369 if (sconn->callback)
1370 (*sconn->callback)(server, NULL, sconn->callback_context);
1371 silc_server_connection_free(sconn);
1376 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1379 case SILC_CONN_ROUTER:
1380 SILC_LOG_DEBUG(("Remote is SILC router"));
1382 /* Register to network */
1383 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1384 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1385 SILC_STR_UI_SHORT(id_len),
1386 SILC_STR_DATA(id, id_len),
1387 SILC_STR_UI_SHORT(strlen(server->server_name)),
1388 SILC_STR_DATA(server->server_name,
1389 strlen(server->server_name)),
1391 silc_server_disconnect_remote(server, sconn->sock,
1392 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1393 if (sconn->callback)
1394 (*sconn->callback)(server, NULL, sconn->callback_context);
1395 silc_server_connection_free(sconn);
1401 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1403 /* Check that we do not have this ID already */
1404 id_entry = silc_idlist_find_server_by_id(server->local_list,
1405 &remote_id.u.server_id,
1408 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1410 id_entry = silc_idlist_find_server_by_id(server->global_list,
1411 &remote_id.u.server_id,
1414 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1418 SILC_LOG_DEBUG(("New server id(%s)",
1419 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1421 /* Add the connected router to global server list. Router is sent
1422 as NULL since it's local to us. */
1423 id_entry = silc_idlist_add_server(server->global_list,
1424 strdup(sconn->remote_host),
1426 silc_id_dup(&remote_id.u.server_id,
1430 silc_server_disconnect_remote(server, sconn->sock,
1431 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1432 if (sconn->callback)
1433 (*sconn->callback)(server, NULL, sconn->callback_context);
1434 silc_server_connection_free(sconn);
1440 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1441 idata = (SilcIDListData)id_entry;
1442 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1443 SILC_IDLIST_STATUS_LOCAL);
1444 idata->sconn = sconn;
1446 if (!sconn->backup) {
1447 /* Mark this router our primary router if we're still standalone */
1448 if (server->standalone) {
1449 SILC_LOG_DEBUG(("This connection is our primary router"));
1450 server->id_entry->router = id_entry;
1451 server->router = id_entry;
1452 server->router->server_type = SILC_ROUTER;
1453 server->standalone = FALSE;
1454 server->backup_primary = FALSE;
1456 /* Announce data if we are not backup router (unless not as primary
1457 currently). Backup router announces later at the end of
1458 resuming protocol. */
1459 if (server->backup_router && server->server_type == SILC_ROUTER) {
1460 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1462 /* If we are router then announce our possible servers. Backup
1463 router announces also global servers. */
1464 if (server->server_type == SILC_ROUTER)
1465 silc_server_announce_servers(server,
1466 server->backup_router ? TRUE : FALSE,
1467 0, SILC_PRIMARY_ROUTE(server));
1469 /* Announce our clients and channels to the router */
1470 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1471 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1474 /* If we are backup router then this primary router is whom we are
1476 if (server->server_type == SILC_BACKUP_ROUTER) {
1477 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1479 NULL, NULL, &ip, NULL);
1480 silc_server_backup_add(server, server->id_entry, ip,
1481 sconn->remote_port, TRUE);
1485 /* We already have primary router. Disconnect this connection */
1486 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1487 silc_idlist_del_server(server->global_list, id_entry);
1488 silc_server_disconnect_remote(server, sconn->sock,
1489 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1490 if (sconn->callback)
1491 (*sconn->callback)(server, NULL, sconn->callback_context);
1492 silc_server_connection_free(sconn);
1498 /* Add this server to be our backup router */
1499 id_entry->server_type = SILC_BACKUP_ROUTER;
1500 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1501 sconn->backup_replace_port, FALSE);
1507 silc_server_disconnect_remote(server, sconn->sock,
1508 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1509 if (sconn->callback)
1510 (*sconn->callback)(server, NULL, sconn->callback_context);
1511 silc_server_connection_free(sconn);
1516 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1518 conn = sconn->conn.ref_ptr;
1519 param = &server->config->param;
1520 if (conn && conn->param)
1521 param = conn->param;
1523 /* Register rekey timeout */
1524 sconn->rekey_timeout = param->key_exchange_rekey;
1525 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1526 sconn->sock, sconn->rekey_timeout, 0);
1528 /* Set the entry as packet stream context */
1529 silc_packet_set_context(sconn->sock, id_entry);
1532 /* Call the completion callback to indicate that we've connected to
1534 if (sconn && sconn->callback)
1535 (*sconn->callback)(server, id_entry, sconn->callback_context);
1537 if (sconn == server->router_conn)
1538 server->router_conn = NULL;
1543 /* SKE completion callback */
1545 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1546 SilcSKESecurityProperties prop,
1547 SilcSKEKeyMaterial keymat,
1548 SilcSKERekeyMaterial rekey,
1551 SilcPacketStream sock = context;
1552 SilcUnknownEntry entry = silc_packet_get_context(sock);
1553 SilcServerConnection sconn = silc_ske_get_context(ske);
1554 SilcServer server = entry->server;
1555 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1556 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1557 void *auth_data = NULL;
1558 SilcUInt32 auth_data_len = 0;
1559 SilcConnAuth connauth;
1560 SilcCipher send_key, receive_key;
1561 SilcHmac hmac_send, hmac_receive;
1566 if (status != SILC_SKE_STATUS_OK) {
1568 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1569 silc_ske_map_status(status), entry->hostname, entry->ip));
1571 /* XXX retry connecting */
1573 silc_server_disconnect_remote(server, sconn->sock,
1574 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1575 if (sconn->callback)
1576 (*sconn->callback)(server, NULL, sconn->callback_context);
1577 silc_server_connection_free(sconn);
1581 SILC_LOG_DEBUG(("Setting keys into use"));
1583 /* Set the keys into use. The data will be encrypted after this. */
1584 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1585 &hmac_send, &hmac_receive, &hash)) {
1587 /* XXX retry connecting */
1589 /* Error setting keys */
1591 silc_server_disconnect_remote(server, sconn->sock,
1592 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1593 if (sconn->callback)
1594 (*sconn->callback)(server, NULL, sconn->callback_context);
1595 silc_server_connection_free(sconn);
1598 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1599 hmac_receive, FALSE);
1601 SILC_LOG_DEBUG(("Starting connection authentication"));
1603 connauth = silc_connauth_alloc(server->schedule, ske,
1604 server->config->conn_auth_timeout);
1606 /* XXX retry connecting */
1608 /** Error allocating auth protocol */
1610 silc_server_disconnect_remote(server, sconn->sock,
1611 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1612 if (sconn->callback)
1613 (*sconn->callback)(server, NULL, sconn->callback_context);
1614 silc_server_connection_free(sconn);
1618 /* Get authentication method */
1620 if (conn->passphrase) {
1621 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1622 auth_meth = SILC_AUTH_PUBLIC_KEY;
1623 auth_data = server->private_key;
1625 auth_meth = SILC_AUTH_PASSWORD;
1626 auth_data = conn->passphrase;
1627 auth_data_len = conn->passphrase_len;
1630 auth_meth = SILC_AUTH_PUBLIC_KEY;
1631 auth_data = server->private_key;
1635 entry->data.rekey = rekey;
1637 /* Start connection authentication */
1639 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1640 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1641 auth_data, auth_data_len,
1642 silc_server_ke_auth_compl, sconn);
1645 /* Function that is called when the network connection to a router has
1646 been established. This will continue with the key exchange protocol
1647 with the remote router. */
1649 void silc_server_start_key_exchange(SilcServerConnection sconn)
1651 SilcServer server = sconn->server;
1652 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1653 SilcUnknownEntry entry;
1654 SilcSKEParamsStruct params;
1657 /* Cancel any possible retry timeouts */
1658 silc_schedule_task_del_by_context(server->schedule, sconn);
1660 /* Create packet stream */
1661 sconn->sock = silc_packet_stream_create(server->packet_engine,
1662 server->schedule, sconn->stream);
1664 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1665 silc_stream_destroy(sconn->stream);
1666 if (sconn->callback)
1667 (*sconn->callback)(server, NULL, sconn->callback_context);
1668 silc_server_connection_free(sconn);
1671 server->stat.conn_num++;
1673 /* Set source ID to packet stream */
1674 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1676 silc_packet_stream_destroy(sconn->sock);
1677 if (sconn->callback)
1678 (*sconn->callback)(server, NULL, sconn->callback_context);
1679 silc_server_connection_free(sconn);
1683 /* Create entry for remote entity */
1684 entry = silc_calloc(1, sizeof(*entry));
1686 silc_packet_stream_destroy(sconn->sock);
1687 silc_server_connection_free(sconn);
1690 entry->server = server;
1691 silc_packet_set_context(sconn->sock, entry);
1693 /* Set Key Exchange flags from configuration, but fall back to global
1695 memset(¶ms, 0, sizeof(params));
1696 SILC_GET_SKE_FLAGS(conn, params.flags);
1697 if (server->config->param.key_exchange_pfs)
1698 params.flags |= SILC_SKE_SP_FLAG_PFS;
1700 /* Start SILC Key Exchange protocol */
1701 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1702 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1703 server->public_key, server->private_key, sconn);
1706 silc_packet_stream_destroy(sconn->sock);
1707 if (sconn->callback)
1708 (*sconn->callback)(server, NULL, sconn->callback_context);
1709 silc_server_connection_free(sconn);
1712 silc_ske_set_callbacks(ske, silc_server_verify_key,
1713 silc_server_ke_completed, sconn->sock);
1715 /* Start key exchange protocol */
1716 params.version = silc_version_string;
1717 params.timeout_secs = server->config->key_exchange_timeout;
1718 sconn->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1721 /* Timeout callback that will be called to retry connecting to remote
1722 router. This is used by both normal and router server. This will wait
1723 before retrying the connecting. The timeout is generated by exponential
1724 backoff algorithm. */
1726 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1728 SilcServerConnection sconn = context;
1729 SilcServer server = sconn->server;
1730 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1731 SilcServerConfigConnParams *param =
1732 (conn->param ? conn->param : &server->config->param);
1734 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1735 sconn->remote_port));
1737 /* Calculate next timeout */
1738 if (sconn->retry_count >= 1) {
1739 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1740 if (sconn->retry_timeout > param->reconnect_interval_max)
1741 sconn->retry_timeout = param->reconnect_interval_max;
1743 sconn->retry_timeout = param->reconnect_interval;
1745 sconn->retry_count++;
1746 sconn->retry_timeout = sconn->retry_timeout +
1747 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1749 /* If we've reached max retry count, give up. */
1750 if ((sconn->retry_count > param->reconnect_count) &&
1751 !param->reconnect_keep_trying) {
1752 SILC_LOG_ERROR(("Could not connect, giving up"));
1754 if (sconn->callback)
1755 (*sconn->callback)(server, NULL, sconn->callback_context);
1756 silc_server_connection_free(sconn);
1760 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1762 /* We will lookup a fresh pointer later */
1763 silc_server_config_unref(&sconn->conn);
1765 /* Wait before retrying */
1766 silc_schedule_task_del_by_context(server->schedule, sconn);
1767 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1768 sconn, sconn->retry_timeout, 0);
1771 /* Callback for async connection to remote router */
1773 static void silc_server_connection_established(SilcNetStatus status,
1777 SilcServerConnection sconn = context;
1778 SilcServer server = sconn->server;
1780 silc_schedule_task_del_by_context(server->schedule, sconn);
1785 SILC_LOG_DEBUG(("Connection to %s:%d established",
1786 sconn->remote_host, sconn->remote_port));
1788 /* Continue with key exchange protocol */
1789 sconn->stream = stream;
1790 silc_server_start_key_exchange(sconn);
1793 case SILC_NET_UNKNOWN_IP:
1794 case SILC_NET_UNKNOWN_HOST:
1795 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1796 sconn->remote_host, sconn->remote_port,
1797 silc_net_get_error_string(status)));
1799 if (sconn->callback)
1800 (*sconn->callback)(server, NULL, sconn->callback_context);
1801 silc_server_connection_free(sconn);
1805 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1806 sconn->remote_host, sconn->remote_port,
1807 silc_net_get_error_string(status)));
1808 if (!sconn->no_reconnect) {
1809 silc_schedule_task_add_timeout(sconn->server->schedule,
1810 silc_server_connect_to_router_retry,
1812 silc_dlist_del(server->conns, sconn);
1814 if (sconn->callback)
1815 (*sconn->callback)(server, NULL, sconn->callback_context);
1816 silc_server_connection_free(sconn);
1822 /* Generic routine to use connect to a router. */
1824 SILC_TASK_CALLBACK(silc_server_connect_router)
1826 SilcServerConnection sconn = context;
1827 SilcServer server = sconn->server;
1828 SilcServerConfigRouter *rconn;
1830 silc_schedule_task_del_by_context(server->schedule, sconn);
1832 /* Don't connect if we are shutting down. */
1833 if (server->server_shutdown) {
1834 if (sconn->callback)
1835 (*sconn->callback)(server, NULL, sconn->callback_context);
1836 silc_server_connection_free(sconn);
1840 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1841 (sconn->backup ? "backup router" : "router"),
1842 sconn->remote_host, sconn->remote_port));
1844 if (!sconn->no_conf) {
1845 /* Find connection configuration */
1846 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1847 sconn->remote_port);
1849 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1850 (sconn->backup ? "backup router" : "router"),
1851 sconn->remote_host, sconn->remote_port));
1852 silc_server_connection_free(sconn);
1855 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1858 /* Connect to remote host */
1860 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1861 server->config->server_info->primary->server_ip),
1862 sconn->remote_host, sconn->remote_port,
1863 server->schedule, silc_server_connection_established,
1866 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1867 sconn->remote_host, sconn->remote_port));
1868 silc_server_connection_free(sconn);
1872 /* Add to connection list */
1873 silc_dlist_add(server->conns, sconn);
1876 /* This function connects to our primary router or if we are a router this
1877 establishes all our primary routes. This is called at the start of the
1878 server to do authentication and key exchange with our router - called
1881 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1883 SilcServer server = context;
1884 SilcServerConnection sconn;
1885 SilcServerConfigRouter *ptr;
1887 /* Don't connect if we are shutting down. */
1888 if (server->server_shutdown)
1891 SILC_LOG_DEBUG(("We are %s",
1892 (server->server_type == SILC_SERVER ?
1893 "normal server" : server->server_type == SILC_ROUTER ?
1894 "router" : "backup router/normal server")));
1896 if (!server->config->routers) {
1897 /* There wasn't a configured router, we will continue but we don't
1898 have a connection to outside world. We will be standalone server. */
1899 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1900 server->standalone = TRUE;
1904 /* Cancel any possible retry timeouts */
1905 silc_schedule_task_del_by_callback(server->schedule,
1906 silc_server_connect_router);
1907 silc_schedule_task_del_by_callback(server->schedule,
1908 silc_server_connect_to_router_retry);
1910 /* Create the connections to all our routes */
1911 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1913 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1914 ptr->backup_router ? "Backup router" : "Router",
1915 ptr->initiator ? "Initiator" : "Responder",
1916 ptr->host, ptr->port));
1918 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1919 ptr->initiator == FALSE && !server->backup_router &&
1920 !silc_server_config_get_backup_router(server))
1921 server->wait_backup = TRUE;
1923 if (!ptr->initiator)
1925 if (ptr->dynamic_connection)
1928 /* Check whether we are connecting or connected to this host already */
1929 if (silc_server_num_sockets_by_remote(server,
1930 silc_net_is_ip(ptr->host) ?
1932 silc_net_is_ip(ptr->host) ?
1933 NULL : ptr->host, ptr->port,
1934 SILC_CONN_ROUTER)) {
1935 SILC_LOG_DEBUG(("We are already connected to %s:%d",
1936 ptr->host, ptr->port));
1938 /* If we don't have primary router and this connection is our
1939 primary router we are in desync. Reconnect to the primary. */
1940 if (server->standalone && !server->router) {
1942 SilcPacketStream sock;
1943 SilcServerConfigRouter *primary =
1944 silc_server_config_get_primary_router(server);
1947 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1948 ptr->host, ptr->port);
1951 server->backup_noswitch = TRUE;
1952 silc_server_free_sock_user_data(server, sock, NULL);
1953 silc_server_disconnect_remote(server, sock, 0, NULL);
1954 server->backup_noswitch = FALSE;
1955 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1961 /* Allocate connection object for hold connection specific stuff. */
1962 sconn = silc_calloc(1, sizeof(*sconn));
1965 sconn->server = server;
1966 sconn->remote_host = strdup(ptr->host);
1967 sconn->remote_port = ptr->port;
1968 sconn->backup = ptr->backup_router;
1969 if (sconn->backup) {
1970 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1971 sconn->backup_replace_port = ptr->backup_replace_port;
1974 SILC_LOG_DEBUG(("Created connection %p", sconn));
1976 if (!server->router_conn && !sconn->backup)
1977 server->router_conn = sconn;
1980 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
1986 /************************ Accepting new connection **************************/
1988 /* After this is called, server don't wait for backup router anymore.
1989 This gets called automatically even after we have backup router
1990 connection established. */
1992 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
1994 SilcServer server = context;
1995 server->wait_backup = FALSE;
1998 /* Authentication data callback */
2001 silc_server_accept_get_auth(SilcConnAuth connauth,
2002 SilcConnectionType conn_type,
2003 unsigned char **passphrase,
2004 SilcUInt32 *passphrase_len,
2005 SilcSKR *repository,
2008 SilcPacketStream sock = context;
2009 SilcUnknownEntry entry = silc_packet_get_context(sock);
2010 SilcServer server = entry->server;
2012 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2014 /* Remote end is client */
2015 if (conn_type == SILC_CONN_CLIENT) {
2016 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2020 *passphrase = cconfig->passphrase;
2021 *passphrase_len = cconfig->passphrase_len;
2022 if (cconfig->publickeys)
2023 *repository = server->repository;
2025 entry->data.conn_type = conn_type;
2029 /* Remote end is server */
2030 if (conn_type == SILC_CONN_SERVER) {
2031 SilcServerConfigServer *sconfig;
2033 /* If we are normal server, don't accept the connection */
2034 if (server->server_type == SILC_SERVER)
2037 sconfig = entry->sconfig.ref_ptr;
2041 *passphrase = sconfig->passphrase;
2042 *passphrase_len = sconfig->passphrase_len;
2043 if (sconfig->publickeys)
2044 *repository = server->repository;
2046 entry->data.conn_type = conn_type;
2050 /* Remote end is router */
2051 if (conn_type == SILC_CONN_ROUTER) {
2052 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2056 *passphrase = rconfig->passphrase;
2057 *passphrase_len = rconfig->passphrase_len;
2058 if (rconfig->publickeys)
2059 *repository = server->repository;
2061 entry->data.conn_type = conn_type;
2068 /* Authentication completion callback. */
2071 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2074 SilcPacketStream sock = context;
2075 SilcUnknownEntry entry = silc_packet_get_context(sock);
2076 SilcIDListData idata = (SilcIDListData)entry;
2077 SilcServer server = entry->server;
2078 SilcServerConfigConnParams *param = &server->config->param;
2079 SilcServerConnection sconn;
2081 const char *hostname, *ip;
2085 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2086 NULL, &hostname, &ip, &port);
2088 if (success == FALSE) {
2089 /* Authentication failed */
2090 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2091 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2092 server->stat.auth_failures++;
2093 silc_server_disconnect_remote(server, sock,
2094 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2098 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2100 switch (entry->data.conn_type) {
2101 case SILC_CONN_CLIENT:
2103 SilcClientEntry client;
2104 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2106 /* Verify whether this connection is after all allowed to connect */
2107 if (!silc_server_connection_allowed(server, sock, entry->data.conn_type,
2108 &server->config->param,
2110 silc_connauth_get_ske(connauth))) {
2111 server->stat.auth_failures++;
2115 /* If we are primary router and we have backup router configured
2116 but it has not connected to use yet, do not accept any other
2118 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2119 !server->backup_router) {
2120 SilcServerConfigRouter *router;
2121 router = silc_server_config_get_backup_router(server);
2122 if (router && strcmp(server->config->server_info->primary->server_ip,
2124 silc_server_find_socket_by_host(server,
2126 router->backup_replace_ip, 0)) {
2127 SILC_LOG_INFO(("Will not accept connections because we do "
2128 "not have backup router connection established"));
2129 silc_server_disconnect_remote(server, sock,
2130 SILC_STATUS_ERR_PERM_DENIED,
2131 "We do not have connection to backup "
2132 "router established, try later");
2133 server->stat.auth_failures++;
2135 /* From here on, wait 20 seconds for the backup router to appear. */
2136 silc_schedule_task_add_timeout(server->schedule,
2137 silc_server_backup_router_wait,
2138 (void *)server, 20, 0);
2143 SILC_LOG_DEBUG(("Remote host is client"));
2144 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2147 /* Add the client to the client ID cache. The nickname and Client ID
2148 and other information is created after we have received NEW_CLIENT
2149 packet from client. */
2150 client = silc_idlist_add_client(server->local_list,
2151 NULL, NULL, NULL, NULL, NULL, sock);
2153 SILC_LOG_ERROR(("Could not add new client to cache"));
2154 server->stat.auth_failures++;
2155 silc_server_disconnect_remote(server, sock,
2156 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2159 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2162 server->stat.my_clients++;
2163 server->stat.clients++;
2164 server->stat.cell_clients++;
2166 /* Get connection parameters */
2168 param = conn->param;
2170 if (!param->keepalive_secs)
2171 param->keepalive_secs = server->config->param.keepalive_secs;
2173 if (!param->qos && server->config->param.qos) {
2174 param->qos = server->config->param.qos;
2175 param->qos_rate_limit = server->config->param.qos_rate_limit;
2176 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2177 param->qos_limit_sec = server->config->param.qos_limit_sec;
2178 param->qos_limit_usec = server->config->param.qos_limit_usec;
2181 /* Check if to be anonymous connection */
2182 if (param->anonymous)
2183 client->mode |= SILC_UMODE_ANONYMOUS;
2186 /* Add public key to repository */
2187 if (!silc_server_get_public_key_by_client(server, client, NULL))
2188 silc_skr_add_public_key_simple(server->repository,
2189 entry->data.public_key,
2190 SILC_SKR_USAGE_IDENTIFICATION, client,
2193 id_entry = (void *)client;
2197 case SILC_CONN_SERVER:
2198 case SILC_CONN_ROUTER:
2200 SilcServerEntry new_server;
2201 SilcBool initiator = FALSE;
2202 SilcBool backup_local = FALSE;
2203 SilcBool backup_router = FALSE;
2204 char *backup_replace_ip = NULL;
2205 SilcUInt16 backup_replace_port = 0;
2206 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2207 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2209 /* If we are backup router and this is incoming server connection
2210 and we do not have connection to primary router, do not allow
2212 if (server->server_type == SILC_BACKUP_ROUTER &&
2213 entry->data.conn_type == SILC_CONN_SERVER &&
2214 !SILC_PRIMARY_ROUTE(server)) {
2215 SILC_LOG_INFO(("Will not accept server connection because we do "
2216 "not have primary router connection established"));
2217 silc_server_disconnect_remote(server, sock,
2218 SILC_STATUS_ERR_PERM_DENIED,
2219 "We do not have connection to primary "
2220 "router established, try later");
2221 server->stat.auth_failures++;
2225 if (entry->data.conn_type == SILC_CONN_ROUTER) {
2226 /* Verify whether this connection is after all allowed to connect */
2227 if (!silc_server_connection_allowed(server, sock,
2228 entry->data.conn_type,
2229 &server->config->param,
2230 rconn ? rconn->param : NULL,
2231 silc_connauth_get_ske(connauth))) {
2232 server->stat.auth_failures++;
2238 param = rconn->param;
2240 if (!param->keepalive_secs)
2241 param->keepalive_secs = server->config->param.keepalive_secs;
2243 if (!param->qos && server->config->param.qos) {
2244 param->qos = server->config->param.qos;
2245 param->qos_rate_limit = server->config->param.qos_rate_limit;
2246 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2247 param->qos_limit_sec = server->config->param.qos_limit_sec;
2248 param->qos_limit_usec = server->config->param.qos_limit_usec;
2252 initiator = rconn->initiator;
2253 backup_local = rconn->backup_local;
2254 backup_router = rconn->backup_router;
2255 backup_replace_ip = rconn->backup_replace_ip;
2256 backup_replace_port = rconn->backup_replace_port;
2260 if (entry->data.conn_type == SILC_CONN_SERVER) {
2261 /* Verify whether this connection is after all allowed to connect */
2262 if (!silc_server_connection_allowed(server, sock,
2263 entry->data.conn_type,
2264 &server->config->param,
2265 srvconn ? srvconn->param : NULL,
2266 silc_connauth_get_ske(connauth))) {
2267 server->stat.auth_failures++;
2271 if (srvconn->param) {
2272 param = srvconn->param;
2274 if (!param->keepalive_secs)
2275 param->keepalive_secs = server->config->param.keepalive_secs;
2277 if (!param->qos && server->config->param.qos) {
2278 param->qos = server->config->param.qos;
2279 param->qos_rate_limit = server->config->param.qos_rate_limit;
2280 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2281 param->qos_limit_sec = server->config->param.qos_limit_sec;
2282 param->qos_limit_usec = server->config->param.qos_limit_usec;
2286 backup_router = srvconn->backup_router;
2290 /* If we are primary router and we have backup router configured
2291 but it has not connected to use yet, do not accept any other
2293 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2294 !server->backup_router && !backup_router) {
2295 SilcServerConfigRouter *router;
2296 router = silc_server_config_get_backup_router(server);
2297 if (router && strcmp(server->config->server_info->primary->server_ip,
2299 silc_server_find_socket_by_host(server,
2301 router->backup_replace_ip, 0)) {
2302 SILC_LOG_INFO(("Will not accept connections because we do "
2303 "not have backup router connection established"));
2304 silc_server_disconnect_remote(server, sock,
2305 SILC_STATUS_ERR_PERM_DENIED,
2306 "We do not have connection to backup "
2307 "router established, try later");
2308 server->stat.auth_failures++;
2310 /* From here on, wait 20 seconds for the backup router to appear. */
2311 silc_schedule_task_add_timeout(server->schedule,
2312 silc_server_backup_router_wait,
2313 (void *)server, 20, 0);
2318 SILC_LOG_DEBUG(("Remote host is %s",
2319 entry->data.conn_type == SILC_CONN_SERVER ?
2320 "server" : (backup_router ?
2321 "backup router" : "router")));
2322 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2323 entry->ip, entry->data.conn_type == SILC_CONN_SERVER ?
2324 "server" : (backup_router ?
2325 "backup router" : "router")));
2327 /* Add the server into server cache. The server name and Server ID
2328 is updated after we have received NEW_SERVER packet from the
2329 server. We mark ourselves as router for this server if we really
2332 silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ?
2333 server->local_list : (backup_router ?
2334 server->local_list :
2335 server->global_list)),
2337 (entry->data.conn_type == SILC_CONN_SERVER ?
2338 SILC_SERVER : SILC_ROUTER),
2340 (entry->data.conn_type == SILC_CONN_SERVER ?
2341 server->id_entry : (backup_router ?
2342 server->id_entry : NULL)),
2345 SILC_LOG_ERROR(("Could not add new server to cache"));
2346 silc_server_disconnect_remote(server, sock,
2347 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2348 server->stat.auth_failures++;
2351 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2353 id_entry = (void *)new_server;
2355 /* If the incoming connection is router and marked as backup router
2356 then add it to be one of our backups */
2357 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2358 /* Change it back to SERVER type since that's what it really is. */
2360 entry->data.conn_type = SILC_CONN_SERVER;
2361 new_server->server_type = SILC_BACKUP_ROUTER;
2363 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2364 ("Backup router %s is now online",
2367 /* Remove the backup waiting with timeout */
2368 silc_schedule_task_add_timeout(server->schedule,
2369 silc_server_backup_router_wait,
2370 (void *)server, 10, 0);
2374 if (entry->data.conn_type == SILC_CONN_SERVER) {
2375 server->stat.my_servers++;
2376 server->stat.servers++;
2377 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2379 server->stat.my_routers++;
2380 server->stat.routers++;
2381 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2384 /* Check whether this connection is to be our primary router connection
2385 if we do not already have the primary route. */
2386 if (!backup_router &&
2387 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2388 if (silc_server_config_is_primary_route(server) && !initiator)
2391 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2392 server->standalone = FALSE;
2393 if (!server->id_entry->router) {
2394 server->id_entry->router = id_entry;
2395 server->router = id_entry;
2407 /* Add connection to server->conns so that we know we have connection
2409 sconn = silc_calloc(1, sizeof(*sconn));
2410 sconn->server = server;
2412 sconn->remote_host = strdup(hostname);
2413 sconn->remote_port = port;
2414 silc_dlist_add(server->conns, sconn);
2415 idata->sconn = sconn;
2416 idata->last_receive = time(NULL);
2418 /* Add the common data structure to the ID entry. */
2419 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2420 silc_packet_set_context(sock, id_entry);
2422 /* Connection has been fully established now. Everything is ok. */
2423 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2425 /* Perform Quality of Service */
2427 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2428 param->qos_rate_limit, param->qos_bytes_limit,
2429 param->qos_limit_sec, param->qos_limit_usec);
2431 silc_server_config_unref(&entry->cconfig);
2432 silc_server_config_unref(&entry->sconfig);
2433 silc_server_config_unref(&entry->rconfig);
2437 silc_ske_free(silc_connauth_get_ske(connauth));
2438 silc_connauth_free(connauth);
2441 /* SKE completion callback. We set the new keys into use here. */
2444 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2445 SilcSKESecurityProperties prop,
2446 SilcSKEKeyMaterial keymat,
2447 SilcSKERekeyMaterial rekey,
2450 SilcPacketStream sock = context;
2451 SilcUnknownEntry entry = silc_packet_get_context(sock);
2452 SilcIDListData idata = (SilcIDListData)entry;
2453 SilcServer server = entry->server;
2454 SilcConnAuth connauth;
2455 SilcCipher send_key, receive_key;
2456 SilcHmac hmac_send, hmac_receive;
2463 if (status != SILC_SKE_STATUS_OK) {
2465 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2466 silc_ske_map_status(status), entry->hostname, entry->ip));
2468 silc_server_disconnect_remote(server, sock,
2469 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2473 SILC_LOG_DEBUG(("Setting keys into use"));
2475 /* Set the keys into use. The data will be encrypted after this. */
2476 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2477 &hmac_send, &hmac_receive, &hash)) {
2478 /* Error setting keys */
2480 silc_server_disconnect_remote(server, sock,
2481 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2484 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2485 hmac_receive, FALSE);
2487 idata->rekey = rekey;
2488 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2489 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2490 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2492 SILC_LOG_DEBUG(("Starting connection authentication"));
2493 server->stat.auth_attempts++;
2495 connauth = silc_connauth_alloc(server->schedule, ske,
2496 server->config->conn_auth_timeout);
2498 /** Error allocating auth protocol */
2500 silc_server_disconnect_remote(server, sock,
2501 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2505 /* Start connection authentication */
2507 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2508 silc_server_accept_auth_compl, sock);
2511 /* Accept new TCP connection */
2513 static void silc_server_accept_new_connection(SilcNetStatus status,
2517 SilcServer server = context;
2518 SilcPacketStream packet_stream;
2519 SilcServerConfigClient *cconfig = NULL;
2520 SilcServerConfigServer *sconfig = NULL;
2521 SilcServerConfigRouter *rconfig = NULL;
2522 SilcServerConfigDeny *deny;
2523 SilcUnknownEntry entry;
2525 SilcSKEParamsStruct params;
2526 char *hostname, *ip;
2529 SILC_LOG_DEBUG(("Accepting new connection"));
2531 /* Check for maximum allowed connections */
2532 server->stat.conn_attempts++;
2533 if (silc_dlist_count(server->conns) >
2534 server->config->param.connections_max) {
2535 SILC_LOG_ERROR(("Refusing connection, server is full"));
2536 server->stat.conn_failures++;
2537 silc_stream_destroy(stream);
2541 /* Get hostname, IP and port */
2542 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2543 (const char **)&ip, &port)) {
2544 /* Bad socket stream */
2545 server->stat.conn_failures++;
2546 silc_stream_destroy(stream);
2550 /* Create packet stream */
2551 packet_stream = silc_packet_stream_create(server->packet_engine,
2552 server->schedule, stream);
2553 if (!packet_stream) {
2554 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2555 server->stat.conn_failures++;
2556 silc_stream_destroy(stream);
2559 server->stat.conn_num++;
2561 /* Set source ID to packet stream */
2562 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2565 server->stat.conn_failures++;
2566 silc_packet_stream_destroy(packet_stream);
2570 /* Check whether this connection is denied to connect to us. */
2571 deny = silc_server_config_find_denied(server, ip);
2573 deny = silc_server_config_find_denied(server, hostname);
2575 /* The connection is denied */
2576 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2577 silc_server_disconnect_remote(server, packet_stream,
2578 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2583 /* Check whether we have configured this sort of connection at all. We
2584 have to check all configurations since we don't know what type of
2585 connection this is. */
2586 if (!(cconfig = silc_server_config_find_client(server, ip)))
2587 cconfig = silc_server_config_find_client(server, hostname);
2588 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2589 sconfig = silc_server_config_find_server_conn(server, hostname);
2590 if (server->server_type == SILC_ROUTER)
2591 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2592 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2593 if (!cconfig && !sconfig && !rconfig) {
2594 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2595 server->stat.conn_failures++;
2596 silc_server_disconnect_remote(server, packet_stream,
2597 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2601 /* The connection is allowed */
2602 entry = silc_calloc(1, sizeof(*entry));
2604 server->stat.conn_failures++;
2605 silc_server_disconnect_remote(server, packet_stream,
2606 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2609 entry->hostname = hostname;
2612 entry->server = server;
2613 entry->data.conn_type = SILC_CONN_UNKNOWN;
2614 silc_packet_set_context(packet_stream, entry);
2616 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2617 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2618 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2620 /* Take flags for key exchange. Since we do not know what type of connection
2621 this is, we go through all found configurations and use the global ones
2622 as well. This will result always into strictest key exchange flags. */
2623 memset(¶ms, 0, sizeof(params));
2624 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2625 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2626 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2627 if (server->config->param.key_exchange_pfs)
2628 params.flags |= SILC_SKE_SP_FLAG_PFS;
2630 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2631 server->stat.conn_attempts++;
2633 /* Start SILC Key Exchange protocol */
2634 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2635 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2636 server->public_key, server->private_key,
2639 server->stat.conn_failures++;
2640 silc_server_disconnect_remote(server, packet_stream,
2641 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2644 silc_ske_set_callbacks(ske, silc_server_verify_key,
2645 silc_server_accept_completed, packet_stream);
2647 /* Start key exchange protocol */
2648 params.version = silc_version_string;
2649 params.timeout_secs = server->config->key_exchange_timeout;
2650 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2654 /********************************** Rekey ***********************************/
2656 /* Initiator rekey completion callback */
2658 static void silc_server_rekey_completion(SilcSKE ske,
2659 SilcSKEStatus status,
2660 const SilcSKESecurityProperties prop,
2661 const SilcSKEKeyMaterial keymat,
2662 SilcSKERekeyMaterial rekey,
2665 SilcPacketStream sock = context;
2666 SilcIDListData idata = silc_packet_get_context(sock);
2667 SilcServer server = idata->sconn->server;
2669 idata->sconn->op = NULL;
2670 if (status != SILC_SKE_STATUS_OK) {
2671 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2672 idata->sconn->remote_host));
2676 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2677 idata->sconn->remote_host, idata->sconn->remote_port,
2678 SILC_CONNTYPE_STRING(idata->conn_type)));
2680 /* Save rekey data for next rekey */
2681 idata->rekey = rekey;
2683 /* Register new rekey timeout */
2684 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2685 sock, idata->sconn->rekey_timeout, 0);
2688 /* Rekey callback. Start rekey as initiator */
2690 SILC_TASK_CALLBACK(silc_server_do_rekey)
2692 SilcServer server = app_context;
2693 SilcPacketStream sock = context;
2694 SilcIDListData idata = silc_packet_get_context(sock);
2697 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2699 /* Do not execute rekey with disabled connections */
2700 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2703 /* If another protocol is active do not start rekey */
2704 if (idata->sconn->op) {
2705 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2706 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2711 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2712 idata->sconn->remote_host, idata->sconn->remote_port,
2713 SILC_CONNTYPE_STRING(idata->conn_type)));
2716 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2717 server->public_key, NULL, sock);
2721 /* Set SKE callbacks */
2722 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2725 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2728 /* Responder rekey completion callback */
2731 silc_server_rekey_resp_completion(SilcSKE ske,
2732 SilcSKEStatus status,
2733 const SilcSKESecurityProperties prop,
2734 const SilcSKEKeyMaterial keymat,
2735 SilcSKERekeyMaterial rekey,
2738 SilcPacketStream sock = context;
2739 SilcIDListData idata = silc_packet_get_context(sock);
2741 idata->sconn->op = NULL;
2742 if (status != SILC_SKE_STATUS_OK) {
2743 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2744 idata->sconn->remote_host));
2748 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2749 idata->sconn->remote_host, idata->sconn->remote_port,
2750 SILC_CONNTYPE_STRING(idata->conn_type)));
2752 /* Save rekey data for next rekey */
2753 idata->rekey = rekey;
2756 /* Start rekey as responder */
2758 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2761 SilcIDListData idata = silc_packet_get_context(sock);
2764 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2765 idata->sconn->remote_host, idata->sconn->remote_port,
2766 SILC_CONNTYPE_STRING(idata->conn_type)));
2769 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2770 server->public_key, NULL, sock);
2772 silc_packet_free(packet);
2776 /* Set SKE callbacks */
2777 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2780 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2785 /****************************** Disconnection *******************************/
2787 /* Destroys packet stream. */
2789 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2791 silc_packet_stream_destroy(context);
2794 /* Closes connection to socket connection */
2796 void silc_server_close_connection(SilcServer server,
2797 SilcPacketStream sock)
2799 SilcIDListData idata = silc_packet_get_context(sock);
2801 const char *hostname;
2804 memset(tmp, 0, sizeof(tmp));
2805 // silc_socket_get_error(sock, tmp, sizeof(tmp));
2806 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2807 NULL, &hostname, NULL, &port);
2808 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2809 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
2810 tmp[0] ? tmp : ""));
2812 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2814 if (idata && idata->sconn) {
2815 silc_server_connection_free(idata->sconn);
2816 idata->sconn = NULL;
2819 /* Close connection with timeout */
2820 server->stat.conn_num--;
2821 silc_schedule_task_del_by_all(server->schedule, 0,
2822 silc_server_close_connection_final, sock);
2823 silc_schedule_task_add_timeout(server->schedule,
2824 silc_server_close_connection_final,
2828 /* Sends disconnect message to remote connection and disconnects the
2831 void silc_server_disconnect_remote(SilcServer server,
2832 SilcPacketStream sock,
2833 SilcStatus status, ...)
2835 unsigned char buf[512];
2842 SILC_LOG_DEBUG(("Disconnecting remote host"));
2844 va_start(ap, status);
2845 cp = va_arg(ap, char *);
2847 silc_vsnprintf(buf, sizeof(buf), cp, ap);
2850 /* Send SILC_PACKET_DISCONNECT */
2851 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2852 SILC_STR_UI_CHAR(status),
2853 SILC_STR_UI8_STRING(cp ? buf : NULL),
2856 /* Close connection */
2857 silc_server_close_connection(server, sock);
2860 /* Frees client data and notifies about client's signoff. */
2862 void silc_server_free_client_data(SilcServer server,
2863 SilcPacketStream sock,
2864 SilcClientEntry client,
2866 const char *signoff)
2868 SILC_LOG_DEBUG(("Freeing client %p data", client));
2871 /* Check if anyone is watching this nickname */
2872 if (server->server_type == SILC_ROUTER)
2873 silc_server_check_watcher_list(server, client, NULL,
2874 SILC_NOTIFY_TYPE_SIGNOFF);
2876 /* Send SIGNOFF notify to routers. */
2878 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2879 SILC_BROADCAST(server), client->id,
2883 /* Remove client from all channels */
2885 silc_server_remove_from_channels(server, NULL, client,
2886 TRUE, (char *)signoff, TRUE, FALSE);
2888 silc_server_remove_from_channels(server, NULL, client,
2889 FALSE, NULL, FALSE, FALSE);
2891 /* Remove this client from watcher list if it is */
2892 silc_server_del_from_watcher_list(server, client);
2894 /* Remove client's public key from repository, this will free it too. */
2895 if (client->data.public_key) {
2896 silc_skr_del_public_key(server->repository, client->data.public_key,
2898 client->data.public_key = NULL;
2901 /* Update statistics */
2902 server->stat.my_clients--;
2903 server->stat.clients--;
2904 if (server->stat.cell_clients)
2905 server->stat.cell_clients--;
2906 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2907 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2908 silc_schedule_task_del_by_context(server->schedule, client);
2910 if (client->data.sconn)
2911 silc_server_connection_free(client->data.sconn);
2913 /* We will not delete the client entry right away. We will take it
2914 into history (for WHOWAS command) for 5 minutes, unless we're
2915 shutting down server. */
2916 if (!server->server_shutdown) {
2917 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2919 client->router = NULL;
2920 client->connection = NULL;
2921 client->data.created = silc_time();
2922 silc_dlist_add(server->expired_clients, client);
2924 /* Delete directly since we're shutting down server */
2925 SILC_LOG_DEBUG(("Delete client directly"));
2926 silc_idlist_del_data(client);
2927 silc_idlist_del_client(server->local_list, client);
2931 /* Frees user_data pointer from socket connection object. This also sends
2932 appropriate notify packets to the network to inform about leaving
2935 void silc_server_free_sock_user_data(SilcServer server,
2936 SilcPacketStream sock,
2937 const char *signoff_message)
2939 SilcIDListData idata = silc_packet_get_context(sock);
2943 SILC_LOG_DEBUG(("Start"));
2948 silc_schedule_task_del_by_context(server->schedule, sock);
2950 /* Cancel active protocols */
2952 if (idata->sconn && idata->sconn->op) {
2953 SILC_LOG_DEBUG(("Abort active protocol"));
2954 silc_async_abort(idata->sconn->op, NULL, NULL);
2956 if (idata->conn_type == SILC_CONN_UNKNOWN &&
2957 ((SilcUnknownEntry)idata)->op) {
2958 SILC_LOG_DEBUG(("Abort active protocol"));
2959 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
2963 switch (idata->conn_type) {
2964 case SILC_CONN_CLIENT:
2966 SilcClientEntry client_entry = (SilcClientEntry)idata;
2967 silc_server_free_client_data(server, sock, client_entry, TRUE,
2969 silc_packet_set_context(sock, NULL);
2973 case SILC_CONN_SERVER:
2974 case SILC_CONN_ROUTER:
2976 SilcServerEntry user_data = (SilcServerEntry)idata;
2977 SilcServerEntry backup_router = NULL;
2979 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
2982 backup_router = silc_server_backup_get(server, user_data->id);
2984 if (!server->backup_router && server->server_type == SILC_ROUTER &&
2985 backup_router == server->id_entry &&
2986 idata->conn_type != SILC_CONN_ROUTER)
2987 backup_router = NULL;
2989 if (server->server_shutdown || server->backup_noswitch)
2990 backup_router = NULL;
2992 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2993 NULL, NULL, &ip, &port);
2995 /* If this was our primary router connection then we're lost to
2996 the outside world. */
2997 if (server->router == user_data) {
2998 /* Check whether we have a backup router connection */
2999 if (!backup_router || backup_router == user_data) {
3000 if (!server->no_reconnect)
3001 silc_server_create_connections(server);
3002 server->id_entry->router = NULL;
3003 server->router = NULL;
3004 server->standalone = TRUE;
3005 server->backup_primary = FALSE;
3006 backup_router = NULL;
3008 if (server->id_entry != backup_router) {
3009 SILC_LOG_INFO(("New primary router is backup router %s",
3010 backup_router->server_name));
3011 server->id_entry->router = backup_router;
3012 server->router = backup_router;
3013 server->router_connect = time(0);
3014 server->backup_primary = TRUE;
3015 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3017 /* Send START_USE to backup router to indicate we have switched */
3018 silc_server_backup_send_start_use(server,
3019 backup_router->connection,
3022 SILC_LOG_INFO(("We are now new primary router in this cell"));
3023 server->id_entry->router = NULL;
3024 server->router = NULL;
3025 server->standalone = TRUE;
3028 /* We stop here to take a breath */
3031 if (server->backup_router) {
3032 server->server_type = SILC_ROUTER;
3034 /* We'll need to constantly try to reconnect to the primary
3035 router so that we'll see when it comes back online. */
3036 silc_server_create_connection(server, FALSE, FALSE, ip, port,
3037 silc_server_backup_connected,
3041 /* Mark this connection as replaced */
3042 silc_server_backup_replaced_add(server, user_data->id,
3045 } else if (backup_router) {
3046 SILC_LOG_INFO(("Enabling the use of backup router %s",
3047 backup_router->server_name));
3049 /* Mark this connection as replaced */
3050 silc_server_backup_replaced_add(server, user_data->id,
3052 } else if (server->server_type == SILC_SERVER &&
3053 idata->conn_type == SILC_CONN_ROUTER) {
3054 /* Reconnect to the router (backup) */
3055 if (!server->no_reconnect)
3056 silc_server_create_connections(server);
3059 if (user_data->server_name)
3060 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3061 ("Server %s signoff", user_data->server_name));
3063 if (!backup_router) {
3064 /* Remove all servers that are originated from this server, and
3065 remove the clients of those servers too. */
3066 silc_server_remove_servers_by_server(server, user_data, TRUE);
3069 /* Remove the clients that this server owns as they will become
3070 invalid now too. For backup router the server is actually
3071 coming from the primary router, so mark that as the owner
3073 if (server->server_type == SILC_BACKUP_ROUTER &&
3074 sock->type == SILC_CONN_SERVER)
3075 silc_server_remove_clients_by_server(server, server->router,
3079 silc_server_remove_clients_by_server(server, user_data,
3082 /* Remove channels owned by this server */
3083 if (server->server_type == SILC_SERVER)
3084 silc_server_remove_channels_by_server(server, user_data);
3086 /* Enable local server connections that may be disabled */
3087 silc_server_local_servers_toggle_enabled(server, TRUE);
3089 /* Update the client entries of this server to the new backup
3090 router. If we are the backup router we also resolve the real
3091 servers for the clients. After updating is over this also
3092 removes the clients that this server explicitly owns. */
3093 silc_server_update_clients_by_server(server, user_data,
3094 backup_router, TRUE);
3096 /* If we are router and just lost our primary router (now standlaone)
3097 we remove everything that was behind it, since we don't know
3099 if (server->server_type == SILC_ROUTER && server->standalone)
3100 /* Remove all servers that are originated from this server, and
3101 remove the clients of those servers too. */
3102 silc_server_remove_servers_by_server(server, user_data, TRUE);
3104 /* Finally remove the clients that are explicitly owned by this
3105 server. They go down with the server. */
3106 silc_server_remove_clients_by_server(server, user_data,
3109 /* Update our server cache to use the new backup router too. */
3110 silc_server_update_servers_by_server(server, user_data, backup_router);
3111 if (server->server_type == SILC_SERVER)
3112 silc_server_update_channels_by_server(server, user_data,
3115 /* Send notify about primary router going down to local operators */
3116 if (server->backup_router)
3117 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3118 SILC_NOTIFY_TYPE_NONE,
3119 ("%s switched to backup router %s "
3120 "(we are primary router now)",
3121 server->server_name, server->server_name));
3122 else if (server->router)
3123 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3124 SILC_NOTIFY_TYPE_NONE,
3125 ("%s switched to backup router %s",
3126 server->server_name,
3127 server->router->server_name));
3129 server->backup_noswitch = FALSE;
3132 silc_server_connection_free(idata->sconn);
3135 if (idata->conn_type == SILC_CONN_SERVER) {
3136 server->stat.my_servers--;
3137 server->stat.servers--;
3138 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3139 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3140 server->stat.my_routers--;
3141 server->stat.routers--;
3142 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3144 if (server->server_type == SILC_ROUTER)
3145 server->stat.cell_servers--;
3147 /* Free the server entry */
3148 silc_server_backup_del(server, user_data);
3149 silc_server_backup_replaced_del(server, user_data);
3150 silc_idlist_del_data(user_data);
3151 if (!silc_idlist_del_server(server->local_list, user_data))
3152 silc_idlist_del_server(server->global_list, user_data);
3154 if (backup_router && backup_router != server->id_entry) {
3155 /* Announce all of our stuff that was created about 5 minutes ago.
3156 The backup router knows all the other stuff already. */
3157 if (server->server_type == SILC_ROUTER)
3158 silc_server_announce_servers(server, FALSE, time(0) - 300,
3159 backup_router->connection);
3161 /* Announce our clients and channels to the router */
3162 silc_server_announce_clients(server, time(0) - 300,
3163 backup_router->connection);
3164 silc_server_announce_channels(server, time(0) - 300,
3165 backup_router->connection);
3168 silc_packet_set_context(sock, NULL);
3174 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3176 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3179 silc_server_connection_free(idata->sconn);
3180 silc_idlist_del_data(idata);
3182 silc_packet_set_context(sock, NULL);
3188 /* Removes client from all channels it has joined. This is used when client
3189 connection is disconnected. If the client on a channel is last, the
3190 channel is removed as well. This sends the SIGNOFF notify types. */
3192 void silc_server_remove_from_channels(SilcServer server,
3193 SilcPacketStream sock,
3194 SilcClientEntry client,
3196 const char *signoff_message,
3200 SilcChannelEntry channel;
3201 SilcChannelClientEntry chl;
3202 SilcHashTableList htl;
3203 SilcBuffer clidp = NULL;
3208 if (notify && !client->id)
3211 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3212 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3215 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3220 /* Remove the client from all channels. The client is removed from
3221 the channels' user list. */
3222 silc_hash_table_list(client->channels, &htl);
3223 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3224 channel = chl->channel;
3226 /* Remove channel if this is last client leaving the channel, unless
3227 the channel is permanent. */
3228 if (server->server_type != SILC_SERVER &&
3229 silc_hash_table_count(channel->user_list) < 2) {
3230 silc_server_channel_delete(server, channel);
3234 silc_hash_table_del(client->channels, channel);
3235 silc_hash_table_del(channel->user_list, client);
3236 channel->user_count--;
3238 /* If there is no global users on the channel anymore mark the channel
3239 as local channel. Do not check if the removed client is local client. */
3240 if (server->server_type == SILC_SERVER && channel->global_users &&
3241 chl->client->router && !silc_server_channel_has_global(channel))
3242 channel->global_users = FALSE;
3244 memset(chl, 'A', sizeof(*chl));
3247 /* Update statistics */
3248 if (SILC_IS_LOCAL(client))
3249 server->stat.my_chanclients--;
3250 if (server->server_type == SILC_ROUTER) {
3251 server->stat.cell_chanclients--;
3252 server->stat.chanclients--;
3255 /* If there is not at least one local user on the channel then we don't
3256 need the channel entry anymore, we can remove it safely, unless the
3257 channel is permanent channel */
3258 if (server->server_type == SILC_SERVER &&
3259 !silc_server_channel_has_local(channel)) {
3260 /* Notify about leaving client if this channel has global users. */
3261 if (notify && channel->global_users)
3262 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3263 SILC_NOTIFY_TYPE_SIGNOFF,
3264 signoff_message ? 2 : 1,
3265 clidp->data, silc_buffer_len(clidp),
3266 signoff_message, signoff_message ?
3267 strlen(signoff_message) : 0);
3269 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3270 silc_server_channel_delete(server, channel);
3274 /* Send notify to channel about client leaving SILC and channel too */
3276 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3277 SILC_NOTIFY_TYPE_SIGNOFF,
3278 signoff_message ? 2 : 1,
3279 clidp->data, silc_buffer_len(clidp),
3280 signoff_message, signoff_message ?
3281 strlen(signoff_message) : 0);
3283 if (killed && clidp) {
3284 /* Remove the client from channel's invite list */
3285 if (channel->invite_list &&
3286 silc_hash_table_count(channel->invite_list)) {
3288 SilcArgumentPayload iargs;
3289 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3290 silc_buffer_len(clidp), 3);
3291 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3292 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3293 silc_buffer_free(ab);
3294 silc_argument_payload_free(iargs);
3298 /* Don't create keys if we are shutting down */
3299 if (server->server_shutdown)
3302 /* Re-generate channel key if needed */
3303 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3304 if (!silc_server_create_channel_key(server, channel, 0))
3307 /* Send the channel key to the channel. The key of course is not sent
3308 to the client who was removed from the channel. */
3309 silc_server_send_channel_key(server, client->connection, channel,
3310 server->server_type == SILC_ROUTER ?
3311 FALSE : !server->standalone);
3315 silc_hash_table_list_reset(&htl);
3317 silc_buffer_free(clidp);
3320 /* Removes client from one channel. This is used for example when client
3321 calls LEAVE command to remove itself from the channel. Returns TRUE
3322 if channel still exists and FALSE if the channel is removed when
3323 last client leaves the channel. If `notify' is FALSE notify messages
3326 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3327 SilcPacketStream sock,
3328 SilcChannelEntry channel,
3329 SilcClientEntry client,
3332 SilcChannelClientEntry chl;
3335 SILC_LOG_DEBUG(("Removing %s from channel %s",
3336 silc_id_render(client->id, SILC_ID_CLIENT),
3337 channel->channel_name));
3339 /* Get the entry to the channel, if this client is not on the channel
3341 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3344 /* Remove channel if this is last client leaving the channel, unless
3345 the channel is permanent. */
3346 if (server->server_type != SILC_SERVER &&
3347 silc_hash_table_count(channel->user_list) < 2) {
3348 silc_server_channel_delete(server, channel);
3352 silc_hash_table_del(client->channels, channel);
3353 silc_hash_table_del(channel->user_list, client);
3354 channel->user_count--;
3356 /* If there is no global users on the channel anymore mark the channel
3357 as local channel. Do not check if the client is local client. */
3358 if (server->server_type == SILC_SERVER && channel->global_users &&
3359 chl->client->router && !silc_server_channel_has_global(channel))
3360 channel->global_users = FALSE;
3362 memset(chl, 'O', sizeof(*chl));
3365 /* Update statistics */
3366 if (SILC_IS_LOCAL(client))
3367 server->stat.my_chanclients--;
3368 if (server->server_type == SILC_ROUTER) {
3369 server->stat.cell_chanclients--;
3370 server->stat.chanclients--;
3373 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3377 /* If there is not at least one local user on the channel then we don't
3378 need the channel entry anymore, we can remove it safely, unless the
3379 channel is permanent channel */
3380 if (server->server_type == SILC_SERVER &&
3381 !silc_server_channel_has_local(channel)) {
3382 /* Notify about leaving client if this channel has global users. */
3383 if (notify && channel->global_users)
3384 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3385 SILC_NOTIFY_TYPE_LEAVE, 1,
3386 clidp->data, silc_buffer_len(clidp));
3388 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3389 silc_server_channel_delete(server, channel);
3390 silc_buffer_free(clidp);
3394 /* Send notify to channel about client leaving the channel */
3396 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3397 SILC_NOTIFY_TYPE_LEAVE, 1,
3398 clidp->data, silc_buffer_len(clidp));
3400 silc_buffer_free(clidp);
3404 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3405 function may be used only by router. In real SILC network all channels
3406 are created by routers thus this function is never used by normal
3409 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3410 SilcServerID *router_id,
3416 SilcChannelID *channel_id;
3417 SilcChannelEntry entry;
3418 SilcCipher send_key, receive_key;
3421 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3424 cipher = SILC_DEFAULT_CIPHER;
3426 hmac = SILC_DEFAULT_HMAC;
3428 /* Allocate cipher */
3429 if (!silc_cipher_alloc(cipher, &send_key))
3431 if (!silc_cipher_alloc(cipher, &receive_key)) {
3432 silc_cipher_free(send_key);
3437 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3438 silc_cipher_free(send_key);
3439 silc_cipher_free(receive_key);
3443 channel_name = strdup(channel_name);
3445 /* Create the channel ID */
3446 if (!silc_id_create_channel_id(server, router_id, server->rng,
3448 silc_free(channel_name);
3449 silc_cipher_free(send_key);
3450 silc_cipher_free(receive_key);
3451 silc_hmac_free(newhmac);
3455 /* Create the channel */
3456 entry = silc_idlist_add_channel(server->local_list, channel_name,
3457 SILC_CHANNEL_MODE_NONE, channel_id,
3458 NULL, send_key, receive_key, newhmac);
3460 silc_free(channel_name);
3461 silc_cipher_free(send_key);
3462 silc_cipher_free(receive_key);
3463 silc_hmac_free(newhmac);
3464 silc_free(channel_id);
3468 entry->cipher = strdup(cipher);
3469 entry->hmac_name = strdup(hmac);
3471 /* Now create the actual key material */
3472 if (!silc_server_create_channel_key(server, entry,
3473 silc_cipher_get_key_len(send_key) / 8)) {
3474 silc_idlist_del_channel(server->local_list, entry);
3478 /* Notify other routers about the new channel. We send the packet
3479 to our primary route. */
3481 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3482 channel_name, entry->id,
3483 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3486 /* Distribute to backup routers */
3487 if (broadcast && server->server_type == SILC_ROUTER) {
3489 unsigned char cid[32];
3490 SilcUInt32 name_len = strlen(channel_name);
3493 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3494 packet = silc_channel_payload_encode(channel_name, name_len,
3495 cid, id_len, entry->mode);
3496 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3497 packet->data, silc_buffer_len(packet), FALSE,
3499 silc_buffer_free(packet);
3502 server->stat.my_channels++;
3503 if (server->server_type == SILC_ROUTER) {
3504 server->stat.channels++;
3505 server->stat.cell_channels++;
3506 entry->users_resolved = TRUE;
3512 /* Same as above but creates the channel with Channel ID `channel_id. */
3515 silc_server_create_new_channel_with_id(SilcServer server,
3519 SilcChannelID *channel_id,
3522 SilcChannelEntry entry;
3523 SilcCipher send_key, receive_key;
3526 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3529 cipher = SILC_DEFAULT_CIPHER;
3531 hmac = SILC_DEFAULT_HMAC;
3533 /* Allocate cipher */
3534 if (!silc_cipher_alloc(cipher, &send_key))
3536 if (!silc_cipher_alloc(cipher, &receive_key)) {
3537 silc_cipher_free(send_key);
3542 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3543 silc_cipher_free(send_key);
3544 silc_cipher_free(receive_key);
3548 channel_name = strdup(channel_name);
3550 /* Create the channel */
3551 entry = silc_idlist_add_channel(server->local_list, channel_name,
3552 SILC_CHANNEL_MODE_NONE, channel_id,
3553 NULL, send_key, receive_key, newhmac);
3555 silc_cipher_free(send_key);
3556 silc_cipher_free(receive_key);
3557 silc_hmac_free(newhmac);
3558 silc_free(channel_name);
3562 /* Now create the actual key material */
3563 if (!silc_server_create_channel_key(server, entry,
3564 silc_cipher_get_key_len(send_key) / 8)) {
3565 silc_idlist_del_channel(server->local_list, entry);
3569 /* Notify other routers about the new channel. We send the packet
3570 to our primary route. */
3572 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3573 channel_name, entry->id,
3574 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3577 /* Distribute to backup routers */
3578 if (broadcast && server->server_type == SILC_ROUTER) {
3580 unsigned char cid[32];
3581 SilcUInt32 name_len = strlen(channel_name);
3584 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3585 packet = silc_channel_payload_encode(channel_name, name_len,
3586 cid, id_len, entry->mode);
3587 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3588 packet->data, silc_buffer_len(packet), FALSE,
3590 silc_buffer_free(packet);
3593 server->stat.my_channels++;
3594 if (server->server_type == SILC_ROUTER) {
3595 server->stat.channels++;
3596 server->stat.cell_channels++;
3597 entry->users_resolved = TRUE;
3603 /* Channel's key re-key timeout callback. */
3605 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3607 SilcServer server = app_context;
3608 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3612 /* Return now if we are shutting down */
3613 if (server->server_shutdown)
3616 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3619 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3622 /* Generates new channel key. This is used to create the initial channel key
3623 but also to re-generate new key for channel. If `key_len' is provided
3624 it is the bytes of the key length. */
3626 SilcBool silc_server_create_channel_key(SilcServer server,
3627 SilcChannelEntry channel,
3631 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3634 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3635 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3639 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3641 if (!channel->send_key)
3642 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3643 channel->send_key = NULL;
3646 if (!channel->receive_key)
3647 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3648 silc_cipher_free(channel->send_key);
3649 channel->send_key = channel->receive_key = NULL;
3655 else if (channel->key_len)
3656 len = channel->key_len / 8;
3658 len = silc_cipher_get_key_len(channel->send_key) / 8;
3660 /* Create channel key */
3661 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3664 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3665 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3667 /* Remove old key if exists */
3669 memset(channel->key, 0, channel->key_len / 8);
3670 silc_free(channel->key);
3674 channel->key_len = len * 8;
3675 channel->key = silc_memdup(channel_key, len);
3676 memset(channel_key, 0, sizeof(channel_key));
3678 /* Generate HMAC key from the channel key data and set it */
3680 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3681 memset(channel->key, 0, channel->key_len / 8);
3682 silc_free(channel->key);
3683 silc_cipher_free(channel->send_key);
3684 silc_cipher_free(channel->receive_key);
3685 channel->send_key = channel->receive_key = NULL;
3688 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3689 silc_hmac_set_key(channel->hmac, hash,
3690 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3691 memset(hash, 0, sizeof(hash));
3693 if (server->server_type == SILC_ROUTER) {
3694 if (!channel->rekey)
3695 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3696 channel->rekey->channel = channel;
3697 channel->rekey->key_len = key_len;
3698 if (channel->rekey->task)
3699 silc_schedule_task_del(server->schedule, channel->rekey->task);
3701 channel->rekey->task =
3702 silc_schedule_task_add_timeout(server->schedule,
3703 silc_server_channel_key_rekey,
3704 (void *)channel->rekey,
3705 server->config->channel_rekey_secs, 0);
3711 /* Saves the channel key found in the encoded `key_payload' buffer. This
3712 function is used when we receive Channel Key Payload and also when we're
3713 processing JOIN command reply. Returns entry to the channel. */
3715 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3716 SilcBuffer key_payload,
3717 SilcChannelEntry channel)
3719 SilcChannelKeyPayload payload = NULL;
3721 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3725 /* Decode channel key payload */
3726 payload = silc_channel_key_payload_parse(key_payload->data,
3727 silc_buffer_len(key_payload));
3729 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3734 /* Get the channel entry */
3737 /* Get channel ID */
3738 tmp = silc_channel_key_get_id(payload, &tmp_len);
3739 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3744 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3746 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3748 if (server->server_type == SILC_ROUTER)
3749 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3750 silc_id_render(&id, SILC_ID_CHANNEL)));
3756 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3758 tmp = silc_channel_key_get_key(payload, &tmp_len);
3764 cipher = silc_channel_key_get_cipher(payload, NULL);
3770 /* Remove old key if exists */
3772 memset(channel->key, 0, channel->key_len / 8);
3773 silc_free(channel->key);
3774 silc_cipher_free(channel->send_key);
3775 silc_cipher_free(channel->receive_key);
3778 /* Create new cipher */
3779 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3780 channel->send_key = NULL;
3784 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3785 silc_cipher_free(channel->send_key);
3786 channel->send_key = channel->receive_key = NULL;
3791 if (channel->cipher)
3792 silc_free(channel->cipher);
3793 channel->cipher = strdup(cipher);
3796 channel->key_len = tmp_len * 8;
3797 channel->key = silc_memdup(tmp, tmp_len);
3798 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3799 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3801 /* Generate HMAC key from the channel key data and set it */
3803 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3804 memset(channel->key, 0, channel->key_len / 8);
3805 silc_free(channel->key);
3806 silc_cipher_free(channel->send_key);
3807 silc_cipher_free(channel->receive_key);
3808 channel->send_key = channel->receive_key = NULL;
3811 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3812 silc_hmac_set_key(channel->hmac, hash,
3813 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3815 memset(hash, 0, sizeof(hash));
3816 memset(tmp, 0, tmp_len);
3818 if (server->server_type == SILC_ROUTER) {
3819 if (!channel->rekey)
3820 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3821 channel->rekey->channel = channel;
3822 if (channel->rekey->task)
3823 silc_schedule_task_del(server->schedule, channel->rekey->task);
3825 channel->rekey->task =
3826 silc_schedule_task_add_timeout(server->schedule,
3827 silc_server_channel_key_rekey,
3828 (void *)channel->rekey,
3829 server->config->channel_rekey_secs, 0);
3834 silc_channel_key_payload_free(payload);
3839 /* Returns assembled of all servers in the given ID list. The packet's
3840 form is dictated by the New ID payload. */
3842 static void silc_server_announce_get_servers(SilcServer server,
3843 SilcServerEntry remote,
3845 SilcBuffer *servers,
3846 unsigned long creation_time)
3849 SilcIDCacheEntry id_cache;
3850 SilcServerEntry entry;
3853 /* Go through all clients in the list */
3854 if (silc_idcache_get_all(id_list->servers, &list)) {
3855 silc_list_start(list);
3856 while ((id_cache = silc_list_get(list))) {
3857 entry = (SilcServerEntry)id_cache->context;
3859 /* Do not announce the one we've sending our announcements and
3860 do not announce ourself. Also check the creation time if it's
3862 if ((entry == remote) || (entry == server->id_entry) ||
3863 (creation_time && entry->data.created < creation_time))
3866 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3868 *servers = silc_buffer_realloc(*servers,
3870 silc_buffer_truelen((*servers)) +
3871 silc_buffer_len(idp) :
3872 silc_buffer_len(idp)));
3873 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3874 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3875 silc_buffer_pull(*servers, silc_buffer_len(idp));
3876 silc_buffer_free(idp);
3882 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3888 p = silc_notify_payload_encode(notify, argc, ap);
3894 /* This function is used by router to announce existing servers to our
3895 primary router when we've connected to it. If `creation_time' is non-zero
3896 then only the servers that has been created after the `creation_time'
3897 will be announced. */
3899 void silc_server_announce_servers(SilcServer server, SilcBool global,
3900 unsigned long creation_time,
3901 SilcPacketStream remote)
3903 SilcBuffer servers = NULL;
3905 SILC_LOG_DEBUG(("Announcing servers"));
3907 /* Get servers in local list */
3908 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3909 server->local_list, &servers,
3913 /* Get servers in global list */
3914 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3915 server->global_list, &servers,
3919 silc_buffer_push(servers, servers->data - servers->head);
3920 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
3922 /* Send the packet */
3923 silc_server_packet_send(server, remote,
3924 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3925 servers->data, silc_buffer_len(servers));
3927 silc_buffer_free(servers);
3931 /* Returns assembled packet of all clients in the given ID list. The
3932 packet's form is dictated by the New ID Payload. */
3934 static void silc_server_announce_get_clients(SilcServer server,
3936 SilcBuffer *clients,
3938 unsigned long creation_time)
3941 SilcIDCacheEntry id_cache;
3942 SilcClientEntry client;
3945 unsigned char mode[4];
3947 /* Go through all clients in the list */
3948 if (silc_idcache_get_all(id_list->clients, &list)) {
3949 silc_list_start(list);
3950 while ((id_cache = silc_list_get(list))) {
3951 client = (SilcClientEntry)id_cache->context;
3953 if (creation_time && client->data.created < creation_time)
3955 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
3957 if (!client->connection && !client->router)
3960 SILC_LOG_DEBUG(("Announce Client ID %s",
3961 silc_id_render(client->id, SILC_ID_CLIENT)));
3963 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3965 *clients = silc_buffer_realloc(*clients,
3967 silc_buffer_truelen((*clients)) +
3968 silc_buffer_len(idp) :
3969 silc_buffer_len(idp)));
3970 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3971 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
3972 silc_buffer_pull(*clients, silc_buffer_len(idp));
3974 SILC_PUT32_MSB(client->mode, mode);
3976 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3977 2, idp->data, silc_buffer_len(idp),
3979 *umodes = silc_buffer_realloc(*umodes,
3981 silc_buffer_truelen((*umodes)) +
3982 silc_buffer_len(tmp) :
3983 silc_buffer_len(tmp)));
3984 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3985 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
3986 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
3987 silc_buffer_free(tmp);
3989 silc_buffer_free(idp);
3994 /* This function is used to announce our existing clients to our router
3995 when we've connected to it. If `creation_time' is non-zero then only
3996 the clients that has been created after the `creation_time' will be
3999 void silc_server_announce_clients(SilcServer server,
4000 unsigned long creation_time,
4001 SilcPacketStream remote)
4003 SilcBuffer clients = NULL;
4004 SilcBuffer umodes = NULL;
4006 SILC_LOG_DEBUG(("Announcing clients"));
4008 /* Get clients in local list */
4009 silc_server_announce_get_clients(server, server->local_list,
4010 &clients, &umodes, creation_time);
4012 /* As router we announce our global list as well */
4013 if (server->server_type == SILC_ROUTER)
4014 silc_server_announce_get_clients(server, server->global_list,
4015 &clients, &umodes, creation_time);
4018 silc_buffer_push(clients, clients->data - clients->head);
4019 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4021 /* Send the packet */
4022 silc_server_packet_send(server, remote,
4023 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4024 clients->data, silc_buffer_len(clients));
4026 silc_buffer_free(clients);
4030 silc_buffer_push(umodes, umodes->data - umodes->head);
4031 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4033 /* Send the packet */
4034 silc_server_packet_send(server, remote,
4035 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4036 umodes->data, silc_buffer_len(umodes));
4038 silc_buffer_free(umodes);
4042 /* Returns channel's topic for announcing it */
4044 void silc_server_announce_get_channel_topic(SilcServer server,
4045 SilcChannelEntry channel,
4050 if (channel->topic) {
4051 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4052 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4054 silc_buffer_len(chidp),
4056 strlen(channel->topic));
4057 silc_buffer_free(chidp);
4061 /* Returns channel's invite and ban lists */
4063 void silc_server_announce_get_inviteban(SilcServer server,
4064 SilcChannelEntry channel,
4068 SilcBuffer list, idp, idp2, tmp2;
4070 SilcHashTableList htl;
4071 const unsigned char a[1] = { 0x03 };
4073 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4075 /* Encode invite list */
4076 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4077 list = silc_buffer_alloc_size(2);
4078 type = silc_hash_table_count(channel->invite_list);
4079 SILC_PUT16_MSB(type, list->data);
4080 silc_hash_table_list(channel->invite_list, &htl);
4081 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4082 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4084 silc_hash_table_list_reset(&htl);
4086 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4088 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4089 idp->data, silc_buffer_len(idp),
4090 channel->channel_name,
4091 strlen(channel->channel_name),
4092 idp2->data, silc_buffer_len(idp2),
4094 list->data, silc_buffer_len(list));
4095 silc_buffer_free(idp2);
4096 silc_buffer_free(list);
4099 /* Encode ban list */
4100 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4101 list = silc_buffer_alloc_size(2);
4102 type = silc_hash_table_count(channel->ban_list);
4103 SILC_PUT16_MSB(type, list->data);
4104 silc_hash_table_list(channel->ban_list, &htl);
4105 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4106 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4108 silc_hash_table_list_reset(&htl);
4111 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4112 idp->data, silc_buffer_len(idp),
4114 list->data, silc_buffer_len(list));
4115 silc_buffer_free(list);
4118 silc_buffer_free(idp);
4121 /* Returns assembled packets for channel users of the `channel'. */
4123 void silc_server_announce_get_channel_users(SilcServer server,
4124 SilcChannelEntry channel,
4125 SilcBuffer *channel_modes,
4126 SilcBuffer *channel_users,
4127 SilcBuffer *channel_users_modes)
4129 SilcChannelClientEntry chl;
4130 SilcHashTableList htl;
4131 SilcBuffer chidp, clidp, csidp;
4132 SilcBuffer tmp, fkey = NULL, chpklist;
4134 unsigned char mode[4], ulimit[4];
4137 SILC_LOG_DEBUG(("Start"));
4139 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4140 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4141 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4144 SILC_PUT32_MSB(channel->mode, mode);
4145 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4146 SILC_PUT32_MSB(channel->user_limit, ulimit);
4147 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4148 if (channel->founder_key)
4149 fkey = silc_public_key_payload_encode(channel->founder_key);
4151 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4153 silc_buffer_len(csidp),
4156 hmac, hmac ? strlen(hmac) : 0,
4157 channel->passphrase,
4158 channel->passphrase ?
4159 strlen(channel->passphrase) : 0,
4160 fkey ? fkey->data : NULL,
4161 fkey ? silc_buffer_len(fkey) : 0,
4162 chpklist ? chpklist->data : NULL,
4164 silc_buffer_len(chpklist) : 0,
4166 SILC_CHANNEL_MODE_ULIMIT ?
4169 SILC_CHANNEL_MODE_ULIMIT ?
4170 sizeof(ulimit) : 0));
4171 len = silc_buffer_len(tmp);
4173 silc_buffer_realloc(*channel_modes,
4175 silc_buffer_truelen((*channel_modes)) + len : len));
4176 silc_buffer_pull_tail(*channel_modes,
4177 ((*channel_modes)->end -
4178 (*channel_modes)->data));
4179 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4180 silc_buffer_pull(*channel_modes, len);
4181 silc_buffer_free(tmp);
4182 silc_buffer_free(fkey);
4185 /* Now find all users on the channel */
4186 silc_hash_table_list(channel->user_list, &htl);
4187 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4188 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4190 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4194 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4196 silc_buffer_len(clidp),
4198 silc_buffer_len(chidp));
4199 len = silc_buffer_len(tmp);
4201 silc_buffer_realloc(*channel_users,
4203 silc_buffer_truelen((*channel_users)) + len : len));
4204 silc_buffer_pull_tail(*channel_users,
4205 ((*channel_users)->end -
4206 (*channel_users)->data));
4208 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4209 silc_buffer_pull(*channel_users, len);
4210 silc_buffer_free(tmp);
4212 /* CUMODE notify for mode change on the channel */
4213 SILC_PUT32_MSB(chl->mode, mode);
4214 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4215 fkey = silc_public_key_payload_encode(channel->founder_key);
4216 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4218 silc_buffer_len(csidp),
4221 silc_buffer_len(clidp),
4222 fkey ? fkey->data : NULL,
4223 fkey ? silc_buffer_len(fkey) : 0);
4224 len = silc_buffer_len(tmp);
4225 *channel_users_modes =
4226 silc_buffer_realloc(*channel_users_modes,
4227 (*channel_users_modes ?
4228 silc_buffer_truelen((*channel_users_modes)) +
4230 silc_buffer_pull_tail(*channel_users_modes,
4231 ((*channel_users_modes)->end -
4232 (*channel_users_modes)->data));
4234 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4235 silc_buffer_pull(*channel_users_modes, len);
4236 silc_buffer_free(tmp);
4237 silc_buffer_free(fkey);
4239 silc_buffer_free(clidp);
4241 silc_hash_table_list_reset(&htl);
4242 silc_buffer_free(chidp);
4243 silc_buffer_free(csidp);
4246 /* Returns assembled packets for all channels and users on those channels
4247 from the given ID List. The packets are in the form dictated by the
4248 New Channel and New Channel User payloads. */
4250 void silc_server_announce_get_channels(SilcServer server,
4252 SilcBuffer *channels,
4253 SilcBuffer **channel_modes,
4254 SilcBuffer *channel_users,
4255 SilcBuffer **channel_users_modes,
4256 SilcUInt32 *channel_users_modes_c,
4257 SilcBuffer **channel_topics,
4258 SilcBuffer **channel_invites,
4259 SilcBuffer **channel_bans,
4260 SilcChannelID ***channel_ids,
4261 unsigned long creation_time)
4264 SilcIDCacheEntry id_cache;
4265 SilcChannelEntry channel;
4266 unsigned char cid[32];
4268 SilcUInt16 name_len;
4270 int i = *channel_users_modes_c;
4273 SILC_LOG_DEBUG(("Start"));
4275 /* Go through all channels in the list */
4276 if (silc_idcache_get_all(id_list->channels, &list)) {
4277 silc_list_start(list);
4278 while ((id_cache = silc_list_get(list))) {
4279 channel = (SilcChannelEntry)id_cache->context;
4281 if (creation_time && channel->created < creation_time)
4286 SILC_LOG_DEBUG(("Announce Channel ID %s",
4287 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4289 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4290 name_len = strlen(channel->channel_name);
4293 len = 4 + name_len + id_len + 4;
4295 silc_buffer_realloc(*channels,
4297 silc_buffer_truelen((*channels)) +
4299 silc_buffer_pull_tail(*channels,
4300 ((*channels)->end - (*channels)->data));
4301 silc_buffer_format(*channels,
4302 SILC_STR_UI_SHORT(name_len),
4303 SILC_STR_UI_XNSTRING(channel->channel_name,
4305 SILC_STR_UI_SHORT(id_len),
4306 SILC_STR_UI_XNSTRING(cid, id_len),
4307 SILC_STR_UI_INT(channel->mode),
4309 silc_buffer_pull(*channels, len);
4312 if (creation_time && channel->updated < creation_time)
4318 /* Channel user modes */
4319 *channel_users_modes = silc_realloc(*channel_users_modes,
4320 sizeof(**channel_users_modes) *
4322 (*channel_users_modes)[i] = NULL;
4323 *channel_modes = silc_realloc(*channel_modes,
4324 sizeof(**channel_modes) * (i + 1));
4325 (*channel_modes)[i] = NULL;
4326 *channel_ids = silc_realloc(*channel_ids,
4327 sizeof(**channel_ids) * (i + 1));
4328 (*channel_ids)[i] = NULL;
4329 silc_server_announce_get_channel_users(server, channel,
4330 &(*channel_modes)[i],
4332 &(*channel_users_modes)[i]);
4333 (*channel_ids)[i] = channel->id;
4335 /* Channel's topic */
4336 *channel_topics = silc_realloc(*channel_topics,
4337 sizeof(**channel_topics) * (i + 1));
4338 (*channel_topics)[i] = NULL;
4339 silc_server_announce_get_channel_topic(server, channel,
4340 &(*channel_topics)[i]);
4342 /* Channel's invite and ban list */
4343 *channel_invites = silc_realloc(*channel_invites,
4344 sizeof(**channel_invites) * (i + 1));
4345 (*channel_invites)[i] = NULL;
4346 *channel_bans = silc_realloc(*channel_bans,
4347 sizeof(**channel_bans) * (i + 1));
4348 (*channel_bans)[i] = NULL;
4349 silc_server_announce_get_inviteban(server, channel,
4350 &(*channel_invites)[i],
4351 &(*channel_bans)[i]);
4353 (*channel_users_modes_c)++;
4361 /* This function is used to announce our existing channels to our router
4362 when we've connected to it. This also announces the users on the
4363 channels to the router. If the `creation_time' is non-zero only the
4364 channels that was created after the `creation_time' are announced.
4365 Note that the channel users are still announced even if the `creation_time'
4368 void silc_server_announce_channels(SilcServer server,
4369 unsigned long creation_time,
4370 SilcPacketStream remote)
4372 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4373 SilcBuffer *channel_users_modes = NULL;
4374 SilcBuffer *channel_topics = NULL;
4375 SilcBuffer *channel_invites = NULL;
4376 SilcBuffer *channel_bans = NULL;
4377 SilcUInt32 channel_users_modes_c = 0;
4378 SilcChannelID **channel_ids = NULL;
4380 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4382 /* Get channels and channel users in local list */
4383 silc_server_announce_get_channels(server, server->local_list,
4384 &channels, &channel_modes,
4386 &channel_users_modes,
4387 &channel_users_modes_c,
4391 &channel_ids, creation_time);
4393 /* Get channels and channel users in global list */
4394 if (server->server_type != SILC_SERVER)
4395 silc_server_announce_get_channels(server, server->global_list,
4396 &channels, &channel_modes,
4398 &channel_users_modes,
4399 &channel_users_modes_c,
4403 &channel_ids, creation_time);
4406 silc_buffer_push(channels, channels->data - channels->head);
4407 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4409 /* Send the packet */
4410 silc_server_packet_send(server, remote,
4411 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4412 channels->data, silc_buffer_len(channels));
4414 silc_buffer_free(channels);
4417 if (channel_users) {
4418 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4419 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4420 silc_buffer_len(channel_users));
4422 /* Send the packet */
4423 silc_server_packet_send(server, remote,
4424 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4425 channel_users->data, silc_buffer_len(channel_users));
4427 silc_buffer_free(channel_users);
4430 if (channel_modes) {
4433 for (i = 0; i < channel_users_modes_c; i++) {
4434 if (!channel_modes[i])
4436 silc_buffer_push(channel_modes[i],
4437 channel_modes[i]->data -
4438 channel_modes[i]->head);
4439 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4440 silc_buffer_len(channel_modes[i]));
4441 silc_server_packet_send_dest(server, remote,
4442 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4443 channel_ids[i], SILC_ID_CHANNEL,
4444 channel_modes[i]->data,
4445 silc_buffer_len(channel_modes[i]));
4446 silc_buffer_free(channel_modes[i]);
4448 silc_free(channel_modes);
4451 if (channel_users_modes) {
4454 for (i = 0; i < channel_users_modes_c; i++) {
4455 if (!channel_users_modes[i])
4457 silc_buffer_push(channel_users_modes[i],
4458 channel_users_modes[i]->data -
4459 channel_users_modes[i]->head);
4460 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4461 silc_buffer_len(channel_users_modes[i]));
4462 silc_server_packet_send_dest(server, remote,
4463 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4464 channel_ids[i], SILC_ID_CHANNEL,
4465 channel_users_modes[i]->data,
4466 silc_buffer_len(channel_users_modes[i]));
4467 silc_buffer_free(channel_users_modes[i]);
4469 silc_free(channel_users_modes);
4472 if (channel_topics) {
4475 for (i = 0; i < channel_users_modes_c; i++) {
4476 if (!channel_topics[i])
4479 silc_buffer_push(channel_topics[i],
4480 channel_topics[i]->data -
4481 channel_topics[i]->head);
4482 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4483 silc_buffer_len(channel_topics[i]));
4484 silc_server_packet_send_dest(server, remote,
4485 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4486 channel_ids[i], SILC_ID_CHANNEL,
4487 channel_topics[i]->data,
4488 silc_buffer_len(channel_topics[i]));
4489 silc_buffer_free(channel_topics[i]);
4491 silc_free(channel_topics);
4494 if (channel_invites) {
4497 for (i = 0; i < channel_users_modes_c; i++) {
4498 if (!channel_invites[i])
4501 silc_buffer_push(channel_invites[i],
4502 channel_invites[i]->data -
4503 channel_invites[i]->head);
4504 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4505 silc_buffer_len(channel_invites[i]));
4506 silc_server_packet_send_dest(server, remote,
4507 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4508 channel_ids[i], SILC_ID_CHANNEL,
4509 channel_invites[i]->data,
4510 silc_buffer_len(channel_invites[i]));
4511 silc_buffer_free(channel_invites[i]);
4513 silc_free(channel_invites);
4519 for (i = 0; i < channel_users_modes_c; i++) {
4520 if (!channel_bans[i])
4523 silc_buffer_push(channel_bans[i],
4524 channel_bans[i]->data -
4525 channel_bans[i]->head);
4526 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4527 silc_buffer_len(channel_bans[i]));
4528 silc_server_packet_send_dest(server, remote,
4529 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4530 channel_ids[i], SILC_ID_CHANNEL,
4531 channel_bans[i]->data,
4532 silc_buffer_len(channel_bans[i]));
4533 silc_buffer_free(channel_bans[i]);
4535 silc_free(channel_bans);
4538 silc_free(channel_ids);
4541 /* Announces WATCH list. */
4543 void silc_server_announce_watches(SilcServer server,
4544 SilcPacketStream remote)
4546 SilcHashTableList htl;
4547 SilcBuffer buffer, idp, args, pkp;
4548 SilcClientEntry client;
4551 SILC_LOG_DEBUG(("Announcing watch list"));
4553 /* XXX because way we save the nicks (hash) we cannot announce them. */
4555 /* XXX we should send all public keys in one command if client is
4556 watching more than one key */
4557 silc_hash_table_list(server->watcher_list_pk, &htl);
4558 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4559 if (!client || !client->id)
4562 server->stat.commands_sent++;
4564 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4565 args = silc_buffer_alloc_size(2);
4566 silc_buffer_format(args,
4567 SILC_STR_UI_SHORT(1),
4569 pkp = silc_public_key_payload_encode(key);
4570 args = silc_argument_payload_encode_one(args, pkp->data,
4571 silc_buffer_len(pkp), 0x00);
4572 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4573 ++server->cmd_ident, 2,
4574 1, idp->data, silc_buffer_len(idp),
4576 silc_buffer_len(args));
4579 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4580 buffer->data, silc_buffer_len(buffer));
4582 silc_buffer_free(pkp);
4583 silc_buffer_free(args);
4584 silc_buffer_free(idp);
4585 silc_buffer_free(buffer);
4587 silc_hash_table_list_reset(&htl);
4590 /* Assembles user list and users mode list from the `channel'. */
4592 SilcBool silc_server_get_users_on_channel(SilcServer server,
4593 SilcChannelEntry channel,
4594 SilcBuffer *user_list,
4595 SilcBuffer *mode_list,
4596 SilcUInt32 *user_count)
4598 SilcChannelClientEntry chl;
4599 SilcHashTableList htl;
4600 SilcBuffer client_id_list;
4601 SilcBuffer client_mode_list;
4603 SilcUInt32 list_count = 0, len = 0;
4605 if (!silc_hash_table_count(channel->user_list))
4608 silc_hash_table_list(channel->user_list, &htl);
4609 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4610 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4611 silc_hash_table_list_reset(&htl);
4613 client_id_list = silc_buffer_alloc(len);
4615 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4616 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4617 silc_buffer_pull_tail(client_mode_list,
4618 silc_buffer_truelen(client_mode_list));
4620 silc_hash_table_list(channel->user_list, &htl);
4621 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4623 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4624 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4625 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4626 silc_buffer_free(idp);
4628 /* Client's mode on channel */
4629 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4630 silc_buffer_pull(client_mode_list, 4);
4634 silc_hash_table_list_reset(&htl);
4635 silc_buffer_push(client_id_list,
4636 client_id_list->data - client_id_list->head);
4637 silc_buffer_push(client_mode_list,
4638 client_mode_list->data - client_mode_list->head);
4640 *user_list = client_id_list;
4641 *mode_list = client_mode_list;
4642 *user_count = list_count;
4646 /* Saves users and their modes to the `channel'. */
4648 void silc_server_save_users_on_channel(SilcServer server,
4649 SilcPacketStream sock,
4650 SilcChannelEntry channel,
4651 SilcClientID *noadd,
4652 SilcBuffer user_list,
4653 SilcBuffer mode_list,
4654 SilcUInt32 user_count)
4660 SilcClientEntry client;
4661 SilcIDCacheEntry cache;
4662 SilcChannelClientEntry chl;
4664 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4665 channel->channel_name));
4667 for (i = 0; i < user_count; i++) {
4669 SILC_GET16_MSB(idp_len, user_list->data + 2);
4671 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4673 silc_buffer_pull(user_list, idp_len);
4676 SILC_GET32_MSB(mode, mode_list->data);
4677 silc_buffer_pull(mode_list, 4);
4679 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4684 /* Check if we have this client cached already. */
4685 client = silc_idlist_find_client_by_id(server->local_list,
4687 server->server_type, &cache);
4689 client = silc_idlist_find_client_by_id(server->global_list,
4691 server->server_type, &cache);
4693 /* If router did not find such Client ID in its lists then this must
4694 be bogus client or some router in the net is buggy. */
4695 if (server->server_type != SILC_SERVER)
4698 /* We don't have that client anywhere, add it. The client is added
4699 to global list since server didn't have it in the lists so it must be
4701 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4702 silc_id_dup(&id.u.client_id,
4704 silc_packet_get_context(sock),
4707 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4711 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4714 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4715 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4716 "%s", channel->channel_name));
4720 if (!silc_server_client_on_channel(client, channel, &chl)) {
4721 /* Client was not on the channel, add it. */
4722 chl = silc_calloc(1, sizeof(*chl));
4723 chl->client = client;
4725 chl->channel = channel;
4726 silc_hash_table_add(channel->user_list, chl->client, chl);
4727 silc_hash_table_add(client->channels, chl->channel, chl);
4728 channel->user_count++;
4736 /* Saves channels and channels user modes to the `client'. Removes
4737 the client from those channels that are not sent in the list but
4740 void silc_server_save_user_channels(SilcServer server,
4741 SilcPacketStream sock,
4742 SilcClientEntry client,
4743 SilcBuffer channels,
4744 SilcBuffer channels_user_modes)
4747 SilcUInt32 *chumodes;
4748 SilcChannelPayload entry;
4749 SilcChannelEntry channel;
4750 SilcChannelID channel_id;
4751 SilcChannelClientEntry chl;
4752 SilcHashTable ht = NULL;
4753 SilcHashTableList htl;
4757 if (!channels || !channels_user_modes ||
4758 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4761 ch = silc_channel_payload_parse_list(channels->data,
4762 silc_buffer_len(channels));
4763 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4765 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4766 NULL, NULL, NULL, TRUE);
4767 silc_dlist_start(ch);
4768 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4769 /* Check if we have this channel, and add it if we don't have it.
4770 Also add the client on the channel unless it is there already. */
4771 if (!silc_channel_get_id_parse(entry, &channel_id))
4773 channel = silc_idlist_find_channel_by_id(server->local_list,
4776 channel = silc_idlist_find_channel_by_id(server->global_list,
4779 if (server->server_type != SILC_SERVER) {
4784 /* We don't have that channel anywhere, add it. */
4785 name = silc_channel_get_name(entry, NULL);
4786 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4787 silc_id_dup(&channel_id,
4789 server->router, NULL, NULL, 0);
4796 channel->mode = silc_channel_get_mode(entry);
4798 /* Add the client on the channel */
4799 if (!silc_server_client_on_channel(client, channel, &chl)) {
4800 chl = silc_calloc(1, sizeof(*chl));
4801 chl->client = client;
4802 chl->mode = chumodes[i++];
4803 chl->channel = channel;
4804 silc_hash_table_add(channel->user_list, chl->client, chl);
4805 silc_hash_table_add(client->channels, chl->channel, chl);
4806 channel->user_count++;
4809 chl->mode = chumodes[i++];
4812 silc_hash_table_add(ht, channel, channel);
4814 silc_channel_payload_list_free(ch);
4815 silc_free(chumodes);
4819 /* Go through the list again and remove client from channels that
4820 are no part of the list. */
4822 silc_hash_table_list(client->channels, &htl);
4823 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4824 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4825 silc_hash_table_del(chl->channel->user_list, chl->client);
4826 silc_hash_table_del(chl->client->channels, chl->channel);
4830 silc_hash_table_list_reset(&htl);
4831 silc_hash_table_free(ht);
4833 silc_hash_table_list(client->channels, &htl);
4834 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4835 silc_hash_table_del(chl->channel->user_list, chl->client);
4836 silc_hash_table_del(chl->client->channels, chl->channel);
4839 silc_hash_table_list_reset(&htl);
4843 /* Lookups route to the client indicated by the `id_data'. The connection
4844 object and internal data object is returned. Returns NULL if route
4845 could not be found to the client. If the `client_id' is specified then
4846 it is used and the `id_data' is ignored. */
4849 silc_server_get_client_route(SilcServer server,
4850 unsigned char *id_data,
4852 SilcClientID *client_id,
4853 SilcIDListData *idata,
4854 SilcClientEntry *client_entry)
4856 SilcClientID *id, clid;
4857 SilcClientEntry client;
4859 SILC_LOG_DEBUG(("Start"));
4862 *client_entry = NULL;
4864 /* Decode destination Client ID */
4866 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
4868 id = silc_id_dup(&clid, SILC_ID_CLIENT);
4870 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4873 /* If the destination belongs to our server we don't have to route
4874 the packet anywhere but to send it to the local destination. */
4875 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4879 /* If we are router and the client has router then the client is in
4880 our cell but not directly connected to us. */
4881 if (server->server_type == SILC_ROUTER && client->router) {
4882 /* We are of course in this case the client's router thus the route
4883 to the client is the server who owns the client. So, we will send
4884 the packet to that server. */
4886 *idata = (SilcIDListData)client->router;
4887 return client->router->connection;
4890 /* Seems that client really is directly connected to us */
4892 *idata = (SilcIDListData)client;
4894 *client_entry = client;
4895 return client->connection;
4898 /* Destination belongs to someone not in this server. If we are normal
4899 server our action is to send the packet to our router. */
4900 if (server->server_type != SILC_ROUTER && !server->standalone) {
4903 *idata = (SilcIDListData)server->router;
4904 return SILC_PRIMARY_ROUTE(server);
4907 /* We are router and we will perform route lookup for the destination
4908 and send the packet to fastest route. */
4909 if (server->server_type == SILC_ROUTER && !server->standalone) {
4910 /* Check first that the ID is valid */
4911 client = silc_idlist_find_client_by_id(server->global_list, id,
4914 SilcPacketStream dst_sock;
4916 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4919 if (idata && dst_sock)
4920 *idata = silc_packet_get_context(dst_sock);
4929 /* Encodes and returns channel list of channels the `client' has joined.
4930 Secret channels are not put to the list. */
4932 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4933 SilcClientEntry client,
4934 SilcBool get_private,
4935 SilcBool get_secret,
4936 SilcBuffer *user_mode_list)
4938 SilcBuffer buffer = NULL;
4939 SilcChannelEntry channel;
4940 SilcChannelClientEntry chl;
4941 SilcHashTableList htl;
4942 unsigned char cid[32];
4944 SilcUInt16 name_len;
4948 *user_mode_list = NULL;
4950 silc_hash_table_list(client->channels, &htl);
4951 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4952 channel = chl->channel;
4954 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4956 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4959 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4960 name_len = strlen(channel->channel_name);
4962 len = 4 + name_len + id_len + 4;
4963 buffer = silc_buffer_realloc(buffer,
4965 silc_buffer_truelen(buffer) + len : len));
4966 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4967 silc_buffer_format(buffer,
4968 SILC_STR_UI_SHORT(name_len),
4969 SILC_STR_DATA(channel->channel_name, name_len),
4970 SILC_STR_UI_SHORT(id_len),
4971 SILC_STR_DATA(cid, id_len),
4972 SILC_STR_UI_INT(chl->channel->mode),
4974 silc_buffer_pull(buffer, len);
4976 if (user_mode_list) {
4978 silc_buffer_realloc(*user_mode_list,
4980 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
4981 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
4982 (*user_mode_list)->data));
4983 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
4984 silc_buffer_pull(*user_mode_list, 4);
4987 silc_hash_table_list_reset(&htl);
4990 silc_buffer_push(buffer, buffer->data - buffer->head);
4991 if (user_mode_list && *user_mode_list)
4992 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
4993 (*user_mode_list)->head));
4998 /* Task callback used to retrieve network statistical information from
4999 router server once in a while. */
5001 SILC_TASK_CALLBACK(silc_server_get_stats)
5003 SilcServer server = (SilcServer)context;
5004 SilcBuffer idp, packet;
5006 if (!server->standalone) {
5007 SILC_LOG_DEBUG(("Retrieving stats from router"));
5008 server->stat.commands_sent++;
5009 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5011 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5012 ++server->cmd_ident, 1,
5014 silc_buffer_len(idp));
5015 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5016 SILC_PACKET_COMMAND, 0, packet->data,
5017 silc_buffer_len(packet));
5018 silc_buffer_free(packet);
5019 silc_buffer_free(idp);
5023 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,