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_do_rekey);
28 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
29 static void silc_server_accept_new_connection(SilcNetStatus status,
32 static void silc_server_packet_parse_type(SilcServer server,
33 SilcPacketStream sock,
35 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
39 /************************ Static utility functions **************************/
41 /* SKE public key verification callback */
44 silc_server_verify_key(SilcSKE ske,
45 SilcPublicKey public_key,
47 SilcSKEVerifyCbCompletion completion,
48 void *completion_context)
50 SilcPacketStream sock = context;
51 SilcUnknownEntry entry = silc_packet_get_context(sock);
53 SILC_LOG_DEBUG(("Verifying public key"));
55 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
56 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
57 entry->hostname, entry->ip, entry->port,
58 silc_pkcs_get_type(public_key)));
59 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
64 /* We accept all keys without explicit verification */
65 completion(ske, SILC_SKE_STATUS_OK, completion_context);
69 /************************ Packet engine callbacks ***************************/
71 /* Packet engine callback to receive a packet */
73 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
74 SilcPacketStream stream,
76 void *callback_context,
79 SilcServer server = callback_context;
80 SilcIDListData idata = stream_context;
85 /* Packets we do not handle */
86 switch (packet->type) {
87 case SILC_PACKET_HEARTBEAT:
88 case SILC_PACKET_SUCCESS:
89 case SILC_PACKET_FAILURE:
90 case SILC_PACKET_REJECT:
91 case SILC_PACKET_KEY_EXCHANGE:
92 case SILC_PACKET_KEY_EXCHANGE_1:
93 case SILC_PACKET_KEY_EXCHANGE_2:
94 case SILC_PACKET_REKEY_DONE:
95 case SILC_PACKET_CONNECTION_AUTH:
100 /* Only specific packets can come without source ID present. */
101 if ((!packet->src_id ||
102 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
103 packet->type != SILC_PACKET_NEW_CLIENT &&
104 packet->type != SILC_PACKET_NEW_SERVER &&
105 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
106 packet->type != SILC_PACKET_DISCONNECT)
109 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID
110 and for unregistered connection. */
111 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
112 packet->type == SILC_PACKET_NEW_SERVER) &&
113 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
116 /* Ignore packets from disabled connection */
117 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
118 packet->type != SILC_PACKET_HEARTBEAT &&
119 packet->type != SILC_PACKET_RESUME_ROUTER &&
120 packet->type != SILC_PACKET_REKEY)
123 /* Check that the the current client ID is same as in the client's packet. */
124 if (idata->conn_type == SILC_CONN_CLIENT) {
125 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
126 SilcClientID client_id;
128 if (client->id && packet->src_id &&
129 silc_id_str2id(packet->src_id, packet->src_id_len,
130 packet->src_id_type, &client_id, sizeof(client_id))) {
131 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
132 SILC_LOG_DEBUG(("Packet source is not same as sender"));
138 if (server->server_type == SILC_ROUTER) {
139 /* Route the packet if it is not destined to us. Other ID types but
140 server are handled separately after processing them. */
141 if (packet->dst_id &&
142 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
143 packet->dst_id_type == SILC_ID_SERVER &&
144 idata->conn_type != SILC_CONN_CLIENT &&
145 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
146 SilcPacketStream conn;
147 SilcServerID server_id;
149 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
150 &server_id, sizeof(server_id));
152 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
154 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
155 silc_id_render(&server_id, SILC_ID_SERVER)));
159 silc_server_packet_route(server, conn, packet);
160 silc_packet_free(packet);
165 /* Broadcast packet if it is marked as broadcast packet and it is
166 originated from router and we are router. */
167 if (server->server_type == SILC_ROUTER &&
168 idata->conn_type == SILC_CONN_ROUTER &&
169 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
170 /* Broadcast to our primary route */
171 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
173 /* If we have backup routers then we need to feed all broadcast
174 data to those servers. */
175 silc_server_backup_broadcast(server, stream, packet);
179 silc_server_packet_parse_type(server, stream, packet);
184 /* Packet engine callback to indicate end of stream */
186 static void silc_server_packet_eos(SilcPacketEngine engine,
187 SilcPacketStream stream,
188 void *callback_context,
189 void *stream_context)
191 SilcServer server = callback_context;
192 SilcIDListData idata = silc_packet_get_context(stream);
194 SILC_LOG_DEBUG(("End of stream received"));
199 if (server->router_conn && server->router_conn->sock == stream &&
200 !server->router && server->standalone) {
201 silc_server_create_connections(server);
203 /* If backup disconnected then mark that resuming will not be allowed */
204 if (server->server_type == SILC_ROUTER && !server->backup_router &&
205 idata->conn_type == SILC_CONN_SERVER) {
206 SilcServerEntry server_entry = (SilcServerEntry)idata;
207 if (server_entry->server_type == SILC_BACKUP_ROUTER)
208 server->backup_closed = TRUE;
211 silc_server_free_sock_user_data(server, stream, NULL);
214 silc_server_close_connection(server, stream);
217 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
219 SilcServer server = app_context;
220 SilcPacketStream stream = context;
221 SilcIDListData idata = silc_packet_get_context(stream);
226 if (server->router_conn && server->router_conn->sock == stream &&
227 !server->router && server->standalone) {
228 silc_server_create_connections(server);
230 /* If backup disconnected then mark that resuming will not be allowed */
231 if (server->server_type == SILC_ROUTER && !server->backup_router &&
232 idata->conn_type == SILC_CONN_SERVER) {
233 SilcServerEntry server_entry = (SilcServerEntry)idata;
234 if (server_entry->server_type == SILC_BACKUP_ROUTER)
235 server->backup_closed = TRUE;
238 silc_server_free_sock_user_data(server, stream, NULL);
241 silc_server_close_connection(server, stream);
244 /* Packet engine callback to indicate error */
246 static void silc_server_packet_error(SilcPacketEngine engine,
247 SilcPacketStream stream,
248 SilcPacketError error,
249 void *callback_context,
250 void *stream_context)
252 SilcServer server = callback_context;
253 SilcIDListData idata = silc_packet_get_context(stream);
254 SilcStream sock = silc_packet_stream_get_stream(stream);
261 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
264 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
265 SILC_CONNTYPE_STRING(idata->conn_type),
266 silc_packet_error_string(error)));
268 silc_schedule_task_add_timeout(server->schedule,
269 silc_server_packet_error_timeout,
273 /* Packet stream callbacks */
274 static SilcPacketCallbacks silc_server_stream_cbs =
276 silc_server_packet_receive,
277 silc_server_packet_eos,
278 silc_server_packet_error
281 /* Parses the packet type and calls what ever routines the packet type
282 requires. This is done for all incoming packets. */
284 static void silc_server_packet_parse_type(SilcServer server,
285 SilcPacketStream sock,
288 SilcPacketType type = packet->type;
289 SilcIDListData idata = silc_packet_get_context(sock);
291 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
292 silc_get_packet_name(type), packet->flags));
294 /* Parse the packet type */
296 case SILC_PACKET_NOTIFY:
298 * Received notify packet. Server can receive notify packets from
299 * router. Server then relays the notify messages to clients if needed.
301 if (packet->flags & SILC_PACKET_FLAG_LIST)
302 silc_server_notify_list(server, sock, packet);
304 silc_server_notify(server, sock, packet);
308 * Private Message packets
310 case SILC_PACKET_PRIVATE_MESSAGE:
312 * Received private message packet. The packet is coming from either
315 if (packet->flags & SILC_PACKET_FLAG_LIST)
317 idata->last_receive = time(NULL);
318 silc_server_private_message(server, sock, packet);
324 case SILC_PACKET_CHANNEL_MESSAGE:
326 * Received channel message. Channel messages are special packets
327 * (although probably most common ones) thus they are handled
330 if (packet->flags & SILC_PACKET_FLAG_LIST)
332 idata->last_receive = time(NULL);
333 silc_server_channel_message(server, sock, packet);
339 case SILC_PACKET_COMMAND:
341 * Recived command. Processes the command request and allocates the
342 * command context and calls the command.
344 if (packet->flags & SILC_PACKET_FLAG_LIST)
346 server->stat.commands_received++;
347 silc_server_command_process(server, sock, packet);
350 case SILC_PACKET_COMMAND_REPLY:
352 * Received command reply packet. Received command reply to command. It
353 * may be reply to command sent by us or reply to command sent by client
354 * that we've routed further.
356 if (packet->flags & SILC_PACKET_FLAG_LIST)
358 server->stat.commands_received++;
359 silc_server_command_reply(server, sock, packet);
362 case SILC_PACKET_DISCONNECT:
365 char *message = NULL;
366 const char *hostname, *ip;
368 if (packet->flags & SILC_PACKET_FLAG_LIST)
370 if (silc_buffer_len(&packet->buffer) < 1)
373 status = (SilcStatus)packet->buffer.data[0];
374 if (silc_buffer_len(&packet->buffer) > 1 &&
375 silc_utf8_valid(packet->buffer.data + 1,
376 silc_buffer_len(&packet->buffer) - 1))
377 message = silc_memdup(packet->buffer.data + 1,
378 silc_buffer_len(&packet->buffer) - 1);
380 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
381 NULL, &hostname, &ip, NULL))
384 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
385 silc_get_status_message(status), status,
386 message ? message : ""));
390 /* Do not switch to backup in case of error */
391 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
393 /* If backup disconnected then mark that resuming will not be allowed */
394 if (server->server_type == SILC_ROUTER && !server->backup_router &&
395 idata->conn_type == SILC_CONN_SERVER) {
396 SilcServerEntry server_entry = (SilcServerEntry)idata;
397 if (server_entry->server_type == SILC_BACKUP_ROUTER)
398 server->backup_closed = TRUE;
401 /* Handle the disconnection from our end too */
402 if (SILC_IS_LOCAL(idata))
403 silc_server_free_sock_user_data(server, sock, NULL);
404 silc_server_close_connection(server, sock);
405 server->backup_noswitch = FALSE;
409 case SILC_PACKET_CHANNEL_KEY:
411 * Received key for channel. As channels are created by the router
412 * the keys are as well. We will distribute the key to all of our
413 * locally connected clients on the particular channel. Router
414 * never receives this channel and thus is ignored.
416 if (packet->flags & SILC_PACKET_FLAG_LIST)
418 silc_server_channel_key(server, sock, packet);
421 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
423 * Private message key packet.
425 if (packet->flags & SILC_PACKET_FLAG_LIST)
427 silc_server_private_message_key(server, sock, packet);
430 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
432 * Connection authentication request packet. When we receive this packet
433 * we will send to the other end information about our mandatory
434 * authentication method for the connection. This packet maybe received
437 if (packet->flags & SILC_PACKET_FLAG_LIST)
439 silc_server_connection_auth_request(server, sock, packet);
442 case SILC_PACKET_NEW_ID:
444 * Received New ID packet. This includes some new ID that has been
445 * created. It may be for client, server or channel. This is the way
446 * to distribute information about new registered entities in the
449 if (packet->flags & SILC_PACKET_FLAG_LIST)
450 silc_server_new_id_list(server, sock, packet);
452 silc_server_new_id(server, sock, packet);
455 case SILC_PACKET_NEW_CLIENT:
457 * Received new client packet. This includes client information that
458 * we will use to create initial client ID. After creating new
459 * ID we will send it to the client.
461 if (packet->flags & SILC_PACKET_FLAG_LIST)
463 silc_server_new_client(server, sock, packet);
466 case SILC_PACKET_NEW_SERVER:
468 * Received new server packet. This includes Server ID and some other
469 * information that we may save. This is received after server has
472 if (packet->flags & SILC_PACKET_FLAG_LIST)
474 silc_server_new_server(server, sock, packet);
477 case SILC_PACKET_NEW_CHANNEL:
479 * Received new channel packet. Information about new channel in the
480 * network are distributed using this packet.
482 if (packet->flags & SILC_PACKET_FLAG_LIST)
483 silc_server_new_channel_list(server, sock, packet);
485 silc_server_new_channel(server, sock, packet);
488 case SILC_PACKET_HEARTBEAT:
490 * Received heartbeat.
492 if (packet->flags & SILC_PACKET_FLAG_LIST)
496 case SILC_PACKET_KEY_AGREEMENT:
498 * Received heartbeat.
500 if (packet->flags & SILC_PACKET_FLAG_LIST)
502 silc_server_key_agreement(server, sock, packet);
505 case SILC_PACKET_REKEY:
507 * Received re-key packet. The sender wants to regenerate the session
510 if (packet->flags & SILC_PACKET_FLAG_LIST)
512 silc_server_rekey(server, sock, packet);
515 case SILC_PACKET_FTP:
517 if (packet->flags & SILC_PACKET_FLAG_LIST)
519 silc_server_ftp(server, sock, packet);
522 case SILC_PACKET_RESUME_CLIENT:
524 if (packet->flags & SILC_PACKET_FLAG_LIST)
526 silc_server_resume_client(server, sock, packet);
529 case SILC_PACKET_RESUME_ROUTER:
530 /* Resume router packet received. This packet is received for backup
531 router resuming protocol. */
532 if (packet->flags & SILC_PACKET_FLAG_LIST)
534 silc_server_backup_resume_router(server, sock, packet);
538 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
543 /****************************** Server API **********************************/
545 /* Allocates a new SILC server object. This has to be done before the server
546 can be used. After allocation one must call silc_server_init to initialize
547 the server. The new allocated server object is returned to the new_server
550 SilcBool silc_server_alloc(SilcServer *new_server)
554 SILC_LOG_DEBUG(("Allocating new server object"));
556 server = silc_calloc(1, sizeof(*server));
559 server->server_type = SILC_SERVER;
560 server->standalone = TRUE;
561 server->local_list = silc_calloc(1, sizeof(*server->local_list));
562 if (!server->local_list)
564 server->global_list = silc_calloc(1, sizeof(*server->global_list));
565 if (!server->global_list)
567 server->pending_commands = silc_dlist_init();
568 if (!server->pending_commands)
570 server->listeners = silc_dlist_init();
571 if (!server->listeners)
573 server->repository = silc_skr_alloc();
574 if (!server->repository)
576 server->conns = silc_dlist_init();
579 server->expired_clients = silc_dlist_init();
580 if (!server->expired_clients)
583 *new_server = server;
588 /* Free's the SILC server object. This is called at the very end before
591 void silc_server_free(SilcServer server)
594 SilcIDCacheEntry cache;
595 SilcIDListData idata;
597 SILC_LOG_DEBUG(("Free server %p", server));
602 silc_server_backup_free(server);
603 silc_server_config_unref(&server->config_ref);
605 silc_rng_free(server->rng);
606 if (server->public_key)
607 silc_pkcs_public_key_free(server->public_key);
608 if (server->private_key)
609 silc_pkcs_private_key_free(server->private_key);
610 if (server->pending_commands)
611 silc_dlist_uninit(server->pending_commands);
612 if (server->id_entry) {
613 if (server->id_entry->data.sconn)
614 silc_schedule_task_del_by_context(server->schedule,
615 server->id_entry->data.sconn->sock);
616 silc_idlist_del_server(server->local_list, server->id_entry);
619 /* Delete all channels */
620 if (silc_idcache_get_all(server->local_list->channels, &list)) {
621 silc_list_start(list);
622 while ((cache = silc_list_get(list)))
623 silc_idlist_del_channel(server->local_list, cache->context);
625 if (silc_idcache_get_all(server->global_list->channels, &list)) {
626 silc_list_start(list);
627 while ((cache = silc_list_get(list)))
628 silc_idlist_del_channel(server->global_list, cache->context);
631 /* Delete all clients */
632 if (silc_idcache_get_all(server->local_list->clients, &list)) {
633 silc_list_start(list);
634 while ((cache = silc_list_get(list))) {
635 silc_schedule_task_del_by_context(server->schedule, cache->context);
636 silc_idlist_del_client(server->local_list, cache->context);
639 if (silc_idcache_get_all(server->global_list->clients, &list)) {
640 silc_list_start(list);
641 while ((cache = silc_list_get(list))) {
642 silc_schedule_task_del_by_context(server->schedule, cache->context);
643 silc_idlist_del_client(server->global_list, cache->context);
647 /* Delete all servers */
648 if (silc_idcache_get_all(server->local_list->servers, &list)) {
649 silc_list_start(list);
650 while ((cache = silc_list_get(list))) {
651 idata = (SilcIDListData)cache->context;
653 silc_schedule_task_del_by_context(server->schedule,
655 silc_idlist_del_server(server->local_list, cache->context);
658 if (silc_idcache_get_all(server->global_list->servers, &list)) {
659 while ((cache = silc_list_get(list))) {
660 idata = (SilcIDListData)cache->context;
662 silc_schedule_task_del_by_context(server->schedule,
664 silc_idlist_del_server(server->global_list, cache->context);
668 silc_idcache_free(server->local_list->clients);
669 silc_idcache_free(server->local_list->servers);
670 silc_idcache_free(server->local_list->channels);
671 silc_idcache_free(server->global_list->clients);
672 silc_idcache_free(server->global_list->servers);
673 silc_idcache_free(server->global_list->channels);
674 silc_hash_table_free(server->watcher_list);
675 silc_hash_table_free(server->watcher_list_pk);
676 silc_hash_free(server->md5hash);
677 silc_hash_free(server->sha1hash);
679 silc_dlist_uninit(server->listeners);
680 silc_dlist_uninit(server->conns);
681 silc_dlist_uninit(server->expired_clients);
682 silc_skr_free(server->repository);
683 silc_packet_engine_stop(server->packet_engine);
685 silc_schedule_task_del_by_context(server->schedule, server);
686 silc_schedule_uninit(server->schedule);
687 server->schedule = NULL;
689 silc_free(server->local_list);
690 silc_free(server->global_list);
691 silc_free(server->server_name);
694 silc_hmac_unregister_all();
695 silc_hash_unregister_all();
696 silc_cipher_unregister_all();
697 silc_pkcs_unregister_all();
700 /* Creates a new server listener. */
702 static SilcNetListener
703 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
705 SilcNetListener listener;
708 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
709 server->config->require_reverse_lookup,
711 silc_server_accept_new_connection, server);
713 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
721 /* Adds a secondary listener. */
723 SilcBool silc_server_init_secondary(SilcServer server)
725 SilcServerConfigServerInfoInterface *interface;
726 SilcNetListener listener;
728 for (interface = server->config->server_info->secondary; interface;
729 interface = interface->next) {
730 listener = silc_server_listen(server, interface->server_ip,
734 silc_dlist_add(server->listeners, listener);
740 /* Initializes the entire SILC server. This is called always before running
741 the server. This is called only once at the initialization of the program.
742 This binds the server to its listenning port. After this function returns
743 one should call silc_server_run to start the server. This returns TRUE
744 when everything is ok to run the server. Configuration file must be
745 read and parsed before calling this. */
747 SilcBool silc_server_init(SilcServer server)
750 SilcServerEntry id_entry;
751 SilcNetListener listener;
755 SILC_LOG_DEBUG(("Initializing server"));
757 server->starttime = time(NULL);
759 /* Take config object for us */
760 silc_server_config_ref(&server->config_ref, server->config,
764 /* Set debugging on if configured */
765 if (server->config->debug_string) {
766 silc_log_debug(TRUE);
767 silc_log_set_debug_string(server->config->debug_string);
769 #endif /* SILC_DEBUG */
771 /* Steal public and private key from the config object */
772 server->public_key = server->config->server_info->public_key;
773 server->private_key = server->config->server_info->private_key;
774 server->config->server_info->public_key = NULL;
775 server->config->server_info->private_key = NULL;
777 /* Register all configured ciphers, PKCS and hash functions. */
778 if (!silc_server_config_register_ciphers(server))
779 silc_cipher_register_default();
780 if (!silc_server_config_register_pkcs(server))
781 silc_pkcs_register_default();
782 if (!silc_server_config_register_hashfuncs(server))
783 silc_hash_register_default();
784 if (!silc_server_config_register_hmacs(server))
785 silc_hmac_register_default();
787 /* Initialize random number generator for the server. */
788 server->rng = silc_rng_alloc();
789 silc_rng_init(server->rng);
790 silc_rng_global_init(server->rng);
792 /* Initialize hash functions for server to use */
793 silc_hash_alloc("md5", &server->md5hash);
794 silc_hash_alloc("sha1", &server->sha1hash);
796 /* Initialize the scheduler */
797 server->schedule = silc_schedule_init(server->config->param.connections_max,
799 if (!server->schedule)
802 /* First, register log files configuration for error output */
803 silc_server_config_setlogfiles(server);
805 /* Initialize ID caches */
806 server->local_list->clients =
807 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
809 server->local_list->servers =
810 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
812 server->local_list->channels =
813 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
816 /* These are allocated for normal server as well as these hold some
817 global information that the server has fetched from its router. For
818 router these are used as they are supposed to be used on router. */
819 server->global_list->clients =
820 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
822 server->global_list->servers =
823 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
825 server->global_list->channels =
826 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
829 /* Init watcher lists */
830 server->watcher_list =
831 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
832 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
834 if (!server->watcher_list)
836 server->watcher_list_pk =
837 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
838 silc_hash_public_key_compare, NULL,
840 if (!server->watcher_list_pk)
843 /* Create TCP listener */
844 listener = silc_server_listen(
846 server->config->server_info->primary == NULL ? NULL :
847 server->config->server_info->primary->server_ip,
848 server->config->server_info->primary == NULL ? 0 :
849 server->config->server_info->primary->port);
852 silc_dlist_add(server->listeners, listener);
854 /* Create a Server ID for the server. */
855 port = silc_net_listener_get_port(listener, NULL);
856 ip = silc_net_listener_get_ip(listener, NULL);
857 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
858 server->config->server_info->primary->public_ip :
859 ip[0], port[0], server->rng, &id);
868 server->server_name = server->config->server_info->server_name;
869 server->config->server_info->server_name = NULL;
870 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
871 sizeof(server->id_string), &server->id_string_len);
873 /* Add ourselves to the server list. We don't have a router yet
874 beacuse we haven't established a route yet. It will be done later.
875 For now, NULL is sent as router. This allocates new entry to
878 silc_idlist_add_server(server->local_list, strdup(server->server_name),
879 server->server_type, server->id, NULL, NULL);
881 SILC_LOG_ERROR(("Could not add local server to cache"));
884 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
885 server->id_entry = id_entry;
887 /* Create secondary TCP listeners */
888 if (silc_server_init_secondary(server) == FALSE)
891 server->listenning = TRUE;
893 /* Create connections to configured routers. */
894 silc_server_create_connections(server);
896 /* If server connections has been configured then we must be router as
897 normal server cannot have server connections, only router connections. */
898 if (server->config->servers) {
899 SilcServerConfigServer *ptr = server->config->servers;
901 server->server_type = SILC_ROUTER;
903 if (ptr->backup_router) {
904 server->server_type = SILC_BACKUP_ROUTER;
905 server->backup_router = TRUE;
906 server->id_entry->server_type = SILC_BACKUP_ROUTER;
913 /* If we are normal server we'll retrieve network statisticial information
914 once in a while from the router. */
915 if (server->server_type != SILC_ROUTER)
916 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
919 if (server->server_type == SILC_ROUTER)
920 server->stat.routers++;
922 /* Start packet engine */
923 server->packet_engine =
924 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
925 &silc_server_stream_cbs, server);
926 if (!server->packet_engine)
929 /* Register client entry expiration timeout */
930 silc_schedule_task_add_timeout(server->schedule,
931 silc_server_purge_expired_clients, server,
934 /* Initialize HTTP server */
935 silc_server_http_init(server);
937 SILC_LOG_DEBUG(("Server initialized"));
939 /* We are done here, return succesfully */
943 silc_server_config_unref(&server->config_ref);
947 /* Task callback to close a socket connection after rehash */
949 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
951 SilcServer server = app_context;
952 SilcPacketStream sock = context;
953 SilcIDListData idata = silc_packet_get_context(sock);
954 const char *hostname;
957 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
958 NULL, &hostname, NULL, &port);
960 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
961 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
962 silc_schedule_task_del_by_context(server->schedule, sock);
963 silc_server_disconnect_remote(server, sock,
964 SILC_STATUS_ERR_BANNED_FROM_SERVER,
965 "This connection is removed from "
967 silc_server_free_sock_user_data(server, sock, NULL);
970 /* This function basically reads the config file again and switches the config
971 object pointed by the server object. After that, we have to fix various
972 things such as the server_name and the listening ports.
973 Keep in mind that we no longer have the root privileges at this point. */
975 SilcBool silc_server_rehash(SilcServer server)
977 SilcServerConfig newconfig;
979 SILC_LOG_INFO(("Rehashing server"));
981 /* Reset the logging system */
982 silc_log_quick(TRUE);
983 silc_log_flush_all();
985 /* Start the main rehash phase (read again the config file) */
986 newconfig = silc_server_config_alloc(server->config_file, server);
988 SILC_LOG_ERROR(("Rehash FAILED."));
992 /* Fix the server_name field */
993 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
994 silc_free(server->server_name);
996 /* Check server name */
997 server->server_name =
998 silc_identifier_check(newconfig->server_info->server_name,
999 strlen(newconfig->server_info->server_name),
1000 SILC_STRING_LOCALE, 256, NULL);
1001 if (!server->server_name) {
1002 SILC_LOG_ERROR(("Malformed server name string '%s'",
1003 server->config->server_info->server_name));
1007 /* Update the idcache list with a fresh pointer */
1008 silc_free(server->id_entry->server_name);
1009 server->id_entry->server_name = strdup(server->server_name);
1010 silc_idcache_update_by_context(server->local_list->servers,
1011 server->id_entry, NULL,
1012 strdup(server->id_entry->server_name),
1017 silc_server_config_setlogfiles(server);
1019 /* Change new key pair if necessary */
1020 if (newconfig->server_info->public_key &&
1021 !silc_pkcs_public_key_compare(server->public_key,
1022 newconfig->server_info->public_key)) {
1023 silc_pkcs_public_key_free(server->public_key);
1024 silc_pkcs_private_key_free(server->private_key);
1025 server->public_key = newconfig->server_info->public_key;
1026 server->private_key = newconfig->server_info->private_key;
1027 newconfig->server_info->public_key = NULL;
1028 newconfig->server_info->private_key = NULL;
1031 /* Check for unconfigured server and router connections and close
1032 connections that were unconfigured. */
1034 if (server->config->routers) {
1035 SilcServerConfigRouter *ptr;
1036 SilcServerConfigRouter *newptr;
1039 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1042 /* Check whether new config has this one too */
1043 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1044 if (silc_string_compare(newptr->host, ptr->host) &&
1045 newptr->port == ptr->port &&
1046 newptr->initiator == ptr->initiator) {
1052 if (!found && ptr->host) {
1053 /* Remove this connection */
1054 SilcPacketStream sock;
1055 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1056 ptr->host, ptr->port);
1058 silc_schedule_task_add_timeout(server->schedule,
1059 silc_server_rehash_close_connection,
1065 if (server->config->servers) {
1066 SilcServerConfigServer *ptr;
1067 SilcServerConfigServer *newptr;
1070 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1073 /* Check whether new config has this one too */
1074 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1075 if (silc_string_compare(newptr->host, ptr->host)) {
1081 if (!found && ptr->host) {
1082 /* Remove this connection */
1083 SilcPacketStream sock;
1084 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1087 silc_schedule_task_add_timeout(server->schedule,
1088 silc_server_rehash_close_connection,
1094 if (server->config->clients) {
1095 SilcServerConfigClient *ptr;
1096 SilcServerConfigClient *newptr;
1099 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1102 /* Check whether new config has this one too */
1103 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1104 if (silc_string_compare(newptr->host, ptr->host)) {
1110 if (!found && ptr->host) {
1111 /* Remove this connection */
1112 SilcPacketStream sock;
1113 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1116 silc_schedule_task_add_timeout(server->schedule,
1117 silc_server_rehash_close_connection,
1123 /* Create connections after rehash */
1124 silc_server_create_connections(server);
1126 /* Check whether our router status has changed */
1127 if (newconfig->servers) {
1128 SilcServerConfigServer *ptr = newconfig->servers;
1130 server->server_type = SILC_ROUTER;
1132 if (ptr->backup_router) {
1133 server->server_type = SILC_BACKUP_ROUTER;
1134 server->backup_router = TRUE;
1135 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1142 /* Our old config is gone now. We'll unreference our reference made in
1143 silc_server_init and then destroy it since we are destroying it
1144 underneath the application (layer which called silc_server_init). */
1145 silc_server_config_unref(&server->config_ref);
1146 silc_server_config_destroy(server->config);
1148 /* Take new config context */
1149 server->config = newconfig;
1150 silc_server_config_ref(&server->config_ref, server->config, server->config);
1153 /* Set debugging on if configured */
1154 if (server->config->debug_string) {
1155 silc_log_debug(TRUE);
1156 silc_log_set_debug_string(server->config->debug_string);
1158 #endif /* SILC_DEBUG */
1160 SILC_LOG_DEBUG(("Server rehashed"));
1165 /* The heart of the server. This runs the scheduler thus runs the server.
1166 When this returns the server has been stopped and the program will
1169 void silc_server_run(SilcServer server)
1171 SILC_LOG_INFO(("SILC Server started"));
1173 /* Start the scheduler, the heart of the SILC server. When this returns
1174 the program will be terminated. */
1175 silc_schedule(server->schedule);
1178 /* Stops the SILC server. This function is used to shutdown the server.
1179 This is usually called after the scheduler has returned. After stopping
1180 the server one should call silc_server_free. */
1182 void silc_server_stop(SilcServer server)
1185 SilcPacketStream ps;
1186 SilcNetListener listener;
1188 SILC_LOG_INFO(("SILC Server shutting down"));
1190 server->server_shutdown = TRUE;
1192 /* Close all connections */
1193 if (server->packet_engine) {
1194 list = silc_packet_engine_get_streams(server->packet_engine);
1196 silc_dlist_start(list);
1197 while ((ps = silc_dlist_get(list))) {
1198 SilcIDListData idata = silc_packet_get_context(ps);
1201 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1203 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1204 "Server is shutting down");
1205 silc_server_free_sock_user_data(server, ps,
1206 "Server is shutting down");
1208 silc_dlist_uninit(list);
1211 /* We are not connected to network anymore */
1212 server->standalone = TRUE;
1214 silc_dlist_start(server->listeners);
1215 while ((listener = silc_dlist_get(server->listeners)))
1216 silc_net_close_listener(listener);
1218 silc_server_http_uninit(server);
1220 silc_schedule_stop(server->schedule);
1222 SILC_LOG_DEBUG(("Server stopped"));
1225 /* Purge expired client entries from the server */
1227 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1229 SilcServer server = context;
1230 SilcClientEntry client;
1232 SilcUInt64 curtime = silc_time();
1234 SILC_LOG_DEBUG(("Expire timeout"));
1236 silc_dlist_start(server->expired_clients);
1237 while ((client = silc_dlist_get(server->expired_clients))) {
1238 if (client->data.status & SILC_IDLIST_STATUS_REGISTERED)
1241 /* For unregistered clients the created timestamp is actually
1242 unregistered timestamp. Make sure client remains in history
1243 at least 500 seconds. */
1244 if (curtime - client->data.created < 500)
1247 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1248 server->local_list : server->global_list);
1250 silc_idlist_del_data(client);
1251 silc_idlist_del_client(id_list, client);
1252 silc_dlist_del(server->expired_clients, client);
1255 silc_schedule_task_add_timeout(server->schedule,
1256 silc_server_purge_expired_clients, server,
1261 /******************************* Connecting *********************************/
1263 /* Free connection context */
1265 void silc_server_connection_free(SilcServerConnection sconn)
1267 SILC_LOG_DEBUG(("Free connection %p", sconn));
1268 silc_dlist_del(sconn->server->conns, sconn);
1269 silc_server_config_unref(&sconn->conn);
1270 silc_free(sconn->remote_host);
1271 silc_free(sconn->backup_replace_ip);
1275 /* Creates connection to a remote router. */
1277 void silc_server_create_connection(SilcServer server,
1280 const char *remote_host, SilcUInt32 port,
1281 SilcServerConnectCallback callback,
1284 SilcServerConnection sconn;
1286 /* Allocate connection object for hold connection specific stuff. */
1287 sconn = silc_calloc(1, sizeof(*sconn));
1290 sconn->remote_host = strdup(remote_host);
1291 sconn->remote_port = port;
1292 sconn->no_reconnect = reconnect == FALSE;
1293 sconn->callback = callback;
1294 sconn->callback_context = context;
1295 sconn->no_conf = dynamic;
1296 sconn->server = server;
1298 SILC_LOG_DEBUG(("Created connection %p", sconn));
1300 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1304 /* Connection authentication completion callback */
1307 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1310 SilcServerConnection sconn = context;
1311 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1312 SilcServer server = entry->server;
1313 SilcServerConfigServer *conn;
1314 SilcServerConfigConnParams *param;
1315 SilcIDListData idata;
1316 SilcServerEntry id_entry = NULL;
1317 unsigned char id[32];
1322 SILC_LOG_DEBUG(("Connection authentication completed"));
1326 if (success == FALSE) {
1327 /* Authentication failed */
1328 /* XXX retry connecting */
1330 silc_server_disconnect_remote(server, sconn->sock,
1331 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1332 if (sconn->callback)
1333 (*sconn->callback)(server, NULL, sconn->callback_context);
1337 /* XXX For now remote is router always */
1338 entry->data.conn_type = SILC_CONN_ROUTER;
1340 SILC_LOG_INFO(("Connected to %s %s",
1341 SILC_CONNTYPE_STRING(entry->data.conn_type),
1342 sconn->remote_host));
1344 /* Create the actual entry for remote entity */
1345 switch (entry->data.conn_type) {
1346 case SILC_CONN_SERVER:
1347 SILC_LOG_DEBUG(("Remote is SILC server"));
1349 /* Add new server. The server must register itself to us before it
1350 becomes registered to SILC network. */
1351 id_entry = silc_idlist_add_server(server->local_list,
1352 strdup(sconn->remote_host),
1353 SILC_SERVER, NULL, NULL, sconn->sock);
1355 silc_server_disconnect_remote(server, sconn->sock,
1356 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1357 if (sconn->callback)
1358 (*sconn->callback)(server, NULL, sconn->callback_context);
1359 silc_server_connection_free(sconn);
1364 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1367 case SILC_CONN_ROUTER:
1368 SILC_LOG_DEBUG(("Remote is SILC router"));
1370 /* Register to network */
1371 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1372 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1373 SILC_STR_UI_SHORT(id_len),
1374 SILC_STR_DATA(id, id_len),
1375 SILC_STR_UI_SHORT(strlen(server->server_name)),
1376 SILC_STR_DATA(server->server_name,
1377 strlen(server->server_name)),
1379 silc_server_disconnect_remote(server, sconn->sock,
1380 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1381 if (sconn->callback)
1382 (*sconn->callback)(server, NULL, sconn->callback_context);
1383 silc_server_connection_free(sconn);
1389 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1391 /* Check that we do not have this ID already */
1392 id_entry = silc_idlist_find_server_by_id(server->local_list,
1393 &remote_id.u.server_id,
1396 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1398 id_entry = silc_idlist_find_server_by_id(server->global_list,
1399 &remote_id.u.server_id,
1402 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1406 SILC_LOG_DEBUG(("New server id(%s)",
1407 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1409 /* Add the connected router to global server list. Router is sent
1410 as NULL since it's local to us. */
1411 id_entry = silc_idlist_add_server(server->global_list,
1412 strdup(sconn->remote_host),
1414 silc_id_dup(&remote_id.u.server_id,
1418 silc_server_disconnect_remote(server, sconn->sock,
1419 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1420 if (sconn->callback)
1421 (*sconn->callback)(server, NULL, sconn->callback_context);
1422 silc_server_connection_free(sconn);
1428 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1429 idata = (SilcIDListData)id_entry;
1430 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1431 SILC_IDLIST_STATUS_LOCAL);
1432 idata->sconn = sconn;
1434 if (!sconn->backup) {
1435 /* Mark this router our primary router if we're still standalone */
1436 if (server->standalone) {
1437 SILC_LOG_DEBUG(("This connection is our primary router"));
1438 server->id_entry->router = id_entry;
1439 server->router = id_entry;
1440 server->router->server_type = SILC_ROUTER;
1441 server->standalone = FALSE;
1442 server->backup_primary = FALSE;
1444 /* Announce data if we are not backup router (unless not as primary
1445 currently). Backup router announces later at the end of
1446 resuming protocol. */
1447 if (server->backup_router && server->server_type == SILC_ROUTER) {
1448 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1450 /* If we are router then announce our possible servers. Backup
1451 router announces also global servers. */
1452 if (server->server_type == SILC_ROUTER)
1453 silc_server_announce_servers(server,
1454 server->backup_router ? TRUE : FALSE,
1455 0, SILC_PRIMARY_ROUTE(server));
1457 /* Announce our clients and channels to the router */
1458 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1459 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1462 /* If we are backup router then this primary router is whom we are
1464 if (server->server_type == SILC_BACKUP_ROUTER) {
1465 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1467 NULL, NULL, &ip, NULL);
1468 silc_server_backup_add(server, server->id_entry, ip,
1469 sconn->remote_port, TRUE);
1472 /* We already have primary router. Disconnect this connection */
1473 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1474 silc_idlist_del_server(server->global_list, id_entry);
1475 silc_server_disconnect_remote(server, sconn->sock,
1476 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1477 if (sconn->callback)
1478 (*sconn->callback)(server, NULL, sconn->callback_context);
1479 silc_server_connection_free(sconn);
1484 /* Add this server to be our backup router */
1485 id_entry->server_type = SILC_BACKUP_ROUTER;
1486 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1487 sconn->backup_replace_port, FALSE);
1493 silc_server_disconnect_remote(server, sconn->sock,
1494 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1495 if (sconn->callback)
1496 (*sconn->callback)(server, NULL, sconn->callback_context);
1497 silc_server_connection_free(sconn);
1502 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1504 conn = sconn->conn.ref_ptr;
1505 param = &server->config->param;
1506 if (conn && conn->param)
1507 param = conn->param;
1509 /* Register rekey timeout */
1510 sconn->rekey_timeout = param->key_exchange_rekey;
1511 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1512 sconn->sock, sconn->rekey_timeout, 0);
1514 /* Set the entry as packet stream context */
1515 silc_packet_set_context(sconn->sock, id_entry);
1518 /* Call the completion callback to indicate that we've connected to
1520 if (sconn && sconn->callback)
1521 (*sconn->callback)(server, id_entry, sconn->callback_context);
1523 /* Free the temporary connection data context */
1525 silc_server_config_unref(&sconn->conn);
1526 silc_free(sconn->remote_host);
1527 silc_free(sconn->backup_replace_ip);
1530 if (sconn == server->router_conn)
1531 server->router_conn = NULL;
1536 /* SKE completion callback */
1538 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1539 SilcSKESecurityProperties prop,
1540 SilcSKEKeyMaterial keymat,
1541 SilcSKERekeyMaterial rekey,
1544 SilcPacketStream sock = context;
1545 SilcUnknownEntry entry = silc_packet_get_context(sock);
1546 SilcServerConnection sconn = silc_ske_get_context(ske);
1547 SilcServer server = entry->server;
1548 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1549 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1550 void *auth_data = NULL;
1551 SilcUInt32 auth_data_len = 0;
1552 SilcConnAuth connauth;
1553 SilcCipher send_key, receive_key;
1554 SilcHmac hmac_send, hmac_receive;
1559 if (status != SILC_SKE_STATUS_OK) {
1561 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1562 silc_ske_map_status(status), entry->hostname, entry->ip));
1564 /* XXX retry connecting */
1566 silc_server_disconnect_remote(server, sconn->sock,
1567 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1568 if (sconn->callback)
1569 (*sconn->callback)(server, NULL, sconn->callback_context);
1570 silc_server_connection_free(sconn);
1574 SILC_LOG_DEBUG(("Setting keys into use"));
1576 /* Set the keys into use. The data will be encrypted after this. */
1577 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1578 &hmac_send, &hmac_receive, &hash)) {
1580 /* XXX retry connecting */
1582 /* Error setting keys */
1584 silc_server_disconnect_remote(server, sconn->sock,
1585 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1586 if (sconn->callback)
1587 (*sconn->callback)(server, NULL, sconn->callback_context);
1588 silc_server_connection_free(sconn);
1591 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1592 hmac_receive, FALSE);
1594 SILC_LOG_DEBUG(("Starting connection authentication"));
1596 connauth = silc_connauth_alloc(server->schedule, ske,
1597 server->config->conn_auth_timeout);
1599 /* XXX retry connecting */
1601 /** Error allocating auth protocol */
1603 silc_server_disconnect_remote(server, sconn->sock,
1604 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1605 if (sconn->callback)
1606 (*sconn->callback)(server, NULL, sconn->callback_context);
1607 silc_server_connection_free(sconn);
1611 /* Get authentication method */
1613 if (conn->passphrase) {
1614 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1615 auth_meth = SILC_AUTH_PUBLIC_KEY;
1616 auth_data = server->private_key;
1618 auth_meth = SILC_AUTH_PASSWORD;
1619 auth_data = conn->passphrase;
1620 auth_data_len = conn->passphrase_len;
1623 auth_meth = SILC_AUTH_PUBLIC_KEY;
1624 auth_data = server->private_key;
1628 /* Start connection authentication */
1630 silc_connauth_initiator(connauth, server->server_type == SILC_ROUTER ?
1631 SILC_CONN_ROUTER : SILC_CONN_SERVER, auth_meth,
1632 auth_data, auth_data_len,
1633 silc_server_ke_auth_compl, sconn);
1636 /* Function that is called when the network connection to a router has
1637 been established. This will continue with the key exchange protocol
1638 with the remote router. */
1640 void silc_server_start_key_exchange(SilcServerConnection sconn)
1642 SilcServer server = sconn->server;
1643 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1644 SilcUnknownEntry entry;
1645 SilcSKEParamsStruct params;
1648 /* Cancel any possible retry timeouts */
1649 silc_schedule_task_del_by_context(server->schedule, sconn);
1651 /* Create packet stream */
1652 sconn->sock = silc_packet_stream_create(server->packet_engine,
1653 server->schedule, sconn->stream);
1655 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1656 silc_stream_destroy(sconn->stream);
1657 if (sconn->callback)
1658 (*sconn->callback)(server, NULL, sconn->callback_context);
1659 silc_server_connection_free(sconn);
1662 server->stat.conn_num++;
1664 /* Set source ID to packet stream */
1665 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1667 silc_packet_stream_destroy(sconn->sock);
1668 if (sconn->callback)
1669 (*sconn->callback)(server, NULL, sconn->callback_context);
1670 silc_server_connection_free(sconn);
1674 /* Create entry for remote entity */
1675 entry = silc_calloc(1, sizeof(*entry));
1677 silc_packet_stream_destroy(sconn->sock);
1678 silc_server_connection_free(sconn);
1681 entry->server = server;
1682 silc_packet_set_context(sconn->sock, entry);
1684 /* Set Key Exchange flags from configuration, but fall back to global
1686 memset(¶ms, 0, sizeof(params));
1687 SILC_GET_SKE_FLAGS(conn, params.flags);
1688 if (server->config->param.key_exchange_pfs)
1689 params.flags |= SILC_SKE_SP_FLAG_PFS;
1691 /* Start SILC Key Exchange protocol */
1692 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1693 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1694 server->public_key, server->private_key, sconn);
1697 silc_packet_stream_destroy(sconn->sock);
1698 if (sconn->callback)
1699 (*sconn->callback)(server, NULL, sconn->callback_context);
1700 silc_server_connection_free(sconn);
1703 silc_ske_set_callbacks(ske, silc_server_verify_key,
1704 silc_server_ke_completed, sconn->sock);
1706 /* Start key exchange protocol */
1707 params.version = silc_version_string;
1708 params.timeout_secs = server->config->key_exchange_timeout;
1709 sconn->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1712 /* Timeout callback that will be called to retry connecting to remote
1713 router. This is used by both normal and router server. This will wait
1714 before retrying the connecting. The timeout is generated by exponential
1715 backoff algorithm. */
1717 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1719 SilcServerConnection sconn = context;
1720 SilcServer server = sconn->server;
1721 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1722 SilcServerConfigConnParams *param =
1723 (conn->param ? conn->param : &server->config->param);
1725 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1726 sconn->remote_port));
1728 /* Calculate next timeout */
1729 if (sconn->retry_count >= 1) {
1730 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1731 if (sconn->retry_timeout > param->reconnect_interval_max)
1732 sconn->retry_timeout = param->reconnect_interval_max;
1734 sconn->retry_timeout = param->reconnect_interval;
1736 sconn->retry_count++;
1737 sconn->retry_timeout = sconn->retry_timeout +
1738 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1740 /* If we've reached max retry count, give up. */
1741 if ((sconn->retry_count > param->reconnect_count) &&
1742 !param->reconnect_keep_trying) {
1743 SILC_LOG_ERROR(("Could not connect, giving up"));
1745 if (sconn->callback)
1746 (*sconn->callback)(server, NULL, sconn->callback_context);
1747 silc_server_connection_free(sconn);
1751 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1753 /* We will lookup a fresh pointer later */
1754 silc_server_config_unref(&sconn->conn);
1756 /* Wait before retrying */
1757 silc_schedule_task_del_by_context(server->schedule, sconn);
1758 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1759 sconn, sconn->retry_timeout, 0);
1762 /* Callback for async connection to remote router */
1764 static void silc_server_connection_established(SilcNetStatus status,
1768 SilcServerConnection sconn = context;
1769 SilcServer server = sconn->server;
1771 silc_schedule_task_del_by_context(server->schedule, sconn);
1776 SILC_LOG_DEBUG(("Connection to %s:%d established",
1777 sconn->remote_host, sconn->remote_port));
1779 /* Continue with key exchange protocol */
1780 sconn->stream = stream;
1781 silc_server_start_key_exchange(sconn);
1784 case SILC_NET_UNKNOWN_IP:
1785 case SILC_NET_UNKNOWN_HOST:
1786 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1787 sconn->remote_host, sconn->remote_port,
1788 silc_net_get_error_string(status)));
1790 if (sconn->callback)
1791 (*sconn->callback)(server, NULL, sconn->callback_context);
1792 silc_server_connection_free(sconn);
1796 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1797 sconn->remote_host, sconn->remote_port,
1798 silc_net_get_error_string(status)));
1799 if (!sconn->no_reconnect) {
1800 silc_schedule_task_add_timeout(sconn->server->schedule,
1801 silc_server_connect_to_router_retry,
1804 if (sconn->callback)
1805 (*sconn->callback)(server, NULL, sconn->callback_context);
1806 silc_server_connection_free(sconn);
1812 /* Generic routine to use connect to a router. */
1814 SILC_TASK_CALLBACK(silc_server_connect_router)
1816 SilcServerConnection sconn = context;
1817 SilcServer server = sconn->server;
1818 SilcServerConfigRouter *rconn;
1820 silc_schedule_task_del_by_context(server->schedule, sconn);
1822 /* Don't connect if we are shutting down. */
1823 if (server->server_shutdown) {
1824 if (sconn->callback)
1825 (*sconn->callback)(server, NULL, sconn->callback_context);
1826 silc_server_connection_free(sconn);
1830 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1831 (sconn->backup ? "backup router" : "router"),
1832 sconn->remote_host, sconn->remote_port));
1834 if (!sconn->no_conf) {
1835 /* Find connection configuration */
1836 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1837 sconn->remote_port);
1839 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1840 (sconn->backup ? "backup router" : "router"),
1841 sconn->remote_host, sconn->remote_port));
1842 silc_server_connection_free(sconn);
1845 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1848 /* Connect to remote host */
1850 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1851 server->config->server_info->primary->server_ip),
1852 sconn->remote_host, sconn->remote_port,
1853 server->schedule, silc_server_connection_established,
1856 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1857 sconn->remote_host, sconn->remote_port));
1858 silc_server_connection_free(sconn);
1862 /* Add to connection list */
1863 silc_dlist_add(server->conns, sconn);
1866 /* This function connects to our primary router or if we are a router this
1867 establishes all our primary routes. This is called at the start of the
1868 server to do authentication and key exchange with our router - called
1871 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1873 SilcServer server = context;
1874 SilcServerConnection sconn;
1875 SilcServerConfigRouter *ptr;
1877 /* Don't connect if we are shutting down. */
1878 if (server->server_shutdown)
1881 SILC_LOG_DEBUG(("We are %s",
1882 (server->server_type == SILC_SERVER ?
1883 "normal server" : server->server_type == SILC_ROUTER ?
1884 "router" : "backup router/normal server")));
1887 if (!server->config->routers) {
1888 /* There wasn't a configured router, we will continue but we don't
1889 have a connection to outside world. We will be standalone server. */
1890 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1891 server->standalone = TRUE;
1895 /* Create the connections to all our routes */
1896 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1898 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1899 ptr->backup_router ? "Backup router" : "Router",
1900 ptr->initiator ? "Initiator" : "Responder",
1901 ptr->host, ptr->port));
1903 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1904 ptr->initiator == FALSE && !server->backup_router &&
1905 !silc_server_config_get_backup_router(server))
1906 server->wait_backup = TRUE;
1908 if (!ptr->initiator)
1910 if (ptr->dynamic_connection)
1913 /* Check whether we are connecting or connected to this host already */
1914 if (silc_server_num_sockets_by_remote(server,
1915 silc_net_is_ip(ptr->host) ?
1917 silc_net_is_ip(ptr->host) ?
1918 NULL : ptr->host, ptr->port,
1919 SILC_CONN_ROUTER)) {
1920 SILC_LOG_DEBUG(("We are already connected to %s:%d",
1921 ptr->host, ptr->port));
1923 /* If we don't have primary router and this connection is our
1924 primary router we are in desync. Reconnect to the primary. */
1925 if (server->standalone && !server->router) {
1927 SilcPacketStream sock;
1928 SilcServerConfigRouter *primary =
1929 silc_server_config_get_primary_router(server);
1932 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1933 ptr->host, ptr->port);
1936 server->backup_noswitch = TRUE;
1937 silc_server_free_sock_user_data(server, sock, NULL);
1938 silc_server_disconnect_remote(server, sock, 0, NULL);
1939 server->backup_noswitch = FALSE;
1940 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1946 /* Allocate connection object for hold connection specific stuff. */
1947 sconn = silc_calloc(1, sizeof(*sconn));
1950 sconn->remote_host = strdup(ptr->host);
1951 sconn->remote_port = ptr->port;
1952 sconn->backup = ptr->backup_router;
1953 if (sconn->backup) {
1954 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1955 sconn->backup_replace_port = ptr->backup_replace_port;
1958 SILC_LOG_DEBUG(("Created connection %p", sconn));
1961 if (!server->router_conn && !sconn->backup)
1962 server->router_conn = sconn;
1965 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
1971 /************************ Accepting new connection **************************/
1973 /* After this is called, server don't wait for backup router anymore.
1974 This gets called automatically even after we have backup router
1975 connection established. */
1977 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
1979 SilcServer server = context;
1980 server->wait_backup = FALSE;
1983 /* Authentication data callback */
1986 silc_server_accept_get_auth(SilcConnAuth connauth,
1987 SilcConnectionType conn_type,
1988 unsigned char **passphrase,
1989 SilcUInt32 *passphrase_len,
1990 SilcSKR *repository,
1993 SilcPacketStream sock = context;
1994 SilcUnknownEntry entry = silc_packet_get_context(sock);
1995 SilcServer server = entry->server;
1997 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
1999 /* Remote end is client */
2000 if (conn_type == SILC_CONN_CLIENT) {
2001 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2005 *passphrase = cconfig->passphrase;
2006 *passphrase_len = cconfig->passphrase_len;
2007 if (cconfig->publickeys)
2008 *repository = server->repository;
2010 entry->data.conn_type = conn_type;
2014 /* Remote end is server */
2015 if (conn_type == SILC_CONN_SERVER) {
2016 SilcServerConfigServer *sconfig;
2018 /* If we are normal server, don't accept the connection */
2019 if (server->server_type == SILC_SERVER)
2022 sconfig = entry->sconfig.ref_ptr;
2026 *passphrase = sconfig->passphrase;
2027 *passphrase_len = sconfig->passphrase_len;
2028 if (sconfig->publickeys)
2029 *repository = server->repository;
2031 entry->data.conn_type = conn_type;
2035 /* Remote end is router */
2036 if (conn_type == SILC_CONN_ROUTER) {
2037 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2041 *passphrase = rconfig->passphrase;
2042 *passphrase_len = rconfig->passphrase_len;
2043 if (rconfig->publickeys)
2044 *repository = server->repository;
2046 entry->data.conn_type = conn_type;
2053 /* Authentication completion callback. */
2056 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2059 SilcPacketStream sock = context;
2060 SilcUnknownEntry entry = silc_packet_get_context(sock);
2061 SilcIDListData idata = (SilcIDListData)entry;
2062 SilcServer server = entry->server;
2063 SilcServerConfigConnParams *param = &server->config->param;
2064 SilcServerConnection sconn;
2066 const char *hostname, *ip;
2070 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2071 NULL, &hostname, &ip, &port);
2073 if (success == FALSE) {
2074 /* Authentication failed */
2075 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2076 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2077 server->stat.auth_failures++;
2078 silc_server_disconnect_remote(server, sock,
2079 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2083 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2085 switch (entry->data.conn_type) {
2086 case SILC_CONN_CLIENT:
2088 SilcClientEntry client;
2089 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2091 /* Verify whether this connection is after all allowed to connect */
2092 if (!silc_server_connection_allowed(server, sock, entry->data.conn_type,
2093 &server->config->param,
2095 silc_connauth_get_ske(connauth))) {
2096 server->stat.auth_failures++;
2100 /* If we are primary router and we have backup router configured
2101 but it has not connected to use yet, do not accept any other
2103 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2104 !server->backup_router) {
2105 SilcServerConfigRouter *router;
2106 router = silc_server_config_get_backup_router(server);
2107 if (router && strcmp(server->config->server_info->primary->server_ip,
2109 silc_server_find_socket_by_host(server,
2111 router->backup_replace_ip, 0)) {
2112 SILC_LOG_INFO(("Will not accept connections because we do "
2113 "not have backup router connection established"));
2114 silc_server_disconnect_remote(server, sock,
2115 SILC_STATUS_ERR_PERM_DENIED,
2116 "We do not have connection to backup "
2117 "router established, try later");
2118 server->stat.auth_failures++;
2120 /* From here on, wait 20 seconds for the backup router to appear. */
2121 silc_schedule_task_add_timeout(server->schedule,
2122 silc_server_backup_router_wait,
2123 (void *)server, 20, 0);
2128 SILC_LOG_DEBUG(("Remote host is client"));
2129 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2132 /* Add the client to the client ID cache. The nickname and Client ID
2133 and other information is created after we have received NEW_CLIENT
2134 packet from client. */
2135 client = silc_idlist_add_client(server->local_list,
2136 NULL, NULL, NULL, NULL, NULL, sock);
2138 SILC_LOG_ERROR(("Could not add new client to cache"));
2139 server->stat.auth_failures++;
2140 silc_server_disconnect_remote(server, sock,
2141 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2144 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2147 server->stat.my_clients++;
2148 server->stat.clients++;
2149 server->stat.cell_clients++;
2151 /* Get connection parameters */
2153 param = conn->param;
2155 if (!param->keepalive_secs)
2156 param->keepalive_secs = server->config->param.keepalive_secs;
2158 if (!param->qos && server->config->param.qos) {
2159 param->qos = server->config->param.qos;
2160 param->qos_rate_limit = server->config->param.qos_rate_limit;
2161 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2162 param->qos_limit_sec = server->config->param.qos_limit_sec;
2163 param->qos_limit_usec = server->config->param.qos_limit_usec;
2166 /* Check if to be anonymous connection */
2167 if (param->anonymous)
2168 client->mode |= SILC_UMODE_ANONYMOUS;
2171 /* Add public key to repository */
2172 if (!silc_server_get_public_key_by_client(server, client, NULL))
2173 silc_skr_add_public_key_simple(server->repository,
2174 entry->data.public_key,
2175 SILC_SKR_USAGE_IDENTIFICATION, client,
2178 id_entry = (void *)client;
2182 case SILC_CONN_SERVER:
2183 case SILC_CONN_ROUTER:
2185 SilcServerEntry new_server;
2186 SilcBool initiator = FALSE;
2187 SilcBool backup_local = FALSE;
2188 SilcBool backup_router = FALSE;
2189 char *backup_replace_ip = NULL;
2190 SilcUInt16 backup_replace_port = 0;
2191 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2192 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2194 /* If we are backup router and this is incoming server connection
2195 and we do not have connection to primary router, do not allow
2197 if (server->server_type == SILC_BACKUP_ROUTER &&
2198 entry->data.conn_type == SILC_CONN_SERVER &&
2199 !SILC_PRIMARY_ROUTE(server)) {
2200 SILC_LOG_INFO(("Will not accept server connection because we do "
2201 "not have primary router connection established"));
2202 silc_server_disconnect_remote(server, sock,
2203 SILC_STATUS_ERR_PERM_DENIED,
2204 "We do not have connection to primary "
2205 "router established, try later");
2206 server->stat.auth_failures++;
2210 if (entry->data.conn_type == SILC_CONN_ROUTER) {
2211 /* Verify whether this connection is after all allowed to connect */
2212 if (!silc_server_connection_allowed(server, sock,
2213 entry->data.conn_type,
2214 &server->config->param,
2215 rconn ? rconn->param : NULL,
2216 silc_connauth_get_ske(connauth))) {
2217 server->stat.auth_failures++;
2223 param = rconn->param;
2225 if (!param->keepalive_secs)
2226 param->keepalive_secs = server->config->param.keepalive_secs;
2228 if (!param->qos && server->config->param.qos) {
2229 param->qos = server->config->param.qos;
2230 param->qos_rate_limit = server->config->param.qos_rate_limit;
2231 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2232 param->qos_limit_sec = server->config->param.qos_limit_sec;
2233 param->qos_limit_usec = server->config->param.qos_limit_usec;
2237 initiator = rconn->initiator;
2238 backup_local = rconn->backup_local;
2239 backup_router = rconn->backup_router;
2240 backup_replace_ip = rconn->backup_replace_ip;
2241 backup_replace_port = rconn->backup_replace_port;
2245 if (entry->data.conn_type == SILC_CONN_SERVER) {
2246 /* Verify whether this connection is after all allowed to connect */
2247 if (!silc_server_connection_allowed(server, sock,
2248 entry->data.conn_type,
2249 &server->config->param,
2250 srvconn ? srvconn->param : NULL,
2251 silc_connauth_get_ske(connauth))) {
2252 server->stat.auth_failures++;
2256 if (srvconn->param) {
2257 param = srvconn->param;
2259 if (!param->keepalive_secs)
2260 param->keepalive_secs = server->config->param.keepalive_secs;
2262 if (!param->qos && server->config->param.qos) {
2263 param->qos = server->config->param.qos;
2264 param->qos_rate_limit = server->config->param.qos_rate_limit;
2265 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2266 param->qos_limit_sec = server->config->param.qos_limit_sec;
2267 param->qos_limit_usec = server->config->param.qos_limit_usec;
2271 backup_router = srvconn->backup_router;
2275 /* If we are primary router and we have backup router configured
2276 but it has not connected to use yet, do not accept any other
2278 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2279 !server->backup_router && !backup_router) {
2280 SilcServerConfigRouter *router;
2281 router = silc_server_config_get_backup_router(server);
2282 if (router && strcmp(server->config->server_info->primary->server_ip,
2284 silc_server_find_socket_by_host(server,
2286 router->backup_replace_ip, 0)) {
2287 SILC_LOG_INFO(("Will not accept connections because we do "
2288 "not have backup router connection established"));
2289 silc_server_disconnect_remote(server, sock,
2290 SILC_STATUS_ERR_PERM_DENIED,
2291 "We do not have connection to backup "
2292 "router established, try later");
2293 server->stat.auth_failures++;
2295 /* From here on, wait 20 seconds for the backup router to appear. */
2296 silc_schedule_task_add_timeout(server->schedule,
2297 silc_server_backup_router_wait,
2298 (void *)server, 20, 0);
2303 SILC_LOG_DEBUG(("Remote host is %s",
2304 entry->data.conn_type == SILC_CONN_SERVER ?
2305 "server" : (backup_router ?
2306 "backup router" : "router")));
2307 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2308 entry->ip, entry->data.conn_type == SILC_CONN_SERVER ?
2309 "server" : (backup_router ?
2310 "backup router" : "router")));
2312 /* Add the server into server cache. The server name and Server ID
2313 is updated after we have received NEW_SERVER packet from the
2314 server. We mark ourselves as router for this server if we really
2317 silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ?
2318 server->local_list : (backup_router ?
2319 server->local_list :
2320 server->global_list)),
2322 (entry->data.conn_type == SILC_CONN_SERVER ?
2323 SILC_SERVER : SILC_ROUTER),
2325 (entry->data.conn_type == SILC_CONN_SERVER ?
2326 server->id_entry : (backup_router ?
2327 server->id_entry : NULL)),
2330 SILC_LOG_ERROR(("Could not add new server to cache"));
2331 silc_server_disconnect_remote(server, sock,
2332 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2333 server->stat.auth_failures++;
2336 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2338 id_entry = (void *)new_server;
2340 /* If the incoming connection is router and marked as backup router
2341 then add it to be one of our backups */
2342 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2343 /* Change it back to SERVER type since that's what it really is. */
2345 entry->data.conn_type = SILC_CONN_SERVER;
2346 new_server->server_type = SILC_BACKUP_ROUTER;
2348 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2349 ("Backup router %s is now online",
2352 /* Remove the backup waiting with timeout */
2353 silc_schedule_task_add_timeout(server->schedule,
2354 silc_server_backup_router_wait,
2355 (void *)server, 10, 0);
2359 if (entry->data.conn_type == SILC_CONN_SERVER) {
2360 server->stat.my_servers++;
2361 server->stat.servers++;
2363 server->stat.my_routers++;
2364 server->stat.routers++;
2367 /* Check whether this connection is to be our primary router connection
2368 if we do not already have the primary route. */
2369 if (!backup_router &&
2370 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2371 if (silc_server_config_is_primary_route(server) && !initiator)
2374 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2375 server->standalone = FALSE;
2376 if (!server->id_entry->router) {
2377 server->id_entry->router = id_entry;
2378 server->router = id_entry;
2390 /* Add connection to server->conns so that we know we have connection
2392 sconn = silc_calloc(1, sizeof(*sconn));
2393 sconn->server = server;
2395 sconn->remote_host = strdup(hostname);
2396 sconn->remote_port = port;
2397 silc_dlist_add(server->conns, sconn);
2398 idata->sconn = sconn;
2399 idata->last_receive = time(NULL);
2401 /* Add the common data structure to the ID entry. */
2402 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2403 silc_packet_set_context(sock, id_entry);
2405 /* Connection has been fully established now. Everything is ok. */
2406 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2408 /* Perform Quality of Service */
2410 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2411 param->qos_rate_limit, param->qos_bytes_limit,
2412 param->qos_limit_sec, param->qos_limit_usec);
2414 silc_server_config_unref(&entry->cconfig);
2415 silc_server_config_unref(&entry->sconfig);
2416 silc_server_config_unref(&entry->rconfig);
2420 silc_ske_free(silc_connauth_get_ske(connauth));
2421 silc_connauth_free(connauth);
2424 /* SKE completion callback. We set the new keys into use here. */
2427 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2428 SilcSKESecurityProperties prop,
2429 SilcSKEKeyMaterial keymat,
2430 SilcSKERekeyMaterial rekey,
2433 SilcPacketStream sock = context;
2434 SilcUnknownEntry entry = silc_packet_get_context(sock);
2435 SilcIDListData idata = (SilcIDListData)entry;
2436 SilcServer server = entry->server;
2437 SilcConnAuth connauth;
2438 SilcCipher send_key, receive_key;
2439 SilcHmac hmac_send, hmac_receive;
2446 if (status != SILC_SKE_STATUS_OK) {
2448 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2449 silc_ske_map_status(status), entry->hostname, entry->ip));
2451 silc_server_disconnect_remote(server, sock,
2452 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2456 SILC_LOG_DEBUG(("Setting keys into use"));
2458 /* Set the keys into use. The data will be encrypted after this. */
2459 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2460 &hmac_send, &hmac_receive, &hash)) {
2461 /* Error setting keys */
2463 silc_server_disconnect_remote(server, sock,
2464 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2467 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2468 hmac_receive, FALSE);
2470 idata->rekey = rekey;
2471 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2472 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2473 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2475 SILC_LOG_DEBUG(("Starting connection authentication"));
2476 server->stat.auth_attempts++;
2478 connauth = silc_connauth_alloc(server->schedule, ske,
2479 server->config->conn_auth_timeout);
2481 /** Error allocating auth protocol */
2483 silc_server_disconnect_remote(server, sock,
2484 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2488 /* Start connection authentication */
2490 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2491 silc_server_accept_auth_compl, sock);
2494 /* Accept new TCP connection */
2496 static void silc_server_accept_new_connection(SilcNetStatus status,
2500 SilcServer server = context;
2501 SilcPacketStream packet_stream;
2502 SilcServerConfigClient *cconfig = NULL;
2503 SilcServerConfigServer *sconfig = NULL;
2504 SilcServerConfigRouter *rconfig = NULL;
2505 SilcServerConfigDeny *deny;
2506 SilcUnknownEntry entry;
2508 SilcSKEParamsStruct params;
2509 char *hostname, *ip;
2512 SILC_LOG_DEBUG(("Accepting new connection"));
2514 /* Check for maximum allowed connections */
2515 server->stat.conn_attempts++;
2516 if (silc_dlist_count(server->conns) >
2517 server->config->param.connections_max) {
2518 SILC_LOG_ERROR(("Refusing connection, server is full"));
2519 server->stat.conn_failures++;
2520 silc_stream_destroy(stream);
2524 /* Get hostname, IP and port */
2525 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2526 (const char **)&ip, &port)) {
2527 /* Bad socket stream */
2528 server->stat.conn_failures++;
2529 silc_stream_destroy(stream);
2533 /* Create packet stream */
2534 packet_stream = silc_packet_stream_create(server->packet_engine,
2535 server->schedule, stream);
2536 if (!packet_stream) {
2537 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2538 server->stat.conn_failures++;
2539 silc_stream_destroy(stream);
2542 server->stat.conn_num++;
2544 /* Set source ID to packet stream */
2545 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2548 server->stat.conn_failures++;
2549 silc_packet_stream_destroy(packet_stream);
2553 /* Check whether this connection is denied to connect to us. */
2554 deny = silc_server_config_find_denied(server, ip);
2556 deny = silc_server_config_find_denied(server, hostname);
2558 /* The connection is denied */
2559 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2560 silc_server_disconnect_remote(server, packet_stream,
2561 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2566 /* Check whether we have configured this sort of connection at all. We
2567 have to check all configurations since we don't know what type of
2568 connection this is. */
2569 if (!(cconfig = silc_server_config_find_client(server, ip)))
2570 cconfig = silc_server_config_find_client(server, hostname);
2571 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2572 sconfig = silc_server_config_find_server_conn(server, hostname);
2573 if (server->server_type == SILC_ROUTER)
2574 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2575 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2576 if (!cconfig && !sconfig && !rconfig) {
2577 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2578 server->stat.conn_failures++;
2579 silc_server_disconnect_remote(server, packet_stream,
2580 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2584 /* The connection is allowed */
2585 entry = silc_calloc(1, sizeof(*entry));
2587 server->stat.conn_failures++;
2588 silc_server_disconnect_remote(server, packet_stream,
2589 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2592 entry->hostname = hostname;
2595 entry->server = server;
2596 entry->data.conn_type = SILC_CONN_UNKNOWN;
2597 silc_packet_set_context(packet_stream, entry);
2599 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2600 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2601 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2603 /* Take flags for key exchange. Since we do not know what type of connection
2604 this is, we go through all found configurations and use the global ones
2605 as well. This will result always into strictest key exchange flags. */
2606 memset(¶ms, 0, sizeof(params));
2607 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2608 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2609 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2610 if (server->config->param.key_exchange_pfs)
2611 params.flags |= SILC_SKE_SP_FLAG_PFS;
2613 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2614 server->stat.conn_attempts++;
2616 /* Start SILC Key Exchange protocol */
2617 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2618 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2619 server->public_key, server->private_key,
2622 server->stat.conn_failures++;
2623 silc_server_disconnect_remote(server, packet_stream,
2624 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2627 silc_ske_set_callbacks(ske, silc_server_verify_key,
2628 silc_server_accept_completed, packet_stream);
2630 /* Start key exchange protocol */
2631 params.version = silc_version_string;
2632 params.timeout_secs = server->config->key_exchange_timeout;
2633 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2637 /********************************** Rekey ***********************************/
2639 /* Initiator rekey completion callback */
2641 static void silc_server_rekey_completion(SilcSKE ske,
2642 SilcSKEStatus status,
2643 const SilcSKESecurityProperties prop,
2644 const SilcSKEKeyMaterial keymat,
2645 SilcSKERekeyMaterial rekey,
2648 SilcPacketStream sock = context;
2649 SilcIDListData idata = silc_packet_get_context(sock);
2650 SilcServer server = idata->sconn->server;
2652 idata->sconn->op = NULL;
2653 if (status != SILC_SKE_STATUS_OK) {
2654 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2655 idata->sconn->remote_host));
2659 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2660 idata->sconn->remote_host, idata->sconn->remote_port,
2661 SILC_CONNTYPE_STRING(idata->conn_type)));
2663 /* Save rekey data for next rekey */
2664 idata->rekey = rekey;
2666 /* Register new rekey timeout */
2667 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2668 sock, idata->sconn->rekey_timeout, 0);
2671 /* Rekey callback. Start rekey as initiator */
2673 SILC_TASK_CALLBACK(silc_server_do_rekey)
2675 SilcServer server = app_context;
2676 SilcPacketStream sock = context;
2677 SilcIDListData idata = silc_packet_get_context(sock);
2680 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2682 /* Do not execute rekey with disabled connections */
2683 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2686 /* If another protocol is active do not start rekey */
2687 if (idata->sconn->op) {
2688 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2689 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2694 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2695 idata->sconn->remote_host, idata->sconn->remote_port,
2696 SILC_CONNTYPE_STRING(idata->conn_type)));
2699 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2700 server->public_key, server->private_key, sock);
2704 /* Set SKE callbacks */
2705 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2708 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2711 /* Responder rekey completion callback */
2714 silc_server_rekey_resp_completion(SilcSKE ske,
2715 SilcSKEStatus status,
2716 const SilcSKESecurityProperties prop,
2717 const SilcSKEKeyMaterial keymat,
2718 SilcSKERekeyMaterial rekey,
2721 SilcPacketStream sock = context;
2722 SilcIDListData idata = silc_packet_get_context(sock);
2724 idata->sconn->op = NULL;
2725 if (status != SILC_SKE_STATUS_OK) {
2726 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2727 idata->sconn->remote_host));
2731 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2732 idata->sconn->remote_host, idata->sconn->remote_port,
2733 SILC_CONNTYPE_STRING(idata->conn_type)));
2735 /* Save rekey data for next rekey */
2736 idata->rekey = rekey;
2739 /* Start rekey as responder */
2741 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2744 SilcIDListData idata = silc_packet_get_context(sock);
2747 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2748 idata->sconn->remote_host, idata->sconn->remote_port,
2749 SILC_CONNTYPE_STRING(idata->conn_type)));
2752 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2753 server->public_key, server->private_key, sock);
2755 silc_packet_free(packet);
2759 /* Set SKE callbacks */
2760 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2763 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2768 /****************************** Disconnection *******************************/
2770 /* Destroys packet stream. */
2772 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2774 silc_packet_stream_destroy(context);
2777 /* Closes connection to socket connection */
2779 void silc_server_close_connection(SilcServer server,
2780 SilcPacketStream sock)
2782 SilcIDListData idata = silc_packet_get_context(sock);
2784 const char *hostname;
2787 memset(tmp, 0, sizeof(tmp));
2788 // silc_socket_get_error(sock, tmp, sizeof(tmp));
2789 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2790 NULL, &hostname, NULL, &port);
2791 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2792 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
2793 tmp[0] ? tmp : ""));
2795 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2797 if (idata && idata->sconn) {
2798 silc_server_connection_free(idata->sconn);
2799 idata->sconn = NULL;
2802 /* Close connection with timeout */
2803 server->stat.conn_num--;
2804 silc_schedule_task_del_by_all(server->schedule, 0,
2805 silc_server_close_connection_final, sock);
2806 silc_schedule_task_add_timeout(server->schedule,
2807 silc_server_close_connection_final,
2811 /* Sends disconnect message to remote connection and disconnects the
2814 void silc_server_disconnect_remote(SilcServer server,
2815 SilcPacketStream sock,
2816 SilcStatus status, ...)
2818 unsigned char buf[512];
2825 SILC_LOG_DEBUG(("Disconnecting remote host"));
2827 va_start(ap, status);
2828 cp = va_arg(ap, char *);
2830 silc_vsnprintf(buf, sizeof(buf), cp, ap);
2833 /* Send SILC_PACKET_DISCONNECT */
2834 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2835 SILC_STR_UI_CHAR(status),
2836 SILC_STR_UI8_STRING(cp ? buf : NULL),
2839 /* Close connection */
2840 silc_server_close_connection(server, sock);
2843 /* Frees client data and notifies about client's signoff. */
2845 void silc_server_free_client_data(SilcServer server,
2846 SilcPacketStream sock,
2847 SilcClientEntry client,
2849 const char *signoff)
2851 SILC_LOG_DEBUG(("Freeing client %p data", client));
2854 /* Check if anyone is watching this nickname */
2855 if (server->server_type == SILC_ROUTER)
2856 silc_server_check_watcher_list(server, client, NULL,
2857 SILC_NOTIFY_TYPE_SIGNOFF);
2859 /* Send SIGNOFF notify to routers. */
2861 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2862 SILC_BROADCAST(server), client->id,
2866 /* Remove client from all channels */
2868 silc_server_remove_from_channels(server, NULL, client,
2869 TRUE, (char *)signoff, TRUE, FALSE);
2871 silc_server_remove_from_channels(server, NULL, client,
2872 FALSE, NULL, FALSE, FALSE);
2874 /* Remove this client from watcher list if it is */
2875 silc_server_del_from_watcher_list(server, client);
2877 /* Remove client's public key from repository, this will free it too. */
2878 if (client->data.public_key) {
2879 silc_skr_del_public_key(server->repository, client->data.public_key,
2881 client->data.public_key = NULL;
2884 /* Update statistics */
2885 server->stat.my_clients--;
2886 server->stat.clients--;
2887 if (server->stat.cell_clients)
2888 server->stat.cell_clients--;
2889 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2890 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2891 silc_schedule_task_del_by_context(server->schedule, client);
2893 if (client->data.sconn)
2894 silc_server_connection_free(client->data.sconn);
2896 /* We will not delete the client entry right away. We will take it
2897 into history (for WHOWAS command) for 5 minutes, unless we're
2898 shutting down server. */
2899 if (!server->server_shutdown) {
2900 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2902 client->router = NULL;
2903 client->connection = NULL;
2904 client->data.created = silc_time();
2905 silc_dlist_add(server->expired_clients, client);
2907 /* Delete directly since we're shutting down server */
2908 SILC_LOG_DEBUG(("Delete client directly"));
2909 silc_idlist_del_data(client);
2910 silc_idlist_del_client(server->local_list, client);
2914 /* Frees user_data pointer from socket connection object. This also sends
2915 appropriate notify packets to the network to inform about leaving
2918 void silc_server_free_sock_user_data(SilcServer server,
2919 SilcPacketStream sock,
2920 const char *signoff_message)
2922 SilcIDListData idata = silc_packet_get_context(sock);
2926 SILC_LOG_DEBUG(("Start"));
2931 silc_schedule_task_del_by_context(server->schedule, sock);
2933 /* Cancel active protocols */
2935 if (idata->sconn && idata->sconn->op) {
2936 SILC_LOG_DEBUG(("Abort active protocol"));
2937 silc_async_abort(idata->sconn->op, NULL, NULL);
2939 if (idata->conn_type == SILC_CONN_UNKNOWN &&
2940 ((SilcUnknownEntry)idata)->op) {
2941 SILC_LOG_DEBUG(("Abort active protocol"));
2942 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
2946 switch (idata->conn_type) {
2947 case SILC_CONN_CLIENT:
2949 SilcClientEntry client_entry = (SilcClientEntry)idata;
2950 silc_server_free_client_data(server, sock, client_entry, TRUE,
2952 silc_packet_set_context(sock, NULL);
2956 case SILC_CONN_SERVER:
2957 case SILC_CONN_ROUTER:
2959 SilcServerEntry user_data = (SilcServerEntry)idata;
2960 SilcServerEntry backup_router = NULL;
2962 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
2965 backup_router = silc_server_backup_get(server, user_data->id);
2967 if (!server->backup_router && server->server_type == SILC_ROUTER &&
2968 backup_router == server->id_entry &&
2969 idata->conn_type != SILC_CONN_ROUTER)
2970 backup_router = NULL;
2972 if (server->server_shutdown || server->backup_noswitch)
2973 backup_router = NULL;
2975 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2976 NULL, NULL, &ip, &port);
2978 /* If this was our primary router connection then we're lost to
2979 the outside world. */
2980 if (server->router == user_data) {
2981 /* Check whether we have a backup router connection */
2982 if (!backup_router || backup_router == user_data) {
2983 if (!server->no_reconnect)
2984 silc_server_create_connections(server);
2985 server->id_entry->router = NULL;
2986 server->router = NULL;
2987 server->standalone = TRUE;
2988 server->backup_primary = FALSE;
2989 backup_router = NULL;
2991 if (server->id_entry != backup_router) {
2992 SILC_LOG_INFO(("New primary router is backup router %s",
2993 backup_router->server_name));
2994 server->id_entry->router = backup_router;
2995 server->router = backup_router;
2996 server->router_connect = time(0);
2997 server->backup_primary = TRUE;
2998 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3000 /* Send START_USE to backup router to indicate we have switched */
3001 silc_server_backup_send_start_use(server,
3002 backup_router->connection,
3005 SILC_LOG_INFO(("We are now new primary router in this cell"));
3006 server->id_entry->router = NULL;
3007 server->router = NULL;
3008 server->standalone = TRUE;
3011 /* We stop here to take a breath */
3014 if (server->backup_router) {
3015 server->server_type = SILC_ROUTER;
3017 /* We'll need to constantly try to reconnect to the primary
3018 router so that we'll see when it comes back online. */
3019 silc_server_create_connection(server, FALSE, FALSE, ip, port,
3020 silc_server_backup_connected,
3024 /* Mark this connection as replaced */
3025 silc_server_backup_replaced_add(server, user_data->id,
3028 } else if (backup_router) {
3029 SILC_LOG_INFO(("Enabling the use of backup router %s",
3030 backup_router->server_name));
3032 /* Mark this connection as replaced */
3033 silc_server_backup_replaced_add(server, user_data->id,
3035 } else if (server->server_type == SILC_SERVER &&
3036 idata->conn_type == SILC_CONN_ROUTER) {
3037 /* Reconnect to the router (backup) */
3038 if (!server->no_reconnect)
3039 silc_server_create_connections(server);
3042 if (user_data->server_name)
3043 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3044 ("Server %s signoff", user_data->server_name));
3046 if (!backup_router) {
3047 /* Remove all servers that are originated from this server, and
3048 remove the clients of those servers too. */
3049 silc_server_remove_servers_by_server(server, user_data, TRUE);
3052 /* Remove the clients that this server owns as they will become
3053 invalid now too. For backup router the server is actually
3054 coming from the primary router, so mark that as the owner
3056 if (server->server_type == SILC_BACKUP_ROUTER &&
3057 sock->type == SILC_CONN_SERVER)
3058 silc_server_remove_clients_by_server(server, server->router,
3062 silc_server_remove_clients_by_server(server, user_data,
3065 /* Remove channels owned by this server */
3066 if (server->server_type == SILC_SERVER)
3067 silc_server_remove_channels_by_server(server, user_data);
3069 /* Enable local server connections that may be disabled */
3070 silc_server_local_servers_toggle_enabled(server, TRUE);
3072 /* Update the client entries of this server to the new backup
3073 router. If we are the backup router we also resolve the real
3074 servers for the clients. After updating is over this also
3075 removes the clients that this server explicitly owns. */
3076 silc_server_update_clients_by_server(server, user_data,
3077 backup_router, TRUE);
3079 /* If we are router and just lost our primary router (now standlaone)
3080 we remove everything that was behind it, since we don't know
3082 if (server->server_type == SILC_ROUTER && server->standalone)
3083 /* Remove all servers that are originated from this server, and
3084 remove the clients of those servers too. */
3085 silc_server_remove_servers_by_server(server, user_data, TRUE);
3087 /* Finally remove the clients that are explicitly owned by this
3088 server. They go down with the server. */
3089 silc_server_remove_clients_by_server(server, user_data,
3092 /* Update our server cache to use the new backup router too. */
3093 silc_server_update_servers_by_server(server, user_data, backup_router);
3094 if (server->server_type == SILC_SERVER)
3095 silc_server_update_channels_by_server(server, user_data,
3098 /* Send notify about primary router going down to local operators */
3099 if (server->backup_router)
3100 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3101 SILC_NOTIFY_TYPE_NONE,
3102 ("%s switched to backup router %s "
3103 "(we are primary router now)",
3104 server->server_name, server->server_name));
3105 else if (server->router)
3106 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3107 SILC_NOTIFY_TYPE_NONE,
3108 ("%s switched to backup router %s",
3109 server->server_name,
3110 server->router->server_name));
3112 server->backup_noswitch = FALSE;
3115 silc_server_connection_free(idata->sconn);
3117 /* Free the server entry */
3118 silc_server_backup_del(server, user_data);
3119 silc_server_backup_replaced_del(server, user_data);
3120 silc_idlist_del_data(user_data);
3121 if (!silc_idlist_del_server(server->local_list, user_data))
3122 silc_idlist_del_server(server->global_list, user_data);
3123 if (idata->conn_type == SILC_CONN_SERVER) {
3124 server->stat.my_servers--;
3125 server->stat.servers--;
3127 server->stat.my_routers--;
3128 server->stat.routers--;
3130 if (server->server_type == SILC_ROUTER)
3131 server->stat.cell_servers--;
3133 if (backup_router && backup_router != server->id_entry) {
3134 /* Announce all of our stuff that was created about 5 minutes ago.
3135 The backup router knows all the other stuff already. */
3136 if (server->server_type == SILC_ROUTER)
3137 silc_server_announce_servers(server, FALSE, time(0) - 300,
3138 backup_router->connection);
3140 /* Announce our clients and channels to the router */
3141 silc_server_announce_clients(server, time(0) - 300,
3142 backup_router->connection);
3143 silc_server_announce_channels(server, time(0) - 300,
3144 backup_router->connection);
3147 silc_packet_set_context(sock, NULL);
3153 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3155 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3158 silc_server_connection_free(idata->sconn);
3159 silc_idlist_del_data(idata);
3161 silc_packet_set_context(sock, NULL);
3167 /* Removes client from all channels it has joined. This is used when client
3168 connection is disconnected. If the client on a channel is last, the
3169 channel is removed as well. This sends the SIGNOFF notify types. */
3171 void silc_server_remove_from_channels(SilcServer server,
3172 SilcPacketStream sock,
3173 SilcClientEntry client,
3175 const char *signoff_message,
3179 SilcChannelEntry channel;
3180 SilcChannelClientEntry chl;
3181 SilcHashTableList htl;
3182 SilcBuffer clidp = NULL;
3187 if (notify && !client->id)
3190 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3191 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3194 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3199 /* Remove the client from all channels. The client is removed from
3200 the channels' user list. */
3201 silc_hash_table_list(client->channels, &htl);
3202 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3203 channel = chl->channel;
3205 /* Remove channel if this is last client leaving the channel, unless
3206 the channel is permanent. */
3207 if (server->server_type != SILC_SERVER &&
3208 silc_hash_table_count(channel->user_list) < 2) {
3209 silc_server_channel_delete(server, channel);
3213 silc_hash_table_del(client->channels, channel);
3214 silc_hash_table_del(channel->user_list, client);
3215 channel->user_count--;
3217 /* If there is no global users on the channel anymore mark the channel
3218 as local channel. Do not check if the removed client is local client. */
3219 if (server->server_type == SILC_SERVER && channel->global_users &&
3220 chl->client->router && !silc_server_channel_has_global(channel))
3221 channel->global_users = FALSE;
3223 memset(chl, 'A', sizeof(*chl));
3226 /* Update statistics */
3227 if (SILC_IS_LOCAL(client))
3228 server->stat.my_chanclients--;
3229 if (server->server_type == SILC_ROUTER) {
3230 server->stat.cell_chanclients--;
3231 server->stat.chanclients--;
3234 /* If there is not at least one local user on the channel then we don't
3235 need the channel entry anymore, we can remove it safely, unless the
3236 channel is permanent channel */
3237 if (server->server_type == SILC_SERVER &&
3238 !silc_server_channel_has_local(channel)) {
3239 /* Notify about leaving client if this channel has global users. */
3240 if (notify && channel->global_users)
3241 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3242 SILC_NOTIFY_TYPE_SIGNOFF,
3243 signoff_message ? 2 : 1,
3244 clidp->data, silc_buffer_len(clidp),
3245 signoff_message, signoff_message ?
3246 strlen(signoff_message) : 0);
3248 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3249 silc_server_channel_delete(server, channel);
3253 /* Send notify to channel about client leaving SILC and channel too */
3255 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3256 SILC_NOTIFY_TYPE_SIGNOFF,
3257 signoff_message ? 2 : 1,
3258 clidp->data, silc_buffer_len(clidp),
3259 signoff_message, signoff_message ?
3260 strlen(signoff_message) : 0);
3262 if (killed && clidp) {
3263 /* Remove the client from channel's invite list */
3264 if (channel->invite_list &&
3265 silc_hash_table_count(channel->invite_list)) {
3267 SilcArgumentPayload iargs;
3268 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3269 silc_buffer_len(clidp), 3);
3270 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3271 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3272 silc_buffer_free(ab);
3273 silc_argument_payload_free(iargs);
3277 /* Don't create keys if we are shutting down */
3278 if (server->server_shutdown)
3281 /* Re-generate channel key if needed */
3282 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3283 if (!silc_server_create_channel_key(server, channel, 0))
3286 /* Send the channel key to the channel. The key of course is not sent
3287 to the client who was removed from the channel. */
3288 silc_server_send_channel_key(server, client->connection, channel,
3289 server->server_type == SILC_ROUTER ?
3290 FALSE : !server->standalone);
3294 silc_hash_table_list_reset(&htl);
3296 silc_buffer_free(clidp);
3299 /* Removes client from one channel. This is used for example when client
3300 calls LEAVE command to remove itself from the channel. Returns TRUE
3301 if channel still exists and FALSE if the channel is removed when
3302 last client leaves the channel. If `notify' is FALSE notify messages
3305 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3306 SilcPacketStream sock,
3307 SilcChannelEntry channel,
3308 SilcClientEntry client,
3311 SilcChannelClientEntry chl;
3314 SILC_LOG_DEBUG(("Removing %s from channel %s",
3315 silc_id_render(client->id, SILC_ID_CLIENT),
3316 channel->channel_name));
3318 /* Get the entry to the channel, if this client is not on the channel
3320 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3323 /* Remove channel if this is last client leaving the channel, unless
3324 the channel is permanent. */
3325 if (server->server_type != SILC_SERVER &&
3326 silc_hash_table_count(channel->user_list) < 2) {
3327 silc_server_channel_delete(server, channel);
3331 silc_hash_table_del(client->channels, channel);
3332 silc_hash_table_del(channel->user_list, client);
3333 channel->user_count--;
3335 /* If there is no global users on the channel anymore mark the channel
3336 as local channel. Do not check if the client is local client. */
3337 if (server->server_type == SILC_SERVER && channel->global_users &&
3338 chl->client->router && !silc_server_channel_has_global(channel))
3339 channel->global_users = FALSE;
3341 memset(chl, 'O', sizeof(*chl));
3344 /* Update statistics */
3345 if (SILC_IS_LOCAL(client))
3346 server->stat.my_chanclients--;
3347 if (server->server_type == SILC_ROUTER) {
3348 server->stat.cell_chanclients--;
3349 server->stat.chanclients--;
3352 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3356 /* If there is not at least one local user on the channel then we don't
3357 need the channel entry anymore, we can remove it safely, unless the
3358 channel is permanent channel */
3359 if (server->server_type == SILC_SERVER &&
3360 !silc_server_channel_has_local(channel)) {
3361 /* Notify about leaving client if this channel has global users. */
3362 if (notify && channel->global_users)
3363 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3364 SILC_NOTIFY_TYPE_LEAVE, 1,
3365 clidp->data, silc_buffer_len(clidp));
3367 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3368 silc_server_channel_delete(server, channel);
3369 silc_buffer_free(clidp);
3373 /* Send notify to channel about client leaving the channel */
3375 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3376 SILC_NOTIFY_TYPE_LEAVE, 1,
3377 clidp->data, silc_buffer_len(clidp));
3379 silc_buffer_free(clidp);
3383 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3384 function may be used only by router. In real SILC network all channels
3385 are created by routers thus this function is never used by normal
3388 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3389 SilcServerID *router_id,
3395 SilcChannelID *channel_id;
3396 SilcChannelEntry entry;
3397 SilcCipher send_key, receive_key;
3400 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3403 cipher = SILC_DEFAULT_CIPHER;
3405 hmac = SILC_DEFAULT_HMAC;
3407 /* Allocate cipher */
3408 if (!silc_cipher_alloc(cipher, &send_key))
3410 if (!silc_cipher_alloc(cipher, &receive_key)) {
3411 silc_cipher_free(send_key);
3416 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3417 silc_cipher_free(send_key);
3418 silc_cipher_free(receive_key);
3422 channel_name = strdup(channel_name);
3424 /* Create the channel ID */
3425 if (!silc_id_create_channel_id(server, router_id, server->rng,
3427 silc_free(channel_name);
3428 silc_cipher_free(send_key);
3429 silc_cipher_free(receive_key);
3430 silc_hmac_free(newhmac);
3434 /* Create the channel */
3435 entry = silc_idlist_add_channel(server->local_list, channel_name,
3436 SILC_CHANNEL_MODE_NONE, channel_id,
3437 NULL, send_key, receive_key, newhmac);
3439 silc_free(channel_name);
3440 silc_cipher_free(send_key);
3441 silc_cipher_free(receive_key);
3442 silc_hmac_free(newhmac);
3443 silc_free(channel_id);
3447 entry->cipher = strdup(cipher);
3448 entry->hmac_name = strdup(hmac);
3450 /* Now create the actual key material */
3451 if (!silc_server_create_channel_key(server, entry,
3452 silc_cipher_get_key_len(send_key) / 8)) {
3453 silc_idlist_del_channel(server->local_list, entry);
3457 /* Notify other routers about the new channel. We send the packet
3458 to our primary route. */
3460 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3461 channel_name, entry->id,
3462 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3465 /* Distribute to backup routers */
3466 if (broadcast && server->server_type == SILC_ROUTER) {
3468 unsigned char cid[32];
3469 SilcUInt32 name_len = strlen(channel_name);
3472 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3473 packet = silc_channel_payload_encode(channel_name, name_len,
3474 cid, id_len, entry->mode);
3475 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3476 packet->data, silc_buffer_len(packet), FALSE,
3478 silc_buffer_free(packet);
3481 server->stat.my_channels++;
3482 if (server->server_type == SILC_ROUTER) {
3483 server->stat.channels++;
3484 server->stat.cell_channels++;
3485 entry->users_resolved = TRUE;
3491 /* Same as above but creates the channel with Channel ID `channel_id. */
3494 silc_server_create_new_channel_with_id(SilcServer server,
3498 SilcChannelID *channel_id,
3501 SilcChannelEntry entry;
3502 SilcCipher send_key, receive_key;
3505 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3508 cipher = SILC_DEFAULT_CIPHER;
3510 hmac = SILC_DEFAULT_HMAC;
3512 /* Allocate cipher */
3513 if (!silc_cipher_alloc(cipher, &send_key))
3515 if (!silc_cipher_alloc(cipher, &receive_key)) {
3516 silc_cipher_free(send_key);
3521 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3522 silc_cipher_free(send_key);
3523 silc_cipher_free(receive_key);
3527 channel_name = strdup(channel_name);
3529 /* Create the channel */
3530 entry = silc_idlist_add_channel(server->local_list, channel_name,
3531 SILC_CHANNEL_MODE_NONE, channel_id,
3532 NULL, send_key, receive_key, newhmac);
3534 silc_cipher_free(send_key);
3535 silc_cipher_free(receive_key);
3536 silc_hmac_free(newhmac);
3537 silc_free(channel_name);
3541 /* Now create the actual key material */
3542 if (!silc_server_create_channel_key(server, entry,
3543 silc_cipher_get_key_len(send_key) / 8)) {
3544 silc_idlist_del_channel(server->local_list, entry);
3548 /* Notify other routers about the new channel. We send the packet
3549 to our primary route. */
3551 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3552 channel_name, entry->id,
3553 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3556 /* Distribute to backup routers */
3557 if (broadcast && server->server_type == SILC_ROUTER) {
3559 unsigned char cid[32];
3560 SilcUInt32 name_len = strlen(channel_name);
3563 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3564 packet = silc_channel_payload_encode(channel_name, name_len,
3565 cid, id_len, entry->mode);
3566 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3567 packet->data, silc_buffer_len(packet), FALSE,
3569 silc_buffer_free(packet);
3572 server->stat.my_channels++;
3573 if (server->server_type == SILC_ROUTER) {
3574 server->stat.channels++;
3575 server->stat.cell_channels++;
3576 entry->users_resolved = TRUE;
3582 /* Channel's key re-key timeout callback. */
3584 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3586 SilcServer server = app_context;
3587 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3591 /* Return now if we are shutting down */
3592 if (server->server_shutdown)
3595 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3598 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3601 /* Generates new channel key. This is used to create the initial channel key
3602 but also to re-generate new key for channel. If `key_len' is provided
3603 it is the bytes of the key length. */
3605 SilcBool silc_server_create_channel_key(SilcServer server,
3606 SilcChannelEntry channel,
3610 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3613 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3614 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3618 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3620 if (!channel->send_key)
3621 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3622 channel->send_key = NULL;
3625 if (!channel->receive_key)
3626 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3627 silc_cipher_free(channel->send_key);
3628 channel->send_key = channel->receive_key = NULL;
3634 else if (channel->key_len)
3635 len = channel->key_len / 8;
3637 len = silc_cipher_get_key_len(channel->send_key) / 8;
3639 /* Create channel key */
3640 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3643 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3644 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3646 /* Remove old key if exists */
3648 memset(channel->key, 0, channel->key_len / 8);
3649 silc_free(channel->key);
3653 channel->key_len = len * 8;
3654 channel->key = silc_memdup(channel_key, len);
3655 memset(channel_key, 0, sizeof(channel_key));
3657 /* Generate HMAC key from the channel key data and set it */
3659 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3660 memset(channel->key, 0, channel->key_len / 8);
3661 silc_free(channel->key);
3662 silc_cipher_free(channel->send_key);
3663 silc_cipher_free(channel->receive_key);
3664 channel->send_key = channel->receive_key = NULL;
3667 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3668 silc_hmac_set_key(channel->hmac, hash,
3669 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3670 memset(hash, 0, sizeof(hash));
3672 if (server->server_type == SILC_ROUTER) {
3673 if (!channel->rekey)
3674 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3675 channel->rekey->channel = channel;
3676 channel->rekey->key_len = key_len;
3677 if (channel->rekey->task)
3678 silc_schedule_task_del(server->schedule, channel->rekey->task);
3680 channel->rekey->task =
3681 silc_schedule_task_add_timeout(server->schedule,
3682 silc_server_channel_key_rekey,
3683 (void *)channel->rekey,
3684 server->config->channel_rekey_secs, 0);
3690 /* Saves the channel key found in the encoded `key_payload' buffer. This
3691 function is used when we receive Channel Key Payload and also when we're
3692 processing JOIN command reply. Returns entry to the channel. */
3694 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3695 SilcBuffer key_payload,
3696 SilcChannelEntry channel)
3698 SilcChannelKeyPayload payload = NULL;
3700 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3704 /* Decode channel key payload */
3705 payload = silc_channel_key_payload_parse(key_payload->data,
3706 silc_buffer_len(key_payload));
3708 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3713 /* Get the channel entry */
3716 /* Get channel ID */
3717 tmp = silc_channel_key_get_id(payload, &tmp_len);
3718 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3723 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3725 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3727 if (server->server_type == SILC_ROUTER)
3728 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3729 silc_id_render(&id, SILC_ID_CHANNEL)));
3735 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3737 tmp = silc_channel_key_get_key(payload, &tmp_len);
3743 cipher = silc_channel_key_get_cipher(payload, NULL);
3749 /* Remove old key if exists */
3751 memset(channel->key, 0, channel->key_len / 8);
3752 silc_free(channel->key);
3753 silc_cipher_free(channel->send_key);
3754 silc_cipher_free(channel->receive_key);
3757 /* Create new cipher */
3758 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3759 channel->send_key = NULL;
3763 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3764 silc_cipher_free(channel->send_key);
3765 channel->send_key = channel->receive_key = NULL;
3770 if (channel->cipher)
3771 silc_free(channel->cipher);
3772 channel->cipher = strdup(cipher);
3775 channel->key_len = tmp_len * 8;
3776 channel->key = silc_memdup(tmp, tmp_len);
3777 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3778 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3780 /* Generate HMAC key from the channel key data and set it */
3782 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3783 memset(channel->key, 0, channel->key_len / 8);
3784 silc_free(channel->key);
3785 silc_cipher_free(channel->send_key);
3786 silc_cipher_free(channel->receive_key);
3787 channel->send_key = channel->receive_key = NULL;
3790 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3791 silc_hmac_set_key(channel->hmac, hash,
3792 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3794 memset(hash, 0, sizeof(hash));
3795 memset(tmp, 0, tmp_len);
3797 if (server->server_type == SILC_ROUTER) {
3798 if (!channel->rekey)
3799 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3800 channel->rekey->channel = channel;
3801 if (channel->rekey->task)
3802 silc_schedule_task_del(server->schedule, channel->rekey->task);
3804 channel->rekey->task =
3805 silc_schedule_task_add_timeout(server->schedule,
3806 silc_server_channel_key_rekey,
3807 (void *)channel->rekey,
3808 server->config->channel_rekey_secs, 0);
3813 silc_channel_key_payload_free(payload);
3818 /* Returns assembled of all servers in the given ID list. The packet's
3819 form is dictated by the New ID payload. */
3821 static void silc_server_announce_get_servers(SilcServer server,
3822 SilcServerEntry remote,
3824 SilcBuffer *servers,
3825 unsigned long creation_time)
3828 SilcIDCacheEntry id_cache;
3829 SilcServerEntry entry;
3832 /* Go through all clients in the list */
3833 if (silc_idcache_get_all(id_list->servers, &list)) {
3834 silc_list_start(list);
3835 while ((id_cache = silc_list_get(list))) {
3836 entry = (SilcServerEntry)id_cache->context;
3838 /* Do not announce the one we've sending our announcements and
3839 do not announce ourself. Also check the creation time if it's
3841 if ((entry == remote) || (entry == server->id_entry) ||
3842 (creation_time && entry->data.created < creation_time))
3845 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3847 *servers = silc_buffer_realloc(*servers,
3849 silc_buffer_truelen((*servers)) +
3850 silc_buffer_len(idp) :
3851 silc_buffer_len(idp)));
3852 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3853 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3854 silc_buffer_pull(*servers, silc_buffer_len(idp));
3855 silc_buffer_free(idp);
3861 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3867 p = silc_notify_payload_encode(notify, argc, ap);
3873 /* This function is used by router to announce existing servers to our
3874 primary router when we've connected to it. If `creation_time' is non-zero
3875 then only the servers that has been created after the `creation_time'
3876 will be announced. */
3878 void silc_server_announce_servers(SilcServer server, SilcBool global,
3879 unsigned long creation_time,
3880 SilcPacketStream remote)
3882 SilcBuffer servers = NULL;
3884 SILC_LOG_DEBUG(("Announcing servers"));
3886 /* Get servers in local list */
3887 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3888 server->local_list, &servers,
3892 /* Get servers in global list */
3893 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3894 server->global_list, &servers,
3898 silc_buffer_push(servers, servers->data - servers->head);
3899 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
3901 /* Send the packet */
3902 silc_server_packet_send(server, remote,
3903 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3904 servers->data, silc_buffer_len(servers));
3906 silc_buffer_free(servers);
3910 /* Returns assembled packet of all clients in the given ID list. The
3911 packet's form is dictated by the New ID Payload. */
3913 static void silc_server_announce_get_clients(SilcServer server,
3915 SilcBuffer *clients,
3917 unsigned long creation_time)
3920 SilcIDCacheEntry id_cache;
3921 SilcClientEntry client;
3924 unsigned char mode[4];
3926 /* Go through all clients in the list */
3927 if (silc_idcache_get_all(id_list->clients, &list)) {
3928 silc_list_start(list);
3929 while ((id_cache = silc_list_get(list))) {
3930 client = (SilcClientEntry)id_cache->context;
3932 if (creation_time && client->data.created < creation_time)
3934 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
3936 if (!client->connection && !client->router)
3939 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3941 *clients = silc_buffer_realloc(*clients,
3943 silc_buffer_truelen((*clients)) +
3944 silc_buffer_len(idp) :
3945 silc_buffer_len(idp)));
3946 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3947 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
3948 silc_buffer_pull(*clients, silc_buffer_len(idp));
3950 SILC_PUT32_MSB(client->mode, mode);
3952 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3953 2, idp->data, silc_buffer_len(idp),
3955 *umodes = silc_buffer_realloc(*umodes,
3957 silc_buffer_truelen((*umodes)) +
3958 silc_buffer_len(tmp) :
3959 silc_buffer_len(tmp)));
3960 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3961 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
3962 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
3963 silc_buffer_free(tmp);
3965 silc_buffer_free(idp);
3970 /* This function is used to announce our existing clients to our router
3971 when we've connected to it. If `creation_time' is non-zero then only
3972 the clients that has been created after the `creation_time' will be
3975 void silc_server_announce_clients(SilcServer server,
3976 unsigned long creation_time,
3977 SilcPacketStream remote)
3979 SilcBuffer clients = NULL;
3980 SilcBuffer umodes = NULL;
3982 SILC_LOG_DEBUG(("Announcing clients"));
3984 /* Get clients in local list */
3985 silc_server_announce_get_clients(server, server->local_list,
3986 &clients, &umodes, creation_time);
3988 /* As router we announce our global list as well */
3989 if (server->server_type == SILC_ROUTER)
3990 silc_server_announce_get_clients(server, server->global_list,
3991 &clients, &umodes, creation_time);
3994 silc_buffer_push(clients, clients->data - clients->head);
3995 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
3997 /* Send the packet */
3998 silc_server_packet_send(server, remote,
3999 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4000 clients->data, silc_buffer_len(clients));
4002 silc_buffer_free(clients);
4006 silc_buffer_push(umodes, umodes->data - umodes->head);
4007 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4009 /* Send the packet */
4010 silc_server_packet_send(server, remote,
4011 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4012 umodes->data, silc_buffer_len(umodes));
4014 silc_buffer_free(umodes);
4018 /* Returns channel's topic for announcing it */
4020 void silc_server_announce_get_channel_topic(SilcServer server,
4021 SilcChannelEntry channel,
4026 if (channel->topic) {
4027 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4028 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4030 silc_buffer_len(chidp),
4032 strlen(channel->topic));
4033 silc_buffer_free(chidp);
4037 /* Returns channel's invite and ban lists */
4039 void silc_server_announce_get_inviteban(SilcServer server,
4040 SilcChannelEntry channel,
4044 SilcBuffer list, idp, idp2, tmp2;
4046 SilcHashTableList htl;
4047 const unsigned char a[1] = { 0x03 };
4049 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4051 /* Encode invite list */
4052 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4053 list = silc_buffer_alloc_size(2);
4054 type = silc_hash_table_count(channel->invite_list);
4055 SILC_PUT16_MSB(type, list->data);
4056 silc_hash_table_list(channel->invite_list, &htl);
4057 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4058 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4060 silc_hash_table_list_reset(&htl);
4062 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4064 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4065 idp->data, silc_buffer_len(idp),
4066 channel->channel_name,
4067 strlen(channel->channel_name),
4068 idp2->data, silc_buffer_len(idp2),
4070 list->data, silc_buffer_len(list));
4071 silc_buffer_free(idp2);
4072 silc_buffer_free(list);
4075 /* Encode ban list */
4076 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4077 list = silc_buffer_alloc_size(2);
4078 type = silc_hash_table_count(channel->ban_list);
4079 SILC_PUT16_MSB(type, list->data);
4080 silc_hash_table_list(channel->ban_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);
4087 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4088 idp->data, silc_buffer_len(idp),
4090 list->data, silc_buffer_len(list));
4091 silc_buffer_free(list);
4094 silc_buffer_free(idp);
4097 /* Returns assembled packets for channel users of the `channel'. */
4099 void silc_server_announce_get_channel_users(SilcServer server,
4100 SilcChannelEntry channel,
4101 SilcBuffer *channel_modes,
4102 SilcBuffer *channel_users,
4103 SilcBuffer *channel_users_modes)
4105 SilcChannelClientEntry chl;
4106 SilcHashTableList htl;
4107 SilcBuffer chidp, clidp, csidp;
4108 SilcBuffer tmp, fkey = NULL, chpklist;
4110 unsigned char mode[4], ulimit[4];
4113 SILC_LOG_DEBUG(("Start"));
4115 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4116 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4117 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4120 SILC_PUT32_MSB(channel->mode, mode);
4121 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4122 SILC_PUT32_MSB(channel->user_limit, ulimit);
4123 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4124 if (channel->founder_key)
4125 fkey = silc_public_key_payload_encode(channel->founder_key);
4127 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4129 silc_buffer_len(csidp),
4132 hmac, hmac ? strlen(hmac) : 0,
4133 channel->passphrase,
4134 channel->passphrase ?
4135 strlen(channel->passphrase) : 0,
4136 fkey ? fkey->data : NULL,
4137 fkey ? silc_buffer_len(fkey) : 0,
4138 chpklist ? chpklist->data : NULL,
4140 silc_buffer_len(chpklist) : 0,
4142 SILC_CHANNEL_MODE_ULIMIT ?
4145 SILC_CHANNEL_MODE_ULIMIT ?
4146 sizeof(ulimit) : 0));
4147 len = silc_buffer_len(tmp);
4149 silc_buffer_realloc(*channel_modes,
4151 silc_buffer_truelen((*channel_modes)) + len : len));
4152 silc_buffer_pull_tail(*channel_modes,
4153 ((*channel_modes)->end -
4154 (*channel_modes)->data));
4155 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4156 silc_buffer_pull(*channel_modes, len);
4157 silc_buffer_free(tmp);
4158 silc_buffer_free(fkey);
4161 /* Now find all users on the channel */
4162 silc_hash_table_list(channel->user_list, &htl);
4163 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4164 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4167 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4169 silc_buffer_len(clidp),
4171 silc_buffer_len(chidp));
4172 len = silc_buffer_len(tmp);
4174 silc_buffer_realloc(*channel_users,
4176 silc_buffer_truelen((*channel_users)) + len : len));
4177 silc_buffer_pull_tail(*channel_users,
4178 ((*channel_users)->end -
4179 (*channel_users)->data));
4181 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4182 silc_buffer_pull(*channel_users, len);
4183 silc_buffer_free(tmp);
4185 /* CUMODE notify for mode change on the channel */
4186 SILC_PUT32_MSB(chl->mode, mode);
4187 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4188 fkey = silc_public_key_payload_encode(channel->founder_key);
4189 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4191 silc_buffer_len(csidp),
4194 silc_buffer_len(clidp),
4195 fkey ? fkey->data : NULL,
4196 fkey ? silc_buffer_len(fkey) : 0);
4197 len = silc_buffer_len(tmp);
4198 *channel_users_modes =
4199 silc_buffer_realloc(*channel_users_modes,
4200 (*channel_users_modes ?
4201 silc_buffer_truelen((*channel_users_modes)) +
4203 silc_buffer_pull_tail(*channel_users_modes,
4204 ((*channel_users_modes)->end -
4205 (*channel_users_modes)->data));
4207 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4208 silc_buffer_pull(*channel_users_modes, len);
4209 silc_buffer_free(tmp);
4210 silc_buffer_free(fkey);
4212 silc_buffer_free(clidp);
4214 silc_hash_table_list_reset(&htl);
4215 silc_buffer_free(chidp);
4216 silc_buffer_free(csidp);
4219 /* Returns assembled packets for all channels and users on those channels
4220 from the given ID List. The packets are in the form dictated by the
4221 New Channel and New Channel User payloads. */
4223 void silc_server_announce_get_channels(SilcServer server,
4225 SilcBuffer *channels,
4226 SilcBuffer **channel_modes,
4227 SilcBuffer *channel_users,
4228 SilcBuffer **channel_users_modes,
4229 SilcUInt32 *channel_users_modes_c,
4230 SilcBuffer **channel_topics,
4231 SilcBuffer **channel_invites,
4232 SilcBuffer **channel_bans,
4233 SilcChannelID ***channel_ids,
4234 unsigned long creation_time)
4237 SilcIDCacheEntry id_cache;
4238 SilcChannelEntry channel;
4239 unsigned char cid[32];
4241 SilcUInt16 name_len;
4243 int i = *channel_users_modes_c;
4246 SILC_LOG_DEBUG(("Start"));
4248 /* Go through all channels in the list */
4249 if (silc_idcache_get_all(id_list->channels, &list)) {
4250 silc_list_start(list);
4251 while ((id_cache = silc_list_get(list))) {
4252 channel = (SilcChannelEntry)id_cache->context;
4254 if (creation_time && channel->created < creation_time)
4259 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4260 name_len = strlen(channel->channel_name);
4263 len = 4 + name_len + id_len + 4;
4265 silc_buffer_realloc(*channels,
4267 silc_buffer_truelen((*channels)) +
4269 silc_buffer_pull_tail(*channels,
4270 ((*channels)->end - (*channels)->data));
4271 silc_buffer_format(*channels,
4272 SILC_STR_UI_SHORT(name_len),
4273 SILC_STR_UI_XNSTRING(channel->channel_name,
4275 SILC_STR_UI_SHORT(id_len),
4276 SILC_STR_UI_XNSTRING(cid, id_len),
4277 SILC_STR_UI_INT(channel->mode),
4279 silc_buffer_pull(*channels, len);
4282 if (creation_time && channel->updated < creation_time)
4288 /* Channel user modes */
4289 *channel_users_modes = silc_realloc(*channel_users_modes,
4290 sizeof(**channel_users_modes) *
4292 (*channel_users_modes)[i] = NULL;
4293 *channel_modes = silc_realloc(*channel_modes,
4294 sizeof(**channel_modes) * (i + 1));
4295 (*channel_modes)[i] = NULL;
4296 *channel_ids = silc_realloc(*channel_ids,
4297 sizeof(**channel_ids) * (i + 1));
4298 (*channel_ids)[i] = NULL;
4299 silc_server_announce_get_channel_users(server, channel,
4300 &(*channel_modes)[i],
4302 &(*channel_users_modes)[i]);
4303 (*channel_ids)[i] = channel->id;
4305 /* Channel's topic */
4306 *channel_topics = silc_realloc(*channel_topics,
4307 sizeof(**channel_topics) * (i + 1));
4308 (*channel_topics)[i] = NULL;
4309 silc_server_announce_get_channel_topic(server, channel,
4310 &(*channel_topics)[i]);
4312 /* Channel's invite and ban list */
4313 *channel_invites = silc_realloc(*channel_invites,
4314 sizeof(**channel_invites) * (i + 1));
4315 (*channel_invites)[i] = NULL;
4316 *channel_bans = silc_realloc(*channel_bans,
4317 sizeof(**channel_bans) * (i + 1));
4318 (*channel_bans)[i] = NULL;
4319 silc_server_announce_get_inviteban(server, channel,
4320 &(*channel_invites)[i],
4321 &(*channel_bans)[i]);
4323 (*channel_users_modes_c)++;
4331 /* This function is used to announce our existing channels to our router
4332 when we've connected to it. This also announces the users on the
4333 channels to the router. If the `creation_time' is non-zero only the
4334 channels that was created after the `creation_time' are announced.
4335 Note that the channel users are still announced even if the `creation_time'
4338 void silc_server_announce_channels(SilcServer server,
4339 unsigned long creation_time,
4340 SilcPacketStream remote)
4342 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4343 SilcBuffer *channel_users_modes = NULL;
4344 SilcBuffer *channel_topics = NULL;
4345 SilcBuffer *channel_invites = NULL;
4346 SilcBuffer *channel_bans = NULL;
4347 SilcUInt32 channel_users_modes_c = 0;
4348 SilcChannelID **channel_ids = NULL;
4350 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4352 /* Get channels and channel users in local list */
4353 silc_server_announce_get_channels(server, server->local_list,
4354 &channels, &channel_modes,
4356 &channel_users_modes,
4357 &channel_users_modes_c,
4361 &channel_ids, creation_time);
4363 /* Get channels and channel users in global list */
4364 if (server->server_type != SILC_SERVER)
4365 silc_server_announce_get_channels(server, server->global_list,
4366 &channels, &channel_modes,
4368 &channel_users_modes,
4369 &channel_users_modes_c,
4373 &channel_ids, creation_time);
4376 silc_buffer_push(channels, channels->data - channels->head);
4377 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4379 /* Send the packet */
4380 silc_server_packet_send(server, remote,
4381 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4382 channels->data, silc_buffer_len(channels));
4384 silc_buffer_free(channels);
4387 if (channel_users) {
4388 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4389 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4390 silc_buffer_len(channel_users));
4392 /* Send the packet */
4393 silc_server_packet_send(server, remote,
4394 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4395 channel_users->data, silc_buffer_len(channel_users));
4397 silc_buffer_free(channel_users);
4400 if (channel_modes) {
4403 for (i = 0; i < channel_users_modes_c; i++) {
4404 if (!channel_modes[i])
4406 silc_buffer_push(channel_modes[i],
4407 channel_modes[i]->data -
4408 channel_modes[i]->head);
4409 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4410 silc_buffer_len(channel_modes[i]));
4411 silc_server_packet_send_dest(server, remote,
4412 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4413 channel_ids[i], SILC_ID_CHANNEL,
4414 channel_modes[i]->data,
4415 silc_buffer_len(channel_modes[i]));
4416 silc_buffer_free(channel_modes[i]);
4418 silc_free(channel_modes);
4421 if (channel_users_modes) {
4424 for (i = 0; i < channel_users_modes_c; i++) {
4425 if (!channel_users_modes[i])
4427 silc_buffer_push(channel_users_modes[i],
4428 channel_users_modes[i]->data -
4429 channel_users_modes[i]->head);
4430 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4431 silc_buffer_len(channel_users_modes[i]));
4432 silc_server_packet_send_dest(server, remote,
4433 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4434 channel_ids[i], SILC_ID_CHANNEL,
4435 channel_users_modes[i]->data,
4436 silc_buffer_len(channel_users_modes[i]));
4437 silc_buffer_free(channel_users_modes[i]);
4439 silc_free(channel_users_modes);
4442 if (channel_topics) {
4445 for (i = 0; i < channel_users_modes_c; i++) {
4446 if (!channel_topics[i])
4449 silc_buffer_push(channel_topics[i],
4450 channel_topics[i]->data -
4451 channel_topics[i]->head);
4452 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4453 silc_buffer_len(channel_topics[i]));
4454 silc_server_packet_send_dest(server, remote,
4455 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4456 channel_ids[i], SILC_ID_CHANNEL,
4457 channel_topics[i]->data,
4458 silc_buffer_len(channel_topics[i]));
4459 silc_buffer_free(channel_topics[i]);
4461 silc_free(channel_topics);
4464 if (channel_invites) {
4467 for (i = 0; i < channel_users_modes_c; i++) {
4468 if (!channel_invites[i])
4471 silc_buffer_push(channel_invites[i],
4472 channel_invites[i]->data -
4473 channel_invites[i]->head);
4474 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4475 silc_buffer_len(channel_invites[i]));
4476 silc_server_packet_send_dest(server, remote,
4477 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4478 channel_ids[i], SILC_ID_CHANNEL,
4479 channel_invites[i]->data,
4480 silc_buffer_len(channel_invites[i]));
4481 silc_buffer_free(channel_invites[i]);
4483 silc_free(channel_invites);
4489 for (i = 0; i < channel_users_modes_c; i++) {
4490 if (!channel_bans[i])
4493 silc_buffer_push(channel_bans[i],
4494 channel_bans[i]->data -
4495 channel_bans[i]->head);
4496 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4497 silc_buffer_len(channel_bans[i]));
4498 silc_server_packet_send_dest(server, remote,
4499 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4500 channel_ids[i], SILC_ID_CHANNEL,
4501 channel_bans[i]->data,
4502 silc_buffer_len(channel_bans[i]));
4503 silc_buffer_free(channel_bans[i]);
4505 silc_free(channel_bans);
4508 silc_free(channel_ids);
4511 /* Announces WATCH list. */
4513 void silc_server_announce_watches(SilcServer server,
4514 SilcPacketStream remote)
4516 SilcHashTableList htl;
4517 SilcBuffer buffer, idp, args, pkp;
4518 SilcClientEntry client;
4521 SILC_LOG_DEBUG(("Announcing watch list"));
4523 /* XXX because way we save the nicks (hash) we cannot announce them. */
4525 /* XXX we should send all public keys in one command if client is
4526 watching more than one key */
4527 silc_hash_table_list(server->watcher_list_pk, &htl);
4528 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4529 if (!client || !client->id)
4532 server->stat.commands_sent++;
4534 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4535 args = silc_buffer_alloc_size(2);
4536 silc_buffer_format(args,
4537 SILC_STR_UI_SHORT(1),
4539 pkp = silc_public_key_payload_encode(key);
4540 args = silc_argument_payload_encode_one(args, pkp->data,
4541 silc_buffer_len(pkp), 0x00);
4542 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4543 ++server->cmd_ident, 2,
4544 1, idp->data, silc_buffer_len(idp),
4546 silc_buffer_len(args));
4549 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4550 buffer->data, silc_buffer_len(buffer));
4552 silc_buffer_free(pkp);
4553 silc_buffer_free(args);
4554 silc_buffer_free(idp);
4555 silc_buffer_free(buffer);
4557 silc_hash_table_list_reset(&htl);
4560 /* Assembles user list and users mode list from the `channel'. */
4562 SilcBool silc_server_get_users_on_channel(SilcServer server,
4563 SilcChannelEntry channel,
4564 SilcBuffer *user_list,
4565 SilcBuffer *mode_list,
4566 SilcUInt32 *user_count)
4568 SilcChannelClientEntry chl;
4569 SilcHashTableList htl;
4570 SilcBuffer client_id_list;
4571 SilcBuffer client_mode_list;
4573 SilcUInt32 list_count = 0, len = 0;
4575 if (!silc_hash_table_count(channel->user_list))
4578 silc_hash_table_list(channel->user_list, &htl);
4579 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4580 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4581 silc_hash_table_list_reset(&htl);
4583 client_id_list = silc_buffer_alloc(len);
4585 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4586 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4587 silc_buffer_pull_tail(client_mode_list,
4588 silc_buffer_truelen(client_mode_list));
4590 silc_hash_table_list(channel->user_list, &htl);
4591 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4593 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4594 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4595 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4596 silc_buffer_free(idp);
4598 /* Client's mode on channel */
4599 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4600 silc_buffer_pull(client_mode_list, 4);
4604 silc_hash_table_list_reset(&htl);
4605 silc_buffer_push(client_id_list,
4606 client_id_list->data - client_id_list->head);
4607 silc_buffer_push(client_mode_list,
4608 client_mode_list->data - client_mode_list->head);
4610 *user_list = client_id_list;
4611 *mode_list = client_mode_list;
4612 *user_count = list_count;
4616 /* Saves users and their modes to the `channel'. */
4618 void silc_server_save_users_on_channel(SilcServer server,
4619 SilcPacketStream sock,
4620 SilcChannelEntry channel,
4621 SilcClientID *noadd,
4622 SilcBuffer user_list,
4623 SilcBuffer mode_list,
4624 SilcUInt32 user_count)
4630 SilcClientEntry client;
4631 SilcIDCacheEntry cache;
4632 SilcChannelClientEntry chl;
4634 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4635 channel->channel_name));
4637 for (i = 0; i < user_count; i++) {
4639 SILC_GET16_MSB(idp_len, user_list->data + 2);
4641 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4643 silc_buffer_pull(user_list, idp_len);
4646 SILC_GET32_MSB(mode, mode_list->data);
4647 silc_buffer_pull(mode_list, 4);
4649 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4654 /* Check if we have this client cached already. */
4655 client = silc_idlist_find_client_by_id(server->local_list,
4657 server->server_type, &cache);
4659 client = silc_idlist_find_client_by_id(server->global_list,
4661 server->server_type, &cache);
4663 /* If router did not find such Client ID in its lists then this must
4664 be bogus client or some router in the net is buggy. */
4665 if (server->server_type != SILC_SERVER)
4668 /* We don't have that client anywhere, add it. The client is added
4669 to global list since server didn't have it in the lists so it must be
4671 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4672 silc_id_dup(&id.u.client_id,
4674 silc_packet_get_context(sock),
4677 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4681 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4684 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4685 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4686 "%s", channel->channel_name));
4690 if (!silc_server_client_on_channel(client, channel, &chl)) {
4691 /* Client was not on the channel, add it. */
4692 chl = silc_calloc(1, sizeof(*chl));
4693 chl->client = client;
4695 chl->channel = channel;
4696 silc_hash_table_add(channel->user_list, chl->client, chl);
4697 silc_hash_table_add(client->channels, chl->channel, chl);
4698 channel->user_count++;
4706 /* Saves channels and channels user modes to the `client'. Removes
4707 the client from those channels that are not sent in the list but
4710 void silc_server_save_user_channels(SilcServer server,
4711 SilcPacketStream sock,
4712 SilcClientEntry client,
4713 SilcBuffer channels,
4714 SilcBuffer channels_user_modes)
4717 SilcUInt32 *chumodes;
4718 SilcChannelPayload entry;
4719 SilcChannelEntry channel;
4720 SilcChannelID channel_id;
4721 SilcChannelClientEntry chl;
4722 SilcHashTable ht = NULL;
4723 SilcHashTableList htl;
4727 if (!channels || !channels_user_modes ||
4728 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4731 ch = silc_channel_payload_parse_list(channels->data,
4732 silc_buffer_len(channels));
4733 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4735 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4736 NULL, NULL, NULL, TRUE);
4737 silc_dlist_start(ch);
4738 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4739 /* Check if we have this channel, and add it if we don't have it.
4740 Also add the client on the channel unless it is there already. */
4741 if (!silc_channel_get_id_parse(entry, &channel_id))
4743 channel = silc_idlist_find_channel_by_id(server->local_list,
4746 channel = silc_idlist_find_channel_by_id(server->global_list,
4749 if (server->server_type != SILC_SERVER) {
4754 /* We don't have that channel anywhere, add it. */
4755 name = silc_channel_get_name(entry, NULL);
4756 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4757 silc_id_dup(&channel_id,
4759 server->router, NULL, NULL, 0);
4766 channel->mode = silc_channel_get_mode(entry);
4768 /* Add the client on the channel */
4769 if (!silc_server_client_on_channel(client, channel, &chl)) {
4770 chl = silc_calloc(1, sizeof(*chl));
4771 chl->client = client;
4772 chl->mode = chumodes[i++];
4773 chl->channel = channel;
4774 silc_hash_table_add(channel->user_list, chl->client, chl);
4775 silc_hash_table_add(client->channels, chl->channel, chl);
4776 channel->user_count++;
4779 chl->mode = chumodes[i++];
4782 silc_hash_table_add(ht, channel, channel);
4784 silc_channel_payload_list_free(ch);
4785 silc_free(chumodes);
4789 /* Go through the list again and remove client from channels that
4790 are no part of the list. */
4792 silc_hash_table_list(client->channels, &htl);
4793 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4794 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4795 silc_hash_table_del(chl->channel->user_list, chl->client);
4796 silc_hash_table_del(chl->client->channels, chl->channel);
4800 silc_hash_table_list_reset(&htl);
4801 silc_hash_table_free(ht);
4803 silc_hash_table_list(client->channels, &htl);
4804 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4805 silc_hash_table_del(chl->channel->user_list, chl->client);
4806 silc_hash_table_del(chl->client->channels, chl->channel);
4809 silc_hash_table_list_reset(&htl);
4813 /* Lookups route to the client indicated by the `id_data'. The connection
4814 object and internal data object is returned. Returns NULL if route
4815 could not be found to the client. If the `client_id' is specified then
4816 it is used and the `id_data' is ignored. */
4819 silc_server_get_client_route(SilcServer server,
4820 unsigned char *id_data,
4822 SilcClientID *client_id,
4823 SilcIDListData *idata,
4824 SilcClientEntry *client_entry)
4826 SilcClientID *id, clid;
4827 SilcClientEntry client;
4829 SILC_LOG_DEBUG(("Start"));
4832 *client_entry = NULL;
4834 /* Decode destination Client ID */
4836 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
4838 id = silc_id_dup(&clid, SILC_ID_CLIENT);
4840 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4843 /* If the destination belongs to our server we don't have to route
4844 the packet anywhere but to send it to the local destination. */
4845 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4849 /* If we are router and the client has router then the client is in
4850 our cell but not directly connected to us. */
4851 if (server->server_type == SILC_ROUTER && client->router) {
4852 /* We are of course in this case the client's router thus the route
4853 to the client is the server who owns the client. So, we will send
4854 the packet to that server. */
4856 *idata = (SilcIDListData)client->router;
4857 return client->router->connection;
4860 /* Seems that client really is directly connected to us */
4862 *idata = (SilcIDListData)client;
4864 *client_entry = client;
4865 return client->connection;
4868 /* Destination belongs to someone not in this server. If we are normal
4869 server our action is to send the packet to our router. */
4870 if (server->server_type != SILC_ROUTER && !server->standalone) {
4873 *idata = (SilcIDListData)server->router;
4874 return SILC_PRIMARY_ROUTE(server);
4877 /* We are router and we will perform route lookup for the destination
4878 and send the packet to fastest route. */
4879 if (server->server_type == SILC_ROUTER && !server->standalone) {
4880 /* Check first that the ID is valid */
4881 client = silc_idlist_find_client_by_id(server->global_list, id,
4884 SilcPacketStream dst_sock;
4886 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4889 if (idata && dst_sock)
4890 *idata = silc_packet_get_context(dst_sock);
4899 /* Encodes and returns channel list of channels the `client' has joined.
4900 Secret channels are not put to the list. */
4902 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4903 SilcClientEntry client,
4904 SilcBool get_private,
4905 SilcBool get_secret,
4906 SilcBuffer *user_mode_list)
4908 SilcBuffer buffer = NULL;
4909 SilcChannelEntry channel;
4910 SilcChannelClientEntry chl;
4911 SilcHashTableList htl;
4912 unsigned char cid[32];
4914 SilcUInt16 name_len;
4918 *user_mode_list = NULL;
4920 silc_hash_table_list(client->channels, &htl);
4921 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4922 channel = chl->channel;
4924 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4926 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4929 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4930 name_len = strlen(channel->channel_name);
4932 len = 4 + name_len + id_len + 4;
4933 buffer = silc_buffer_realloc(buffer,
4935 silc_buffer_truelen(buffer) + len : len));
4936 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4937 silc_buffer_format(buffer,
4938 SILC_STR_UI_SHORT(name_len),
4939 SILC_STR_DATA(channel->channel_name, name_len),
4940 SILC_STR_UI_SHORT(id_len),
4941 SILC_STR_DATA(cid, id_len),
4942 SILC_STR_UI_INT(chl->channel->mode),
4944 silc_buffer_pull(buffer, len);
4946 if (user_mode_list) {
4948 silc_buffer_realloc(*user_mode_list,
4950 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
4951 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
4952 (*user_mode_list)->data));
4953 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
4954 silc_buffer_pull(*user_mode_list, 4);
4957 silc_hash_table_list_reset(&htl);
4960 silc_buffer_push(buffer, buffer->data - buffer->head);
4961 if (user_mode_list && *user_mode_list)
4962 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
4963 (*user_mode_list)->head));
4968 /* Task callback used to retrieve network statistical information from
4969 router server once in a while. */
4971 SILC_TASK_CALLBACK(silc_server_get_stats)
4973 SilcServer server = (SilcServer)context;
4974 SilcBuffer idp, packet;
4976 if (!server->standalone) {
4977 SILC_LOG_DEBUG(("Retrieving stats from router"));
4978 server->stat.commands_sent++;
4979 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
4981 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
4982 ++server->cmd_ident, 1,
4984 silc_buffer_len(idp));
4985 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4986 SILC_PACKET_COMMAND, 0, packet->data,
4987 silc_buffer_len(packet));
4988 silc_buffer_free(packet);
4989 silc_buffer_free(idp);
4993 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,