5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2009 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /************************* Types and definitions ****************************/
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
28 SILC_TASK_CALLBACK(silc_server_do_rekey);
29 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
30 static void silc_server_accept_new_connection(SilcNetStatus status,
33 static void silc_server_packet_parse_type(SilcServer server,
34 SilcPacketStream sock,
36 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
40 /************************ Static utility functions **************************/
42 /* SKE public key verification callback */
45 silc_server_verify_key(SilcSKE ske,
46 SilcPublicKey public_key,
48 SilcSKEVerifyCbCompletion completion,
49 void *completion_context)
51 SilcPacketStream sock = context;
52 SilcUnknownEntry entry = silc_packet_get_context(sock);
54 SILC_LOG_DEBUG(("Verifying public key"));
56 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
57 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
58 entry->hostname, entry->ip, entry->port,
59 silc_pkcs_get_type(public_key)));
60 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
65 /* We accept all keys without explicit verification */
66 completion(ske, SILC_SKE_STATUS_OK, completion_context);
70 /************************ Packet engine callbacks ***************************/
72 /* Packet engine callback to receive a packet */
74 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
75 SilcPacketStream stream,
77 void *callback_context,
80 SilcServer server = callback_context;
81 SilcIDListData idata = stream_context;
86 /* Packets we do not handle */
87 switch (packet->type) {
88 case SILC_PACKET_HEARTBEAT:
89 case SILC_PACKET_SUCCESS:
90 case SILC_PACKET_FAILURE:
91 case SILC_PACKET_REJECT:
92 case SILC_PACKET_KEY_EXCHANGE:
93 case SILC_PACKET_KEY_EXCHANGE_1:
94 case SILC_PACKET_KEY_EXCHANGE_2:
95 case SILC_PACKET_REKEY_DONE:
96 case SILC_PACKET_CONNECTION_AUTH:
101 /* Only specific packets can come without source ID present. */
102 if ((!packet->src_id ||
103 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
104 packet->type != SILC_PACKET_NEW_CLIENT &&
105 packet->type != SILC_PACKET_NEW_SERVER &&
106 packet->type != SILC_PACKET_RESUME_CLIENT &&
107 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
108 packet->type != SILC_PACKET_DISCONNECT)
111 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and
112 for unregistered connection. */
113 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
114 packet->type == SILC_PACKET_NEW_SERVER) &&
115 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
118 /* Ignore packets from disabled connection */
119 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
120 packet->type != SILC_PACKET_HEARTBEAT &&
121 packet->type != SILC_PACKET_RESUME_ROUTER &&
122 packet->type != SILC_PACKET_REKEY)
125 /* Check that the the current client ID is same as in the client's packet. */
126 if (idata->conn_type == SILC_CONN_CLIENT) {
127 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
128 SilcClientID client_id;
130 if (client->id && packet->src_id &&
131 silc_id_str2id(packet->src_id, packet->src_id_len,
132 packet->src_id_type, &client_id, sizeof(client_id))) {
133 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
134 SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
135 silc_get_packet_name(packet->type)));
141 if (server->server_type == SILC_ROUTER) {
142 /* Route the packet if it is not destined to us. Other ID types but
143 server are handled separately after processing them. */
144 if (packet->dst_id &&
145 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
146 packet->dst_id_type == SILC_ID_SERVER &&
147 idata->conn_type != SILC_CONN_CLIENT &&
148 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
149 SilcPacketStream conn;
150 SilcServerID server_id;
152 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
153 &server_id, sizeof(server_id));
155 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
157 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
158 silc_id_render(&server_id, SILC_ID_SERVER)));
162 silc_server_packet_route(server, conn, packet);
163 silc_packet_free(packet);
168 /* Broadcast packet if it is marked as broadcast packet and it is
169 originated from router and we are router. */
170 if (server->server_type == SILC_ROUTER &&
171 idata->conn_type == SILC_CONN_ROUTER &&
172 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
173 /* Broadcast to our primary route */
174 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
176 /* If we have backup routers then we need to feed all broadcast
177 data to those servers. */
178 silc_server_backup_broadcast(server, stream, packet);
182 silc_server_packet_parse_type(server, stream, packet);
187 /* Packet engine callback to indicate end of stream */
189 static void silc_server_packet_eos(SilcPacketEngine engine,
190 SilcPacketStream stream,
191 void *callback_context,
192 void *stream_context)
194 SilcServer server = callback_context;
195 SilcIDListData idata = silc_packet_get_context(stream);
197 SILC_LOG_DEBUG(("End of stream received, sock %p", stream));
199 if (server->router_conn && server->router_conn->sock == stream &&
200 !server->router && server->standalone) {
201 if (idata && idata->sconn && idata->sconn->callback)
202 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
203 silc_server_create_connections(server);
204 silc_server_free_sock_user_data(server, stream, NULL);
206 /* If backup disconnected then mark that resuming will not be allowed */
208 server->server_type == SILC_ROUTER && !server->backup_router &&
209 idata->conn_type == SILC_CONN_SERVER) {
210 SilcServerEntry server_entry = (SilcServerEntry)idata;
211 if (server_entry->server_type == SILC_BACKUP_ROUTER)
212 server->backup_closed = TRUE;
215 if (idata && idata->sconn && idata->sconn->callback)
216 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
217 silc_server_free_sock_user_data(server, stream, NULL);
220 silc_server_close_connection(server, stream);
223 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
225 SilcServer server = app_context;
226 SilcPacketStream stream = context;
227 SilcIDListData idata = silc_packet_get_context(stream);
229 if (!idata || !silc_packet_stream_is_valid(stream)) {
230 silc_packet_stream_unref(stream);
234 if (server->router_conn && server->router_conn->sock == stream &&
235 !server->router && server->standalone) {
236 if (idata->sconn && idata->sconn->callback)
237 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
238 silc_server_create_connections(server);
239 silc_server_free_sock_user_data(server, stream, NULL);
241 /* If backup disconnected then mark that resuming will not be allowed */
242 if (server->server_type == SILC_ROUTER && !server->backup_router &&
243 idata->conn_type == SILC_CONN_SERVER) {
244 SilcServerEntry server_entry = (SilcServerEntry)idata;
245 if (server_entry->server_type == SILC_BACKUP_ROUTER)
246 server->backup_closed = TRUE;
249 if (idata->sconn && idata->sconn->callback)
250 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
251 silc_server_free_sock_user_data(server, stream, NULL);
254 silc_server_close_connection(server, stream);
256 /* Release our stream reference */
257 silc_packet_stream_unref(stream);
260 /* Packet engine callback to indicate error */
262 static void silc_server_packet_error(SilcPacketEngine engine,
263 SilcPacketStream stream,
264 SilcPacketError error,
265 void *callback_context,
266 void *stream_context)
268 SilcServer server = callback_context;
269 SilcIDListData idata = silc_packet_get_context(stream);
270 SilcStream sock = silc_packet_stream_get_stream(stream);
274 SILC_LOG_DEBUG(("Packet error %d, sock %p", error, stream));
279 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
282 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
283 SILC_CONNTYPE_STRING(idata->conn_type),
284 silc_packet_error_string(error)));
286 if (!silc_packet_stream_is_valid(stream))
289 /* We must take reference of the stream */
290 silc_packet_stream_ref(stream);
292 /* In case we get here many times, register only one timeout */
293 silc_schedule_task_del_by_all(server->schedule, 0,
294 silc_server_packet_error_timeout, stream);
296 /* Close connection with random timeout */
297 silc_schedule_task_add_timeout(server->schedule,
298 silc_server_packet_error_timeout, stream,
299 silc_rng_get_byte(server->rng) % 10, 0);
302 /* Packet stream callbacks */
303 static SilcPacketCallbacks silc_server_stream_cbs =
305 silc_server_packet_receive,
306 silc_server_packet_eos,
307 silc_server_packet_error
310 /* Parses the packet type and calls what ever routines the packet type
311 requires. This is done for all incoming packets. */
313 static void silc_server_packet_parse_type(SilcServer server,
314 SilcPacketStream sock,
317 SilcPacketType type = packet->type;
318 SilcIDListData idata = silc_packet_get_context(sock);
323 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
324 NULL, NULL, &ip, &port);
325 #endif /* SILC_DEBUG */
327 SILC_LOG_DEBUG(("Received %s packet [flags %d] from %s:%d",
328 silc_get_packet_name(type), packet->flags, ip, port));
330 /* Parse the packet type */
332 case SILC_PACKET_NOTIFY:
334 * Received notify packet. Server can receive notify packets from
335 * router. Server then relays the notify messages to clients if needed.
337 if (packet->flags & SILC_PACKET_FLAG_LIST)
338 silc_server_notify_list(server, sock, packet);
340 silc_server_notify(server, sock, packet);
344 * Private Message packets
346 case SILC_PACKET_PRIVATE_MESSAGE:
348 * Received private message packet. The packet is coming from either
351 if (packet->flags & SILC_PACKET_FLAG_LIST)
353 idata->last_receive = time(NULL);
354 silc_server_private_message(server, sock, packet);
360 case SILC_PACKET_CHANNEL_MESSAGE:
362 * Received channel message. Channel messages are special packets
363 * (although probably most common ones) thus they are handled
366 if (packet->flags & SILC_PACKET_FLAG_LIST)
368 idata->last_receive = time(NULL);
369 silc_server_channel_message(server, sock, packet);
375 case SILC_PACKET_COMMAND:
377 * Recived command. Processes the command request and allocates the
378 * command context and calls the command.
380 if (packet->flags & SILC_PACKET_FLAG_LIST)
382 server->stat.commands_received++;
383 silc_server_command_process(server, sock, packet);
386 case SILC_PACKET_COMMAND_REPLY:
388 * Received command reply packet. Received command reply to command. It
389 * may be reply to command sent by us or reply to command sent by client
390 * that we've routed further.
392 if (packet->flags & SILC_PACKET_FLAG_LIST)
394 server->stat.commands_received++;
395 silc_server_command_reply(server, sock, packet);
398 case SILC_PACKET_DISCONNECT:
401 char *message = NULL;
402 const char *hostname, *ip;
404 if (packet->flags & SILC_PACKET_FLAG_LIST)
406 if (silc_buffer_len(&packet->buffer) < 1)
409 status = (SilcStatus)packet->buffer.data[0];
410 if (silc_buffer_len(&packet->buffer) > 1 &&
411 silc_utf8_valid(packet->buffer.data + 1,
412 silc_buffer_len(&packet->buffer) - 1))
413 message = silc_memdup(packet->buffer.data + 1,
414 silc_buffer_len(&packet->buffer) - 1);
416 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
417 NULL, &hostname, &ip, NULL))
420 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
421 silc_get_status_message(status), status,
422 message ? message : ""));
426 /* Do not switch to backup in case of error */
427 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
429 /* If backup disconnected then mark that resuming will not be allowed */
430 if (server->server_type == SILC_ROUTER && !server->backup_router &&
431 idata->conn_type == SILC_CONN_SERVER) {
432 SilcServerEntry server_entry = (SilcServerEntry)idata;
433 if (server_entry->server_type == SILC_BACKUP_ROUTER)
434 server->backup_closed = TRUE;
437 /* Handle the disconnection from our end too */
438 if (SILC_IS_LOCAL(idata))
439 silc_server_free_sock_user_data(server, sock, NULL);
440 silc_server_close_connection(server, sock);
441 server->backup_noswitch = FALSE;
445 case SILC_PACKET_CHANNEL_KEY:
447 * Received key for channel. As channels are created by the router
448 * the keys are as well. We will distribute the key to all of our
449 * locally connected clients on the particular channel. Router
450 * never receives this channel and thus is ignored.
452 if (packet->flags & SILC_PACKET_FLAG_LIST)
454 silc_server_channel_key(server, sock, packet);
457 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
459 * Private message key packet.
461 if (packet->flags & SILC_PACKET_FLAG_LIST)
463 silc_server_private_message_key(server, sock, packet);
466 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
468 * Connection authentication request packet. When we receive this packet
469 * we will send to the other end information about our mandatory
470 * authentication method for the connection. This packet maybe received
473 if (packet->flags & SILC_PACKET_FLAG_LIST)
475 silc_server_connection_auth_request(server, sock, packet);
478 case SILC_PACKET_NEW_ID:
480 * Received New ID packet. This includes some new ID that has been
481 * created. It may be for client, server or channel. This is the way
482 * to distribute information about new registered entities in the
485 if (packet->flags & SILC_PACKET_FLAG_LIST)
486 silc_server_new_id_list(server, sock, packet);
488 silc_server_new_id(server, sock, packet);
491 case SILC_PACKET_NEW_CLIENT:
493 * Received new client packet. This includes client information that
494 * we will use to create initial client ID. After creating new
495 * ID we will send it to the client.
497 if (packet->flags & SILC_PACKET_FLAG_LIST)
499 silc_server_new_client(server, sock, packet);
502 case SILC_PACKET_NEW_SERVER:
504 * Received new server packet. This includes Server ID and some other
505 * information that we may save. This is received after server has
508 if (packet->flags & SILC_PACKET_FLAG_LIST)
510 silc_server_new_server(server, sock, packet);
513 case SILC_PACKET_NEW_CHANNEL:
515 * Received new channel packet. Information about new channel in the
516 * network are distributed using this packet.
518 if (packet->flags & SILC_PACKET_FLAG_LIST)
519 silc_server_new_channel_list(server, sock, packet);
521 silc_server_new_channel(server, sock, packet);
524 case SILC_PACKET_HEARTBEAT:
526 * Received heartbeat.
528 if (packet->flags & SILC_PACKET_FLAG_LIST)
532 case SILC_PACKET_KEY_AGREEMENT:
534 * Received key agreement.
536 if (packet->flags & SILC_PACKET_FLAG_LIST)
538 silc_server_key_agreement(server, sock, packet);
541 case SILC_PACKET_REKEY:
543 * Received re-key packet. The sender wants to regenerate the session
546 if (packet->flags & SILC_PACKET_FLAG_LIST)
548 silc_server_rekey(server, sock, packet);
551 case SILC_PACKET_FTP:
553 if (packet->flags & SILC_PACKET_FLAG_LIST)
555 silc_server_ftp(server, sock, packet);
558 case SILC_PACKET_RESUME_CLIENT:
560 if (packet->flags & SILC_PACKET_FLAG_LIST)
562 silc_server_resume_client(server, sock, packet);
565 case SILC_PACKET_RESUME_ROUTER:
566 /* Resume router packet received. This packet is received for backup
567 router resuming protocol. */
568 if (packet->flags & SILC_PACKET_FLAG_LIST)
570 silc_server_backup_resume_router(server, sock, packet);
574 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
579 /****************************** Server API **********************************/
581 /* Allocates a new SILC server object. This has to be done before the server
582 can be used. After allocation one must call silc_server_init to initialize
583 the server. The new allocated server object is returned to the new_server
586 SilcBool silc_server_alloc(SilcServer *new_server)
590 SILC_LOG_DEBUG(("Allocating new server object"));
592 server = silc_calloc(1, sizeof(*server));
595 server->server_type = SILC_SERVER;
596 server->standalone = TRUE;
597 server->local_list = silc_calloc(1, sizeof(*server->local_list));
598 if (!server->local_list)
600 server->global_list = silc_calloc(1, sizeof(*server->global_list));
601 if (!server->global_list)
603 server->pending_commands = silc_dlist_init();
604 if (!server->pending_commands)
606 server->listeners = silc_dlist_init();
607 if (!server->listeners)
609 server->repository = silc_skr_alloc();
610 if (!server->repository)
612 server->conns = silc_dlist_init();
615 server->expired_clients = silc_dlist_init();
616 if (!server->expired_clients)
619 *new_server = server;
624 /* Free's the SILC server object. This is called at the very end before
627 void silc_server_free(SilcServer server)
630 SilcIDCacheEntry cache;
631 SilcIDListData idata;
633 SILC_LOG_DEBUG(("Free server %p", server));
638 silc_server_backup_free(server);
639 silc_server_config_unref(&server->config_ref);
641 silc_rng_free(server->rng);
642 if (server->public_key)
643 silc_pkcs_public_key_free(server->public_key);
644 if (server->private_key)
645 silc_pkcs_private_key_free(server->private_key);
646 if (server->pending_commands)
647 silc_dlist_uninit(server->pending_commands);
648 if (server->id_entry) {
649 if (server->id_entry->data.sconn)
650 silc_schedule_task_del_by_context(server->schedule,
651 server->id_entry->data.sconn->sock);
652 silc_idlist_del_server(server->local_list, server->id_entry);
655 /* Delete all channels */
656 if (silc_idcache_get_all(server->local_list->channels, &list)) {
657 silc_list_start(list);
658 while ((cache = silc_list_get(list)))
659 silc_idlist_del_channel(server->local_list, cache->context);
661 if (silc_idcache_get_all(server->global_list->channels, &list)) {
662 silc_list_start(list);
663 while ((cache = silc_list_get(list)))
664 silc_idlist_del_channel(server->global_list, cache->context);
667 /* Delete all clients */
668 if (silc_idcache_get_all(server->local_list->clients, &list)) {
669 silc_list_start(list);
670 while ((cache = silc_list_get(list))) {
671 silc_schedule_task_del_by_context(server->schedule, cache->context);
672 silc_idlist_del_client(server->local_list, cache->context);
675 if (silc_idcache_get_all(server->global_list->clients, &list)) {
676 silc_list_start(list);
677 while ((cache = silc_list_get(list))) {
678 silc_schedule_task_del_by_context(server->schedule, cache->context);
679 silc_idlist_del_client(server->global_list, cache->context);
683 /* Delete all servers */
684 if (silc_idcache_get_all(server->local_list->servers, &list)) {
685 silc_list_start(list);
686 while ((cache = silc_list_get(list))) {
687 idata = (SilcIDListData)cache->context;
689 silc_schedule_task_del_by_context(server->schedule,
691 silc_idlist_del_server(server->local_list, cache->context);
694 if (silc_idcache_get_all(server->global_list->servers, &list)) {
695 while ((cache = silc_list_get(list))) {
696 idata = (SilcIDListData)cache->context;
698 silc_schedule_task_del_by_context(server->schedule,
700 silc_idlist_del_server(server->global_list, cache->context);
704 silc_schedule_task_del_by_context(server->schedule, server);
705 silc_schedule_uninit(server->schedule);
706 server->schedule = NULL;
708 silc_idcache_free(server->local_list->clients);
709 silc_idcache_free(server->local_list->servers);
710 silc_idcache_free(server->local_list->channels);
711 silc_idcache_free(server->global_list->clients);
712 silc_idcache_free(server->global_list->servers);
713 silc_idcache_free(server->global_list->channels);
714 silc_hash_table_free(server->watcher_list);
715 silc_hash_table_free(server->watcher_list_pk);
716 silc_hash_free(server->md5hash);
717 silc_hash_free(server->sha1hash);
719 silc_dlist_uninit(server->listeners);
720 silc_dlist_uninit(server->conns);
721 silc_dlist_uninit(server->expired_clients);
722 silc_skr_free(server->repository);
723 silc_packet_engine_stop(server->packet_engine);
725 silc_free(server->local_list);
726 silc_free(server->global_list);
727 silc_free(server->server_name);
728 silc_free(server->id);
731 silc_hmac_unregister_all();
732 silc_hash_unregister_all();
733 silc_cipher_unregister_all();
734 silc_pkcs_unregister_all();
737 /* Creates a new server listener. */
739 static SilcNetListener
740 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
742 SilcNetListener listener;
745 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
746 server->config->require_reverse_lookup,
748 silc_server_accept_new_connection, server);
750 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
758 /* Adds a secondary listener. */
760 SilcBool silc_server_init_secondary(SilcServer server)
762 SilcServerConfigServerInfoInterface *interface;
763 SilcNetListener listener;
765 for (interface = server->config->server_info->secondary; interface;
766 interface = interface->next) {
767 listener = silc_server_listen(server, interface->server_ip,
771 silc_dlist_add(server->listeners, listener);
777 /* Initializes the entire SILC server. This is called always before running
778 the server. This is called only once at the initialization of the program.
779 This binds the server to its listenning port. After this function returns
780 one should call silc_server_run to start the server. This returns TRUE
781 when everything is ok to run the server. Configuration file must be
782 read and parsed before calling this. */
784 SilcBool silc_server_init(SilcServer server)
787 SilcServerEntry id_entry;
788 SilcNetListener listener;
792 SILC_LOG_DEBUG(("Initializing server"));
794 server->starttime = time(NULL);
796 /* Take config object for us */
797 silc_server_config_ref(&server->config_ref, server->config,
801 /* Set debugging on if configured */
802 if (server->config->debug_string) {
803 silc_log_debug(TRUE);
804 silc_log_set_debug_string(server->config->debug_string);
806 #endif /* SILC_DEBUG */
808 /* Steal public and private key from the config object */
809 server->public_key = server->config->server_info->public_key;
810 server->private_key = server->config->server_info->private_key;
811 server->config->server_info->public_key = NULL;
812 server->config->server_info->private_key = NULL;
814 /* Register all configured ciphers, PKCS and hash functions. */
815 if (!silc_server_config_register_ciphers(server))
816 silc_cipher_register_default();
817 if (!silc_server_config_register_pkcs(server))
818 silc_pkcs_register_default();
819 if (!silc_server_config_register_hashfuncs(server))
820 silc_hash_register_default();
821 if (!silc_server_config_register_hmacs(server))
822 silc_hmac_register_default();
824 /* Initialize random number generator for the server. */
825 server->rng = silc_rng_alloc();
826 silc_rng_init(server->rng);
827 silc_rng_global_init(server->rng);
829 /* Initialize hash functions for server to use */
830 silc_hash_alloc("md5", &server->md5hash);
831 silc_hash_alloc("sha1", &server->sha1hash);
833 /* Initialize the scheduler */
834 server->schedule = silc_schedule_init(server->config->param.connections_max,
836 if (!server->schedule)
839 /* First, register log files configuration for error output */
840 silc_server_config_setlogfiles(server);
842 /* Initialize ID caches */
843 server->local_list->clients =
844 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
846 server->local_list->servers =
847 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
849 server->local_list->channels =
850 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
853 /* These are allocated for normal server as well as these hold some
854 global information that the server has fetched from its router. For
855 router these are used as they are supposed to be used on router. */
856 server->global_list->clients =
857 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
859 server->global_list->servers =
860 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
862 server->global_list->channels =
863 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
866 /* Init watcher lists */
867 server->watcher_list =
868 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
869 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
871 if (!server->watcher_list)
873 server->watcher_list_pk =
874 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
875 silc_hash_public_key_compare, NULL,
877 if (!server->watcher_list_pk)
880 /* Create TCP listener */
881 listener = silc_server_listen(
883 server->config->server_info->primary == NULL ? NULL :
884 server->config->server_info->primary->server_ip,
885 server->config->server_info->primary == NULL ? 0 :
886 server->config->server_info->primary->port);
889 silc_dlist_add(server->listeners, listener);
891 /* Create a Server ID for the server. */
892 port = silc_net_listener_get_port(listener, NULL);
893 ip = silc_net_listener_get_ip(listener, NULL);
894 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
895 server->config->server_info->primary->public_ip :
896 ip[0], port[0], server->rng, &id);
905 server->server_name = server->config->server_info->server_name;
906 server->config->server_info->server_name = NULL;
907 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
908 sizeof(server->id_string), &server->id_string_len);
910 /* Add ourselves to the server list. We don't have a router yet
911 beacuse we haven't established a route yet. It will be done later.
912 For now, NULL is sent as router. This allocates new entry to
915 silc_idlist_add_server(server->local_list, strdup(server->server_name),
917 silc_id_dup(server->id, SILC_ID_SERVER),
920 SILC_LOG_ERROR(("Could not add local server to cache"));
923 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
924 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
925 SILC_CONN_SERVER : SILC_CONN_ROUTER);
926 server->id_entry = id_entry;
928 /* Create secondary TCP listeners */
929 if (silc_server_init_secondary(server) == FALSE)
932 server->listenning = TRUE;
934 /* Create connections to configured routers. */
935 silc_server_create_connections(server);
937 /* If server connections has been configured then we must be router as
938 normal server cannot have server connections, only router connections. */
939 if (server->config->servers) {
940 SilcServerConfigServer *ptr = server->config->servers;
942 server->server_type = SILC_ROUTER;
944 if (ptr->backup_router) {
945 server->server_type = SILC_BACKUP_ROUTER;
946 server->backup_router = TRUE;
947 server->id_entry->server_type = SILC_BACKUP_ROUTER;
954 if (server->server_type != SILC_ROUTER) {
955 server->stat.servers = 1;
956 server->stat.cell_servers = 1;
958 server->stat.routers = 1;
961 /* If we are normal server we'll retrieve network statisticial information
962 once in a while from the router. */
963 if (server->server_type != SILC_ROUTER)
964 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
967 /* Start packet engine */
968 server->packet_engine =
969 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
970 &silc_server_stream_cbs, server);
971 if (!server->packet_engine)
974 /* Register client entry expiration timeout */
975 silc_schedule_task_add_timeout(server->schedule,
976 silc_server_purge_expired_clients, server,
979 /* Initialize HTTP server */
980 silc_server_http_init(server);
982 SILC_LOG_DEBUG(("Server initialized"));
984 /* We are done here, return succesfully */
988 silc_server_config_unref(&server->config_ref);
992 /* Task callback to close a socket connection after rehash */
994 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
996 SilcServer server = app_context;
997 SilcPacketStream sock = context;
998 SilcIDListData idata = silc_packet_get_context(sock);
999 const char *hostname;
1002 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1003 NULL, &hostname, NULL, &port);
1005 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
1006 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
1007 silc_schedule_task_del_by_context(server->schedule, sock);
1008 silc_server_disconnect_remote(server, sock,
1009 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1010 "This connection is removed from "
1012 silc_server_free_sock_user_data(server, sock, NULL);
1015 /* This function basically reads the config file again and switches the config
1016 object pointed by the server object. After that, we have to fix various
1017 things such as the server_name and the listening ports.
1018 Keep in mind that we no longer have the root privileges at this point. */
1020 SilcBool silc_server_rehash(SilcServer server)
1022 SilcServerConfig newconfig;
1024 SILC_LOG_INFO(("Rehashing server"));
1026 /* Reset the logging system */
1027 silc_log_quick(TRUE);
1028 silc_log_flush_all();
1030 /* Start the main rehash phase (read again the config file) */
1031 newconfig = silc_server_config_alloc(server->config_file, server);
1033 SILC_LOG_ERROR(("Rehash FAILED."));
1037 /* Fix the server_name field */
1038 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1039 silc_free(server->server_name);
1041 /* Check server name */
1042 server->server_name =
1043 silc_identifier_check(newconfig->server_info->server_name,
1044 strlen(newconfig->server_info->server_name),
1045 SILC_STRING_LOCALE, 256, NULL);
1046 if (!server->server_name) {
1047 SILC_LOG_ERROR(("Malformed server name string '%s'",
1048 server->config->server_info->server_name));
1052 /* Update the idcache list with a fresh pointer */
1053 silc_free(server->id_entry->server_name);
1054 server->id_entry->server_name = strdup(server->server_name);
1055 silc_idcache_update_by_context(server->local_list->servers,
1056 server->id_entry, NULL,
1057 strdup(server->id_entry->server_name),
1062 silc_server_config_setlogfiles(server);
1064 /* Change new key pair if necessary */
1065 if (newconfig->server_info->public_key &&
1066 !silc_pkcs_public_key_compare(server->public_key,
1067 newconfig->server_info->public_key)) {
1068 silc_pkcs_public_key_free(server->public_key);
1069 silc_pkcs_private_key_free(server->private_key);
1070 server->public_key = newconfig->server_info->public_key;
1071 server->private_key = newconfig->server_info->private_key;
1072 newconfig->server_info->public_key = NULL;
1073 newconfig->server_info->private_key = NULL;
1076 /* Check for unconfigured server and router connections and close
1077 connections that were unconfigured. */
1079 if (server->config->routers) {
1080 SilcServerConfigRouter *ptr;
1081 SilcServerConfigRouter *newptr;
1084 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1087 /* Check whether new config has this one too */
1088 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1089 if (silc_string_compare(newptr->host, ptr->host) &&
1090 newptr->port == ptr->port &&
1091 newptr->initiator == ptr->initiator) {
1097 if (!found && ptr->host) {
1098 /* Remove this connection */
1099 SilcPacketStream sock;
1100 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1101 ptr->host, ptr->port);
1103 silc_schedule_task_add_timeout(server->schedule,
1104 silc_server_rehash_close_connection,
1110 if (server->config->servers) {
1111 SilcServerConfigServer *ptr;
1112 SilcServerConfigServer *newptr;
1115 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1118 /* Check whether new config has this one too */
1119 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1120 if (silc_string_compare(newptr->host, ptr->host)) {
1126 if (!found && ptr->host) {
1127 /* Remove this connection */
1128 SilcPacketStream sock;
1129 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1132 silc_schedule_task_add_timeout(server->schedule,
1133 silc_server_rehash_close_connection,
1139 if (server->config->clients) {
1140 SilcServerConfigClient *ptr;
1141 SilcServerConfigClient *newptr;
1144 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1147 /* Check whether new config has this one too */
1148 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1149 if (silc_string_compare(newptr->host, ptr->host)) {
1155 if (!found && ptr->host) {
1156 /* Remove this connection */
1157 SilcPacketStream sock;
1158 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1161 silc_schedule_task_add_timeout(server->schedule,
1162 silc_server_rehash_close_connection,
1168 /* Create connections after rehash */
1169 silc_server_create_connections(server);
1171 /* Check whether our router status has changed */
1172 if (newconfig->servers) {
1173 SilcServerConfigServer *ptr = newconfig->servers;
1175 server->server_type = SILC_ROUTER;
1177 if (ptr->backup_router) {
1178 server->server_type = SILC_BACKUP_ROUTER;
1179 server->backup_router = TRUE;
1180 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1187 /* Our old config is gone now. We'll unreference our reference made in
1188 silc_server_init and then destroy it since we are destroying it
1189 underneath the application (layer which called silc_server_init). */
1190 silc_server_config_unref(&server->config_ref);
1191 silc_server_config_destroy(server->config);
1193 /* Take new config context */
1194 server->config = newconfig;
1195 silc_server_config_ref(&server->config_ref, server->config, server->config);
1198 /* Set debugging on if configured */
1199 if (server->config->debug_string) {
1200 silc_log_debug(TRUE);
1201 silc_log_set_debug_string(server->config->debug_string);
1203 #endif /* SILC_DEBUG */
1205 SILC_LOG_DEBUG(("Server rehashed"));
1210 /* The heart of the server. This runs the scheduler thus runs the server.
1211 When this returns the server has been stopped and the program will
1214 void silc_server_run(SilcServer server)
1216 SILC_LOG_INFO(("SILC Server started"));
1218 /* Start the scheduler, the heart of the SILC server. When this returns
1219 the program will be terminated. */
1220 silc_schedule(server->schedule);
1223 /* Stops the SILC server. This function is used to shutdown the server.
1224 This is usually called after the scheduler has returned. After stopping
1225 the server one should call silc_server_free. */
1227 void silc_server_stop(SilcServer server)
1230 SilcPacketStream ps;
1231 SilcNetListener listener;
1233 SILC_LOG_INFO(("SILC Server shutting down"));
1235 server->server_shutdown = TRUE;
1237 /* Close all connections */
1238 if (server->packet_engine) {
1239 list = silc_packet_engine_get_streams(server->packet_engine);
1241 silc_dlist_start(list);
1242 while ((ps = silc_dlist_get(list))) {
1243 SilcIDListData idata = silc_packet_get_context(ps);
1245 if (!silc_packet_stream_is_valid(ps))
1249 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1251 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1252 "Server is shutting down");
1253 silc_server_free_sock_user_data(server, ps,
1254 "Server is shutting down");
1256 silc_packet_engine_free_streams_list(list);
1259 /* We are not connected to network anymore */
1260 server->standalone = TRUE;
1262 silc_dlist_start(server->listeners);
1263 while ((listener = silc_dlist_get(server->listeners)))
1264 silc_net_close_listener(listener);
1266 silc_server_http_uninit(server);
1268 /* Cancel any possible retry timeouts */
1269 silc_schedule_task_del_by_callback(server->schedule,
1270 silc_server_connect_router);
1271 silc_schedule_task_del_by_callback(server->schedule,
1272 silc_server_connect_to_router_retry);
1273 silc_schedule_task_del_by_callback(server->schedule,
1274 silc_server_connect_to_router);
1276 silc_schedule_stop(server->schedule);
1278 SILC_LOG_DEBUG(("Server stopped"));
1281 /* Purge expired client entries from the server */
1283 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1285 SilcServer server = context;
1286 SilcClientEntry client;
1288 SilcUInt64 curtime = silc_time();
1290 SILC_LOG_DEBUG(("Expire timeout"));
1292 silc_dlist_start(server->expired_clients);
1293 while ((client = silc_dlist_get(server->expired_clients))) {
1294 /* For unregistered clients the created timestamp is actually
1295 unregistered timestamp. Make sure client remains in history
1296 at least 500 seconds. */
1297 if (client->data.created && curtime - client->data.created < 500)
1300 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1301 server->local_list : server->global_list);
1303 silc_idlist_del_data(client);
1304 silc_idlist_del_client(id_list, client);
1305 silc_dlist_del(server->expired_clients, client);
1308 silc_schedule_task_add_timeout(server->schedule,
1309 silc_server_purge_expired_clients, server,
1314 /******************************* Connecting *********************************/
1316 /* Free connection context */
1318 void silc_server_connection_free(SilcServerConnection sconn)
1322 SILC_LOG_DEBUG(("Free connection %p", sconn));
1323 silc_dlist_del(sconn->server->conns, sconn);
1324 silc_server_config_unref(&sconn->conn);
1325 silc_free(sconn->remote_host);
1326 silc_free(sconn->backup_replace_ip);
1330 /* Creates connection to a remote router. */
1332 void silc_server_create_connection(SilcServer server,
1335 const char *remote_host, SilcUInt32 port,
1336 SilcServerConnectCallback callback,
1339 SilcServerConnection sconn;
1341 /* Allocate connection object for hold connection specific stuff. */
1342 sconn = silc_calloc(1, sizeof(*sconn));
1345 sconn->remote_host = strdup(remote_host);
1346 sconn->remote_port = port;
1347 sconn->no_reconnect = reconnect == FALSE;
1348 sconn->callback = callback;
1349 sconn->callback_context = context;
1350 sconn->no_conf = dynamic;
1351 sconn->server = server;
1353 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1354 remote_host, port));
1356 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1360 /* Connection authentication completion callback */
1363 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1366 SilcServerConnection sconn = context;
1367 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1368 SilcServer server = entry->server;
1369 SilcServerConfigServer *conn;
1370 SilcServerConfigConnParams *param;
1371 SilcIDListData idata;
1372 SilcServerEntry id_entry = NULL;
1373 unsigned char id[32];
1378 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1383 if (success == FALSE) {
1384 /* Authentication failed */
1386 /* Try reconnecting if configuration wants it */
1387 if (!sconn->no_reconnect) {
1388 silc_schedule_task_add_timeout(server->schedule,
1389 silc_server_connect_to_router_retry,
1391 silc_dlist_del(server->conns, sconn);
1395 if (sconn->callback)
1396 (*sconn->callback)(server, NULL, sconn->callback_context);
1397 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1398 silc_server_disconnect_remote(server, sconn->sock,
1399 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1403 /* XXX For now remote is router always */
1404 entry->data.conn_type = SILC_CONN_ROUTER;
1406 SILC_LOG_INFO(("Connected to %s %s",
1407 SILC_CONNTYPE_STRING(entry->data.conn_type),
1408 sconn->remote_host));
1410 /* Create the actual entry for remote entity */
1411 switch (entry->data.conn_type) {
1412 case SILC_CONN_SERVER:
1413 SILC_LOG_DEBUG(("Remote is SILC server"));
1415 /* Add new server. The server must register itself to us before it
1416 becomes registered to SILC network. */
1417 id_entry = silc_idlist_add_server(server->local_list,
1418 strdup(sconn->remote_host),
1419 SILC_SERVER, NULL, NULL, sconn->sock);
1421 if (sconn->callback)
1422 (*sconn->callback)(server, NULL, sconn->callback_context);
1423 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1424 silc_server_disconnect_remote(server, sconn->sock,
1425 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1430 server->stat.my_servers++;
1431 if (server->server_type == SILC_ROUTER)
1432 server->stat.servers++;
1433 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1435 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1438 case SILC_CONN_ROUTER:
1439 SILC_LOG_DEBUG(("Remote is SILC router"));
1441 /* Register to network */
1442 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1443 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1444 SILC_STR_UI_SHORT(id_len),
1445 SILC_STR_DATA(id, id_len),
1446 SILC_STR_UI_SHORT(strlen(server->server_name)),
1447 SILC_STR_DATA(server->server_name,
1448 strlen(server->server_name)),
1450 if (sconn->callback)
1451 (*sconn->callback)(server, NULL, sconn->callback_context);
1452 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1453 silc_server_disconnect_remote(server, sconn->sock,
1454 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1459 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1461 /* Check that we do not have this ID already */
1462 id_entry = silc_idlist_find_server_by_id(server->local_list,
1463 &remote_id.u.server_id,
1466 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1468 id_entry = silc_idlist_find_server_by_id(server->global_list,
1469 &remote_id.u.server_id,
1472 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1476 SILC_LOG_DEBUG(("New server id(%s)",
1477 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1479 /* Add the connected router to global server list. Router is sent
1480 as NULL since it's local to us. */
1481 id_entry = silc_idlist_add_server(server->global_list,
1482 strdup(sconn->remote_host),
1484 silc_id_dup(&remote_id.u.server_id,
1488 /* Try reconnecting if configuration wants it */
1489 if (!sconn->no_reconnect) {
1490 silc_schedule_task_add_timeout(server->schedule,
1491 silc_server_connect_to_router_retry,
1493 silc_dlist_del(server->conns, sconn);
1497 if (sconn->callback)
1498 (*sconn->callback)(server, NULL, sconn->callback_context);
1499 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1500 silc_server_disconnect_remote(server, sconn->sock,
1501 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1506 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1507 idata = (SilcIDListData)id_entry;
1508 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1509 SILC_IDLIST_STATUS_LOCAL);
1510 idata->sconn = sconn;
1511 idata->sconn->callback = NULL;
1514 server->stat.my_routers++;
1515 if (server->server_type == SILC_ROUTER)
1516 server->stat.routers++;
1517 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1519 if (!sconn->backup) {
1520 /* Mark this router our primary router if we're still standalone */
1521 if (server->standalone) {
1522 SILC_LOG_DEBUG(("This connection is our primary router"));
1523 server->id_entry->router = id_entry;
1524 server->router = id_entry;
1525 server->router->server_type = SILC_ROUTER;
1526 server->standalone = FALSE;
1527 server->backup_primary = FALSE;
1529 /* Announce data if we are not backup router (unless not as primary
1530 currently). Backup router announces later at the end of
1531 resuming protocol. */
1532 if (server->backup_router && server->server_type == SILC_ROUTER) {
1533 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1535 /* If we are router then announce our possible servers. Backup
1536 router announces also global servers. */
1537 if (server->server_type == SILC_ROUTER)
1538 silc_server_announce_servers(server,
1539 server->backup_router ? TRUE : FALSE,
1540 0, SILC_PRIMARY_ROUTE(server));
1542 /* Announce our clients and channels to the router */
1543 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1544 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1547 /* If we are backup router then this primary router is whom we are
1549 if (server->server_type == SILC_BACKUP_ROUTER) {
1550 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1552 NULL, NULL, &ip, NULL);
1553 silc_server_backup_add(server, server->id_entry, ip,
1554 sconn->remote_port, TRUE);
1559 /* We already have primary router. Disconnect this connection */
1560 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1561 silc_idlist_del_server(server->global_list, id_entry);
1562 if (sconn->callback)
1563 (*sconn->callback)(server, NULL, sconn->callback_context);
1564 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1565 silc_server_disconnect_remote(server, sconn->sock,
1566 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1571 /* Add this server to be our backup router */
1572 id_entry->server_type = SILC_BACKUP_ROUTER;
1573 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1574 sconn->backup_replace_port, FALSE);
1580 if (sconn->callback)
1581 (*sconn->callback)(server, NULL, sconn->callback_context);
1582 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1583 silc_server_disconnect_remote(server, sconn->sock,
1584 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1588 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1590 conn = sconn->conn.ref_ptr;
1591 param = &server->config->param;
1592 if (conn && conn->param)
1593 param = conn->param;
1595 /* Register rekey timeout */
1596 sconn->rekey_timeout = param->key_exchange_rekey;
1597 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1598 sconn->sock, sconn->rekey_timeout, 0);
1600 /* Set the entry as packet stream context */
1601 silc_packet_set_context(sconn->sock, id_entry);
1603 /* Call the completion callback to indicate that we've connected to
1605 if (sconn && sconn->callback)
1606 (*sconn->callback)(server, id_entry, sconn->callback_context);
1608 if (sconn == server->router_conn)
1609 server->router_conn = NULL;
1614 /* SKE completion callback */
1616 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1617 SilcSKESecurityProperties prop,
1618 SilcSKEKeyMaterial keymat,
1619 SilcSKERekeyMaterial rekey,
1622 SilcPacketStream sock = context;
1623 SilcUnknownEntry entry = silc_packet_get_context(sock);
1624 SilcServerConnection sconn;
1626 SilcServerConfigRouter *conn;
1627 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1628 void *auth_data = NULL;
1629 SilcUInt32 auth_data_len = 0;
1630 SilcConnAuth connauth;
1631 SilcCipher send_key, receive_key;
1632 SilcHmac hmac_send, hmac_receive;
1634 server = entry->server;
1635 sconn = entry->data.sconn;
1636 conn = sconn->conn.ref_ptr;
1639 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1641 if (status != SILC_SKE_STATUS_OK) {
1643 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1644 silc_ske_map_status(status), entry->hostname, entry->ip));
1647 /* Try reconnecting if configuration wants it */
1648 if (!sconn->no_reconnect) {
1649 silc_schedule_task_add_timeout(server->schedule,
1650 silc_server_connect_to_router_retry,
1652 silc_dlist_del(server->conns, sconn);
1656 if (sconn->callback)
1657 (*sconn->callback)(server, NULL, sconn->callback_context);
1658 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1659 silc_server_disconnect_remote(server, sconn->sock,
1660 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1664 SILC_LOG_DEBUG(("Setting keys into use"));
1666 /* Set the keys into use. The data will be encrypted after this. */
1667 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1668 &hmac_send, &hmac_receive, NULL)) {
1671 /* Try reconnecting if configuration wants it */
1672 if (!sconn->no_reconnect) {
1673 silc_schedule_task_add_timeout(server->schedule,
1674 silc_server_connect_to_router_retry,
1676 silc_dlist_del(server->conns, sconn);
1680 /* Error setting keys */
1681 if (sconn->callback)
1682 (*sconn->callback)(server, NULL, sconn->callback_context);
1683 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1684 silc_server_disconnect_remote(server, sconn->sock,
1685 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1688 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1689 hmac_receive, FALSE);
1691 SILC_LOG_DEBUG(("Starting connection authentication"));
1693 connauth = silc_connauth_alloc(server->schedule, ske,
1694 server->config->conn_auth_timeout);
1698 /* Try reconnecting if configuration wants it */
1699 if (!sconn->no_reconnect) {
1700 silc_schedule_task_add_timeout(server->schedule,
1701 silc_server_connect_to_router_retry,
1703 silc_dlist_del(server->conns, sconn);
1707 /** Error allocating auth protocol */
1708 if (sconn->callback)
1709 (*sconn->callback)(server, NULL, sconn->callback_context);
1710 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1711 silc_server_disconnect_remote(server, sconn->sock,
1712 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1716 /* Get authentication method */
1718 if (conn->passphrase) {
1719 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1720 auth_meth = SILC_AUTH_PUBLIC_KEY;
1721 auth_data = server->private_key;
1723 auth_meth = SILC_AUTH_PASSWORD;
1724 auth_data = conn->passphrase;
1725 auth_data_len = conn->passphrase_len;
1728 auth_meth = SILC_AUTH_PUBLIC_KEY;
1729 auth_data = server->private_key;
1733 entry->data.rekey = rekey;
1735 /* Start connection authentication */
1737 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1738 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1739 auth_data, auth_data_len,
1740 silc_server_ke_auth_compl, sconn);
1743 /* Function that is called when the network connection to a router has
1744 been established. This will continue with the key exchange protocol
1745 with the remote router. */
1747 void silc_server_start_key_exchange(SilcServerConnection sconn)
1749 SilcServer server = sconn->server;
1750 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1751 SilcUnknownEntry entry;
1752 SilcSKEParamsStruct params;
1755 /* Cancel any possible retry timeouts */
1756 silc_schedule_task_del_by_context(server->schedule, sconn);
1758 /* Create packet stream */
1759 sconn->sock = silc_packet_stream_create(server->packet_engine,
1760 server->schedule, sconn->stream);
1762 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1763 silc_stream_destroy(sconn->stream);
1765 /* Try reconnecting if configuration wants it */
1766 if (!sconn->no_reconnect) {
1767 silc_schedule_task_add_timeout(server->schedule,
1768 silc_server_connect_to_router_retry,
1770 silc_dlist_del(server->conns, sconn);
1774 if (sconn->callback)
1775 (*sconn->callback)(server, NULL, sconn->callback_context);
1776 silc_server_connection_free(sconn);
1779 server->stat.conn_num++;
1781 /* Set source ID to packet stream */
1782 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1784 silc_packet_stream_destroy(sconn->sock);
1786 /* Try reconnecting if configuration wants it */
1787 if (!sconn->no_reconnect) {
1788 silc_schedule_task_add_timeout(server->schedule,
1789 silc_server_connect_to_router_retry,
1791 silc_dlist_del(server->conns, sconn);
1795 if (sconn->callback)
1796 (*sconn->callback)(server, NULL, sconn->callback_context);
1797 silc_server_connection_free(sconn);
1801 /* Create entry for remote entity */
1802 entry = silc_calloc(1, sizeof(*entry));
1804 silc_packet_stream_destroy(sconn->sock);
1806 /* Try reconnecting if configuration wants it */
1807 if (!sconn->no_reconnect) {
1808 silc_schedule_task_add_timeout(server->schedule,
1809 silc_server_connect_to_router_retry,
1811 silc_dlist_del(server->conns, sconn);
1815 if (sconn->callback)
1816 (*sconn->callback)(server, NULL, sconn->callback_context);
1817 silc_server_connection_free(sconn);
1820 entry->server = server;
1821 entry->data.sconn = sconn;
1822 entry->data.conn_type = SILC_CONN_UNKNOWN;
1823 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1824 silc_packet_set_context(sconn->sock, entry);
1826 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1828 /* Set Key Exchange flags from configuration, but fall back to global
1830 memset(¶ms, 0, sizeof(params));
1831 SILC_GET_SKE_FLAGS(conn, params.flags);
1832 if (server->config->param.key_exchange_pfs)
1833 params.flags |= SILC_SKE_SP_FLAG_PFS;
1835 /* Start SILC Key Exchange protocol */
1836 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1837 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1838 server->public_key, server->private_key, sconn);
1841 silc_packet_stream_destroy(sconn->sock);
1843 /* Try reconnecting if configuration wants it */
1844 if (!sconn->no_reconnect) {
1845 silc_schedule_task_add_timeout(server->schedule,
1846 silc_server_connect_to_router_retry,
1848 silc_dlist_del(server->conns, sconn);
1852 if (sconn->callback)
1853 (*sconn->callback)(server, NULL, sconn->callback_context);
1854 silc_server_connection_free(sconn);
1857 silc_ske_set_callbacks(ske, silc_server_verify_key,
1858 silc_server_ke_completed, sconn->sock);
1860 /* Start key exchange protocol */
1861 params.version = silc_version_string;
1862 params.timeout_secs = server->config->key_exchange_timeout;
1863 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1866 /* Timeout callback that will be called to retry connecting to remote
1867 router. This is used by both normal and router server. This will wait
1868 before retrying the connecting. The timeout is generated by exponential
1869 backoff algorithm. */
1871 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1873 SilcServerConnection sconn = context;
1874 SilcServer server = sconn->server;
1875 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1876 SilcServerConfigConnParams *param =
1877 (conn->param ? conn->param : &server->config->param);
1879 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1880 sconn->remote_port));
1882 /* Calculate next timeout */
1883 if (sconn->retry_count >= 1) {
1884 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1885 if (sconn->retry_timeout > param->reconnect_interval_max)
1886 sconn->retry_timeout = param->reconnect_interval_max;
1888 sconn->retry_timeout = param->reconnect_interval;
1890 sconn->retry_count++;
1891 sconn->retry_timeout = sconn->retry_timeout +
1892 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1894 /* If we've reached max retry count, give up. */
1895 if ((sconn->retry_count > param->reconnect_count) &&
1896 sconn->no_reconnect) {
1897 SILC_LOG_ERROR(("Could not connect, giving up"));
1899 if (sconn->callback)
1900 (*sconn->callback)(server, NULL, sconn->callback_context);
1901 silc_server_connection_free(sconn);
1905 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1907 /* We will lookup a fresh pointer later */
1908 silc_server_config_unref(&sconn->conn);
1910 /* Wait before retrying */
1911 silc_schedule_task_del_by_context(server->schedule, sconn);
1912 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1913 sconn, sconn->retry_timeout, 0);
1916 /* Callback for async connection to remote router */
1918 static void silc_server_connection_established(SilcNetStatus status,
1922 SilcServerConnection sconn = context;
1923 SilcServer server = sconn->server;
1925 silc_schedule_task_del_by_context(server->schedule, sconn);
1930 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1931 sconn->remote_host, sconn->remote_port));
1933 /* Continue with key exchange protocol */
1934 sconn->stream = stream;
1935 silc_server_start_key_exchange(sconn);
1938 case SILC_NET_UNKNOWN_IP:
1939 case SILC_NET_UNKNOWN_HOST:
1940 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1941 sconn->remote_host, sconn->remote_port,
1942 silc_net_get_error_string(status)));
1943 if (!sconn->no_reconnect) {
1944 silc_schedule_task_add_timeout(sconn->server->schedule,
1945 silc_server_connect_to_router_retry,
1947 silc_dlist_del(server->conns, sconn);
1949 if (sconn->callback)
1950 (*sconn->callback)(server, NULL, sconn->callback_context);
1951 silc_server_connection_free(sconn);
1956 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1957 sconn->remote_host, sconn->remote_port,
1958 silc_net_get_error_string(status)));
1959 if (!sconn->no_reconnect) {
1960 silc_schedule_task_add_timeout(sconn->server->schedule,
1961 silc_server_connect_to_router_retry,
1963 silc_dlist_del(server->conns, sconn);
1965 if (sconn->callback)
1966 (*sconn->callback)(server, NULL, sconn->callback_context);
1967 silc_server_connection_free(sconn);
1973 /* Generic routine to use connect to a router. */
1975 SILC_TASK_CALLBACK(silc_server_connect_router)
1977 SilcServerConnection sconn = context;
1978 SilcServer server = sconn->server;
1979 SilcServerConfigRouter *rconn;
1981 silc_schedule_task_del_by_context(server->schedule, sconn);
1983 /* Don't connect if we are shutting down. */
1984 if (server->server_shutdown) {
1985 if (sconn->callback)
1986 (*sconn->callback)(server, NULL, sconn->callback_context);
1987 silc_server_connection_free(sconn);
1991 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1992 (sconn->backup ? "backup router" : "router"),
1993 sconn->remote_host, sconn->remote_port));
1995 if (!sconn->no_conf) {
1996 /* Find connection configuration */
1997 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1998 sconn->remote_port);
2000 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
2001 (sconn->backup ? "backup router" : "router"),
2002 sconn->remote_host, sconn->remote_port));
2003 if (sconn->callback)
2004 (*sconn->callback)(server, NULL, sconn->callback_context);
2005 silc_server_connection_free(sconn);
2008 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
2011 /* Connect to remote host */
2013 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
2014 server->config->server_info->primary->server_ip),
2015 sconn->remote_host, sconn->remote_port,
2016 server->schedule, silc_server_connection_established,
2019 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2020 sconn->remote_host, sconn->remote_port));
2021 if (sconn->callback)
2022 (*sconn->callback)(server, NULL, sconn->callback_context);
2023 silc_server_connection_free(sconn);
2027 /* Add to connection list */
2028 silc_dlist_add(server->conns, sconn);
2031 /* This function connects to our primary router or if we are a router this
2032 establishes all our primary routes. This is called at the start of the
2033 server to do authentication and key exchange with our router - called
2036 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2038 SilcServer server = context;
2039 SilcServerConnection sconn;
2040 SilcServerConfigRouter *ptr;
2041 SilcServerConfigConnParams *param;
2043 /* Don't connect if we are shutting down. */
2044 if (server->server_shutdown)
2047 SILC_LOG_DEBUG(("We are %s",
2048 (server->server_type == SILC_SERVER ?
2049 "normal server" : server->server_type == SILC_ROUTER ?
2050 "router" : "backup router/normal server")));
2052 if (!server->config->routers) {
2053 /* There wasn't a configured router, we will continue but we don't
2054 have a connection to outside world. We will be standalone server. */
2055 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2056 server->standalone = TRUE;
2060 /* Cancel any possible retry timeouts */
2061 silc_schedule_task_del_by_callback(server->schedule,
2062 silc_server_connect_router);
2063 silc_schedule_task_del_by_callback(server->schedule,
2064 silc_server_connect_to_router_retry);
2066 /* Create the connections to all our routes */
2067 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2069 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2070 ptr->backup_router ? "Backup router" : "Router",
2071 ptr->initiator ? "Initiator" : "Responder",
2072 ptr->host, ptr->port));
2074 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2075 ptr->initiator == FALSE && !server->backup_router &&
2076 !silc_server_config_get_backup_router(server))
2077 server->wait_backup = TRUE;
2079 if (!ptr->initiator)
2081 if (ptr->dynamic_connection)
2084 /* Check whether we are connecting or connected to this host already */
2085 if (silc_server_num_sockets_by_remote(server,
2086 silc_net_is_ip(ptr->host) ?
2088 silc_net_is_ip(ptr->host) ?
2089 NULL : ptr->host, ptr->port,
2090 SILC_CONN_ROUTER)) {
2091 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2092 ptr->host, ptr->port));
2094 /* If we don't have primary router and this connection is our
2095 primary router we are in desync. Reconnect to the primary. */
2096 if (server->standalone && !server->router) {
2098 SilcPacketStream sock;
2099 SilcServerConfigRouter *primary =
2100 silc_server_config_get_primary_router(server);
2103 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2104 ptr->host, ptr->port);
2107 server->backup_noswitch = TRUE;
2108 silc_server_free_sock_user_data(server, sock, NULL);
2109 silc_server_disconnect_remote(server, sock, 0, NULL);
2110 server->backup_noswitch = FALSE;
2111 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2117 param = (ptr->param ? ptr->param : &server->config->param);
2119 /* Allocate connection object for hold connection specific stuff. */
2120 sconn = silc_calloc(1, sizeof(*sconn));
2123 sconn->server = server;
2124 sconn->remote_host = strdup(ptr->host);
2125 sconn->remote_port = ptr->port;
2126 sconn->backup = ptr->backup_router;
2127 if (sconn->backup) {
2128 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2129 sconn->backup_replace_port = ptr->backup_replace_port;
2131 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2133 SILC_LOG_DEBUG(("Created connection %p", sconn));
2135 if (!server->router_conn && !sconn->backup)
2136 server->router_conn = sconn;
2139 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2145 /************************ Accepting new connection **************************/
2147 /* After this is called, server don't wait for backup router anymore.
2148 This gets called automatically even after we have backup router
2149 connection established. */
2151 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2153 SilcServer server = context;
2154 server->wait_backup = FALSE;
2157 /* Authentication data callback */
2160 silc_server_accept_get_auth(SilcConnAuth connauth,
2161 SilcConnectionType conn_type,
2162 unsigned char **passphrase,
2163 SilcUInt32 *passphrase_len,
2164 SilcSKR *repository,
2167 SilcPacketStream sock = context;
2168 SilcUnknownEntry entry = silc_packet_get_context(sock);
2169 SilcServer server = entry->server;
2171 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2173 /* Remote end is client */
2174 if (conn_type == SILC_CONN_CLIENT) {
2175 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2179 *passphrase = cconfig->passphrase;
2180 *passphrase_len = cconfig->passphrase_len;
2181 if (cconfig->publickeys)
2182 *repository = server->repository;
2184 if (cconfig->publickeys) {
2185 if (server->config->prefer_passphrase_auth) {
2189 *passphrase_len = 0;
2193 entry->conn_type = conn_type;
2197 /* Remote end is server */
2198 if (conn_type == SILC_CONN_SERVER) {
2199 SilcServerConfigServer *sconfig;
2201 /* If we are normal server, don't accept the connection */
2202 if (server->server_type == SILC_SERVER)
2205 sconfig = entry->sconfig.ref_ptr;
2209 *passphrase = sconfig->passphrase;
2210 *passphrase_len = sconfig->passphrase_len;
2211 if (sconfig->publickeys)
2212 *repository = server->repository;
2214 if (sconfig->publickeys) {
2215 if (server->config->prefer_passphrase_auth) {
2219 *passphrase_len = 0;
2223 entry->conn_type = conn_type;
2227 /* Remote end is router */
2228 if (conn_type == SILC_CONN_ROUTER) {
2229 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2233 *passphrase = rconfig->passphrase;
2234 *passphrase_len = rconfig->passphrase_len;
2235 if (rconfig->publickeys)
2236 *repository = server->repository;
2238 if (rconfig->publickeys) {
2239 if (server->config->prefer_passphrase_auth) {
2243 *passphrase_len = 0;
2247 entry->conn_type = conn_type;
2254 /* Authentication completion callback. */
2257 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2260 SilcPacketStream sock = context;
2261 SilcUnknownEntry entry = silc_packet_get_context(sock);
2262 SilcIDListData idata = (SilcIDListData)entry;
2263 SilcServer server = entry->server;
2264 SilcServerConfigConnParams *param = &server->config->param;
2265 SilcServerConnection sconn;
2267 const char *hostname, *ip;
2271 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2272 NULL, &hostname, &ip, &port);
2274 if (success == FALSE) {
2275 /* Authentication failed */
2276 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2277 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2278 server->stat.auth_failures++;
2279 silc_server_disconnect_remote(server, sock,
2280 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2281 silc_server_config_unref(&entry->cconfig);
2282 silc_server_config_unref(&entry->sconfig);
2283 silc_server_config_unref(&entry->rconfig);
2284 silc_server_free_sock_user_data(server, sock, NULL);
2288 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2290 switch (entry->conn_type) {
2291 case SILC_CONN_CLIENT:
2293 SilcClientEntry client;
2294 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2296 /* Verify whether this connection is after all allowed to connect */
2297 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2298 &server->config->param,
2300 silc_connauth_get_ske(connauth))) {
2301 server->stat.auth_failures++;
2305 /* If we are primary router and we have backup router configured
2306 but it has not connected to use yet, do not accept any other
2308 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2309 !server->backup_router) {
2310 SilcServerConfigRouter *router;
2311 router = silc_server_config_get_backup_router(server);
2312 if (router && strcmp(server->config->server_info->primary->server_ip,
2314 silc_server_find_socket_by_host(server,
2316 router->backup_replace_ip, 0)) {
2317 SILC_LOG_INFO(("Will not accept connections because we do "
2318 "not have backup router connection established"));
2319 silc_server_disconnect_remote(server, sock,
2320 SILC_STATUS_ERR_PERM_DENIED,
2321 "We do not have connection to backup "
2322 "router established, try later");
2323 silc_server_config_unref(&entry->cconfig);
2324 silc_server_config_unref(&entry->sconfig);
2325 silc_server_config_unref(&entry->rconfig);
2326 silc_server_free_sock_user_data(server, sock, NULL);
2327 server->stat.auth_failures++;
2329 /* From here on, wait 20 seconds for the backup router to appear. */
2330 silc_schedule_task_add_timeout(server->schedule,
2331 silc_server_backup_router_wait,
2332 (void *)server, 20, 0);
2337 SILC_LOG_DEBUG(("Remote host is client"));
2338 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2341 /* Add the client to the client ID cache. The nickname and Client ID
2342 and other information is created after we have received NEW_CLIENT
2343 packet from client. */
2344 client = silc_idlist_add_client(server->local_list,
2345 NULL, NULL, NULL, NULL, NULL, sock);
2347 SILC_LOG_ERROR(("Could not add new client to cache"));
2348 server->stat.auth_failures++;
2349 silc_server_disconnect_remote(server, sock,
2350 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2351 silc_server_config_unref(&entry->cconfig);
2352 silc_server_config_unref(&entry->sconfig);
2353 silc_server_config_unref(&entry->rconfig);
2354 silc_server_free_sock_user_data(server, sock, NULL);
2357 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2358 entry->data.conn_type = SILC_CONN_CLIENT;
2361 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
2362 server->stat.clients + 1));
2363 server->stat.my_clients++;
2364 server->stat.clients++;
2365 server->stat.cell_clients++;
2367 /* Get connection parameters */
2369 param = conn->param;
2371 if (!param->keepalive_secs)
2372 param->keepalive_secs = server->config->param.keepalive_secs;
2374 if (!param->qos && server->config->param.qos) {
2375 param->qos = server->config->param.qos;
2376 param->qos_rate_limit = server->config->param.qos_rate_limit;
2377 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2378 param->qos_limit_sec = server->config->param.qos_limit_sec;
2379 param->qos_limit_usec = server->config->param.qos_limit_usec;
2382 /* Check if to be anonymous connection */
2383 if (param->anonymous)
2384 client->mode |= SILC_UMODE_ANONYMOUS;
2387 /* Add public key to repository */
2388 SILC_LOG_DEBUG(("Add client public key to repository"));
2389 if (!silc_server_get_public_key_by_client(server, client, NULL))
2390 silc_skr_add_public_key_simple(server->repository,
2391 entry->data.public_key,
2392 SILC_SKR_USAGE_IDENTIFICATION, client,
2395 id_entry = (void *)client;
2399 case SILC_CONN_SERVER:
2400 case SILC_CONN_ROUTER:
2402 SilcServerEntry new_server;
2403 SilcBool initiator = FALSE;
2404 SilcBool backup_local = FALSE;
2405 SilcBool backup_router = FALSE;
2406 char *backup_replace_ip = NULL;
2407 SilcUInt16 backup_replace_port = 0;
2408 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2409 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2411 /* If we are backup router and this is incoming server connection
2412 and we do not have connection to primary router, do not allow
2414 if (server->server_type == SILC_BACKUP_ROUTER &&
2415 entry->conn_type == SILC_CONN_SERVER &&
2416 !SILC_PRIMARY_ROUTE(server)) {
2417 SILC_LOG_INFO(("Will not accept server connection because we do "
2418 "not have primary router connection established"));
2419 silc_server_disconnect_remote(server, sock,
2420 SILC_STATUS_ERR_PERM_DENIED,
2421 "We do not have connection to primary "
2422 "router established, try later");
2423 silc_server_config_unref(&entry->cconfig);
2424 silc_server_config_unref(&entry->sconfig);
2425 silc_server_config_unref(&entry->rconfig);
2426 silc_server_free_sock_user_data(server, sock, NULL);
2427 server->stat.auth_failures++;
2431 if (entry->conn_type == SILC_CONN_ROUTER) {
2432 /* Verify whether this connection is after all allowed to connect */
2433 if (!silc_server_connection_allowed(server, sock,
2435 &server->config->param,
2436 rconn ? rconn->param : NULL,
2437 silc_connauth_get_ske(connauth))) {
2438 silc_server_config_unref(&entry->cconfig);
2439 silc_server_config_unref(&entry->sconfig);
2440 silc_server_config_unref(&entry->rconfig);
2441 server->stat.auth_failures++;
2447 param = rconn->param;
2449 if (!param->keepalive_secs)
2450 param->keepalive_secs = server->config->param.keepalive_secs;
2452 if (!param->qos && server->config->param.qos) {
2453 param->qos = server->config->param.qos;
2454 param->qos_rate_limit = server->config->param.qos_rate_limit;
2455 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2456 param->qos_limit_sec = server->config->param.qos_limit_sec;
2457 param->qos_limit_usec = server->config->param.qos_limit_usec;
2461 initiator = rconn->initiator;
2462 backup_local = rconn->backup_local;
2463 backup_router = rconn->backup_router;
2464 backup_replace_ip = rconn->backup_replace_ip;
2465 backup_replace_port = rconn->backup_replace_port;
2469 if (entry->conn_type == SILC_CONN_SERVER) {
2470 /* Verify whether this connection is after all allowed to connect */
2471 if (!silc_server_connection_allowed(server, sock,
2473 &server->config->param,
2474 srvconn ? srvconn->param : NULL,
2475 silc_connauth_get_ske(connauth))) {
2476 server->stat.auth_failures++;
2480 if (srvconn->param) {
2481 param = srvconn->param;
2483 if (!param->keepalive_secs)
2484 param->keepalive_secs = server->config->param.keepalive_secs;
2486 if (!param->qos && server->config->param.qos) {
2487 param->qos = server->config->param.qos;
2488 param->qos_rate_limit = server->config->param.qos_rate_limit;
2489 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2490 param->qos_limit_sec = server->config->param.qos_limit_sec;
2491 param->qos_limit_usec = server->config->param.qos_limit_usec;
2495 backup_router = srvconn->backup_router;
2499 /* If we are primary router and we have backup router configured
2500 but it has not connected to use yet, do not accept any other
2502 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2503 !server->backup_router && !backup_router) {
2504 SilcServerConfigRouter *router;
2505 router = silc_server_config_get_backup_router(server);
2506 if (router && strcmp(server->config->server_info->primary->server_ip,
2508 silc_server_find_socket_by_host(server,
2510 router->backup_replace_ip, 0)) {
2511 SILC_LOG_INFO(("Will not accept connections because we do "
2512 "not have backup router connection established"));
2513 silc_server_disconnect_remote(server, sock,
2514 SILC_STATUS_ERR_PERM_DENIED,
2515 "We do not have connection to backup "
2516 "router established, try later");
2517 silc_server_config_unref(&entry->cconfig);
2518 silc_server_config_unref(&entry->sconfig);
2519 silc_server_config_unref(&entry->rconfig);
2520 silc_server_free_sock_user_data(server, sock, NULL);
2521 server->stat.auth_failures++;
2523 /* From here on, wait 20 seconds for the backup router to appear. */
2524 silc_schedule_task_add_timeout(server->schedule,
2525 silc_server_backup_router_wait,
2526 (void *)server, 20, 0);
2531 SILC_LOG_DEBUG(("Remote host is %s",
2532 entry->conn_type == SILC_CONN_SERVER ?
2533 "server" : (backup_router ?
2534 "backup router" : "router")));
2535 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2536 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2537 "server" : (backup_router ?
2538 "backup router" : "router")));
2540 /* Add the server into server cache. The server name and Server ID
2541 is updated after we have received NEW_SERVER packet from the
2542 server. We mark ourselves as router for this server if we really
2545 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2546 server->local_list : (backup_router ?
2547 server->local_list :
2548 server->global_list)),
2550 (entry->conn_type == SILC_CONN_SERVER ?
2551 SILC_SERVER : SILC_ROUTER),
2553 (entry->conn_type == SILC_CONN_SERVER ?
2554 server->id_entry : (backup_router ?
2555 server->id_entry : NULL)),
2558 SILC_LOG_ERROR(("Could not add new server to cache"));
2559 silc_server_disconnect_remote(server, sock,
2560 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2561 silc_server_config_unref(&entry->cconfig);
2562 silc_server_config_unref(&entry->sconfig);
2563 silc_server_config_unref(&entry->rconfig);
2564 silc_server_free_sock_user_data(server, sock, NULL);
2565 server->stat.auth_failures++;
2568 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2569 entry->data.conn_type = entry->conn_type;
2571 id_entry = (void *)new_server;
2573 /* If the incoming connection is router and marked as backup router
2574 then add it to be one of our backups */
2575 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2576 /* Change it back to SERVER type since that's what it really is. */
2578 entry->data.conn_type = SILC_CONN_SERVER;
2579 new_server->server_type = SILC_BACKUP_ROUTER;
2581 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2582 ("Backup router %s is now online",
2585 /* Remove the backup waiting with timeout */
2586 silc_schedule_task_add_timeout(server->schedule,
2587 silc_server_backup_router_wait,
2588 (void *)server, 10, 0);
2592 if (entry->data.conn_type == SILC_CONN_SERVER) {
2593 server->stat.my_servers++;
2594 server->stat.servers++;
2595 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2597 server->stat.my_routers++;
2598 server->stat.routers++;
2599 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2602 /* Check whether this connection is to be our primary router connection
2603 if we do not already have the primary route. */
2604 if (!backup_router &&
2605 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2606 if (silc_server_config_is_primary_route(server) && !initiator)
2609 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2610 server->standalone = FALSE;
2611 if (!server->id_entry->router) {
2612 server->id_entry->router = id_entry;
2613 server->router = id_entry;
2625 /* Add connection to server->conns so that we know we have connection
2627 sconn = silc_calloc(1, sizeof(*sconn));
2630 sconn->server = server;
2632 sconn->remote_host = strdup(hostname);
2633 sconn->remote_port = port;
2634 silc_dlist_add(server->conns, sconn);
2635 idata->sconn = sconn;
2636 idata->sconn->callback = NULL;
2637 idata->last_receive = time(NULL);
2639 /* Add the common data structure to the ID entry. */
2640 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2641 silc_packet_set_context(sock, id_entry);
2643 /* Connection has been fully established now. Everything is ok. */
2644 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2646 /* Perform Quality of Service */
2648 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2649 param->qos_rate_limit, param->qos_bytes_limit,
2650 param->qos_limit_sec, param->qos_limit_usec);
2652 /* Perform heartbeat */
2653 if (param->keepalive_secs) {
2654 SILC_LOG_DEBUG(("Perform heartbeat every %d seconds",
2655 param->keepalive_secs));
2656 silc_schedule_task_add_timeout(server->schedule, silc_server_do_heartbeat,
2657 sock, param->keepalive_secs, 0);
2660 silc_server_config_unref(&entry->cconfig);
2661 silc_server_config_unref(&entry->sconfig);
2662 silc_server_config_unref(&entry->rconfig);
2666 silc_ske_free(silc_connauth_get_ske(connauth));
2667 silc_connauth_free(connauth);
2670 /* SKE completion callback. We set the new keys into use here. */
2673 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2674 SilcSKESecurityProperties prop,
2675 SilcSKEKeyMaterial keymat,
2676 SilcSKERekeyMaterial rekey,
2679 SilcPacketStream sock = context;
2680 SilcUnknownEntry entry = silc_packet_get_context(sock);
2681 SilcIDListData idata = (SilcIDListData)entry;
2682 SilcServer server = entry->server;
2683 SilcConnAuth connauth;
2684 SilcCipher send_key, receive_key;
2685 SilcHmac hmac_send, hmac_receive;
2692 if (status != SILC_SKE_STATUS_OK) {
2694 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2695 silc_ske_map_status(status), entry->hostname, entry->ip));
2697 silc_server_disconnect_remote(server, sock,
2698 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2699 silc_server_config_unref(&entry->cconfig);
2700 silc_server_config_unref(&entry->sconfig);
2701 silc_server_config_unref(&entry->rconfig);
2702 silc_server_free_sock_user_data(server, sock, NULL);
2706 SILC_LOG_DEBUG(("Setting keys into use"));
2708 /* Set the keys into use. The data will be encrypted after this. */
2709 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2710 &hmac_send, &hmac_receive, &hash)) {
2711 /* Error setting keys */
2713 silc_server_disconnect_remote(server, sock,
2714 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2715 silc_server_free_sock_user_data(server, sock, NULL);
2718 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2719 hmac_receive, FALSE);
2721 idata->rekey = rekey;
2722 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2723 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2725 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2730 SILC_LOG_DEBUG(("Starting connection authentication"));
2731 server->stat.auth_attempts++;
2733 connauth = silc_connauth_alloc(server->schedule, ske,
2734 server->config->conn_auth_timeout);
2736 /** Error allocating auth protocol */
2738 silc_server_disconnect_remote(server, sock,
2739 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2740 silc_server_config_unref(&entry->cconfig);
2741 silc_server_config_unref(&entry->sconfig);
2742 silc_server_config_unref(&entry->rconfig);
2743 silc_server_free_sock_user_data(server, sock, NULL);
2747 /* Start connection authentication */
2749 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2750 silc_server_accept_auth_compl, sock);
2753 /* Accept new TCP connection */
2755 static void silc_server_accept_new_connection(SilcNetStatus status,
2759 SilcServer server = context;
2760 SilcPacketStream packet_stream;
2761 SilcServerConfigClient *cconfig = NULL;
2762 SilcServerConfigServer *sconfig = NULL;
2763 SilcServerConfigRouter *rconfig = NULL;
2764 SilcServerConfigDeny *deny;
2765 SilcUnknownEntry entry;
2767 SilcSKEParamsStruct params;
2768 char *hostname, *ip;
2771 SILC_LOG_DEBUG(("Accepting new connection"));
2773 /* Check for maximum allowed connections */
2774 server->stat.conn_attempts++;
2775 if (silc_dlist_count(server->conns) >
2776 server->config->param.connections_max) {
2777 SILC_LOG_ERROR(("Refusing connection, server is full"));
2778 server->stat.conn_failures++;
2779 silc_stream_destroy(stream);
2783 /* Get hostname, IP and port */
2784 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2785 (const char **)&ip, &port)) {
2786 /* Bad socket stream */
2787 server->stat.conn_failures++;
2788 silc_stream_destroy(stream);
2792 /* Create packet stream */
2793 packet_stream = silc_packet_stream_create(server->packet_engine,
2794 server->schedule, stream);
2795 if (!packet_stream) {
2796 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2797 server->stat.conn_failures++;
2798 silc_stream_destroy(stream);
2801 server->stat.conn_num++;
2803 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2805 /* Set source ID to packet stream */
2806 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2809 server->stat.conn_failures++;
2810 silc_packet_stream_destroy(packet_stream);
2814 /* Check whether this connection is denied to connect to us. */
2815 deny = silc_server_config_find_denied(server, ip);
2817 deny = silc_server_config_find_denied(server, hostname);
2819 /* The connection is denied */
2820 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2821 silc_server_disconnect_remote(server, packet_stream,
2822 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2824 silc_server_free_sock_user_data(server, packet_stream, NULL);
2828 /* Check whether we have configured this sort of connection at all. We
2829 have to check all configurations since we don't know what type of
2830 connection this is. */
2831 if (!(cconfig = silc_server_config_find_client(server, ip)))
2832 cconfig = silc_server_config_find_client(server, hostname);
2833 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2834 sconfig = silc_server_config_find_server_conn(server, hostname);
2835 if (server->server_type == SILC_ROUTER)
2836 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2837 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2838 if (!cconfig && !sconfig && !rconfig) {
2839 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2840 server->stat.conn_failures++;
2841 silc_server_disconnect_remote(server, packet_stream,
2842 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2843 silc_server_free_sock_user_data(server, packet_stream, NULL);
2847 /* The connection is allowed */
2848 entry = silc_calloc(1, sizeof(*entry));
2850 server->stat.conn_failures++;
2851 silc_server_disconnect_remote(server, packet_stream,
2852 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2853 silc_server_free_sock_user_data(server, packet_stream, NULL);
2856 entry->hostname = hostname;
2859 entry->server = server;
2860 entry->data.conn_type = SILC_CONN_UNKNOWN;
2861 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2862 silc_packet_set_context(packet_stream, entry);
2864 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2866 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2867 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2868 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2870 /* Take flags for key exchange. Since we do not know what type of connection
2871 this is, we go through all found configurations and use the global ones
2872 as well. This will result always into strictest key exchange flags. */
2873 memset(¶ms, 0, sizeof(params));
2874 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2875 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2876 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2877 if (server->config->param.key_exchange_pfs)
2878 params.flags |= SILC_SKE_SP_FLAG_PFS;
2880 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2881 server->stat.conn_attempts++;
2883 /* Start SILC Key Exchange protocol */
2884 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2885 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2886 server->public_key, server->private_key,
2889 server->stat.conn_failures++;
2890 silc_server_disconnect_remote(server, packet_stream,
2891 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2892 silc_server_free_sock_user_data(server, packet_stream, NULL);
2895 silc_ske_set_callbacks(ske, silc_server_verify_key,
2896 silc_server_accept_completed, packet_stream);
2898 /* Start key exchange protocol */
2899 params.version = silc_version_string;
2900 params.timeout_secs = server->config->key_exchange_timeout;
2901 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2904 /* Perform heartbeat */
2906 SILC_TASK_CALLBACK(silc_server_do_heartbeat)
2908 SilcServer server = app_context;
2909 SilcPacketStream sock = context;
2910 silc_server_send_heartbeat(server, sock);
2914 /********************************** Rekey ***********************************/
2916 /* Initiator rekey completion callback */
2918 static void silc_server_rekey_completion(SilcSKE ske,
2919 SilcSKEStatus status,
2920 const SilcSKESecurityProperties prop,
2921 const SilcSKEKeyMaterial keymat,
2922 SilcSKERekeyMaterial rekey,
2925 SilcPacketStream sock = context;
2926 SilcIDListData idata = silc_packet_get_context(sock);
2927 SilcServer server = idata->sconn->server;
2929 idata->sconn->op = NULL;
2930 if (status != SILC_SKE_STATUS_OK) {
2931 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2932 idata->sconn->remote_host));
2936 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2937 idata->sconn->remote_host, idata->sconn->remote_port,
2938 SILC_CONNTYPE_STRING(idata->conn_type)));
2940 /* Save rekey data for next rekey */
2941 idata->rekey = rekey;
2943 /* Register new rekey timeout */
2944 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2945 sock, idata->sconn->rekey_timeout, 0);
2948 /* Helper to stop future rekeys on a link. */
2949 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2951 if (!client->connection)
2954 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2956 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2957 client->connection);
2960 /* Rekey callback. Start rekey as initiator */
2962 SILC_TASK_CALLBACK(silc_server_do_rekey)
2964 SilcServer server = app_context;
2965 SilcPacketStream sock = context;
2966 SilcIDListData idata = silc_packet_get_context(sock);
2969 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2971 /* Do not execute rekey with disabled connections */
2972 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2975 /* If another protocol is active do not start rekey */
2976 if (idata->sconn->op) {
2977 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2978 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2983 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2984 idata->sconn->remote_host, idata->sconn->remote_port,
2985 SILC_CONNTYPE_STRING(idata->conn_type)));
2988 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2989 server->public_key, NULL, sock);
2993 /* Set SKE callbacks */
2994 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2997 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
3000 /* Responder rekey completion callback */
3003 silc_server_rekey_resp_completion(SilcSKE ske,
3004 SilcSKEStatus status,
3005 const SilcSKESecurityProperties prop,
3006 const SilcSKEKeyMaterial keymat,
3007 SilcSKERekeyMaterial rekey,
3010 SilcPacketStream sock = context;
3011 SilcIDListData idata = silc_packet_get_context(sock);
3013 idata->sconn->op = NULL;
3014 if (status != SILC_SKE_STATUS_OK) {
3015 SILC_LOG_ERROR(("Error during rekey protocol with %s",
3016 idata->sconn->remote_host));
3020 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
3021 idata->sconn->remote_host, idata->sconn->remote_port,
3022 SILC_CONNTYPE_STRING(idata->conn_type)));
3024 /* Save rekey data for next rekey */
3025 idata->rekey = rekey;
3028 /* Start rekey as responder */
3030 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
3033 SilcIDListData idata = silc_packet_get_context(sock);
3036 if (!idata->rekey) {
3037 silc_packet_free(packet);
3040 if (idata->conn_type == SILC_CONN_UNKNOWN) {
3041 silc_packet_free(packet);
3045 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3046 idata->sconn->remote_host, idata->sconn->remote_port,
3047 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3050 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3051 server->public_key, NULL, sock);
3053 silc_packet_free(packet);
3057 /* Set SKE callbacks */
3058 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3061 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3066 /****************************** Disconnection *******************************/
3068 /* Destroys packet stream. */
3070 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3072 silc_packet_stream_unref(context);
3075 /* Closes connection to socket connection */
3077 void silc_server_close_connection(SilcServer server,
3078 SilcPacketStream sock)
3080 SilcIDListData idata = silc_packet_get_context(sock);
3082 const char *hostname;
3085 if (!silc_packet_stream_is_valid(sock))
3088 memset(tmp, 0, sizeof(tmp));
3089 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3090 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3091 NULL, &hostname, NULL, &port);
3092 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3093 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3094 tmp[0] ? tmp : ""));
3096 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3098 if (idata && idata->sconn) {
3099 silc_server_connection_free(idata->sconn);
3100 idata->sconn = NULL;
3103 /* Take a reference and then destroy the stream. The last reference
3104 is released later in a timeout callback. */
3105 silc_packet_stream_ref(sock);
3106 silc_packet_stream_destroy(sock);
3108 /* Close connection with timeout */
3109 server->stat.conn_num--;
3110 silc_schedule_task_del_by_all(server->schedule, 0,
3111 silc_server_close_connection_final, sock);
3112 silc_schedule_task_add_timeout(server->schedule,
3113 silc_server_close_connection_final,
3117 /* Sends disconnect message to remote connection and disconnects the
3120 void silc_server_disconnect_remote(SilcServer server,
3121 SilcPacketStream sock,
3122 SilcStatus status, ...)
3124 unsigned char buf[512];
3131 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3133 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_heartbeat,
3136 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p, status %d", sock,
3139 va_start(ap, status);
3140 cp = va_arg(ap, char *);
3142 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3145 /* Send SILC_PACKET_DISCONNECT */
3146 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3147 SILC_STR_UI_CHAR(status),
3148 SILC_STR_UI8_STRING(cp ? buf : NULL),
3151 /* Close connection */
3152 silc_server_close_connection(server, sock);
3155 /* Frees client data and notifies about client's signoff. */
3157 void silc_server_free_client_data(SilcServer server,
3158 SilcPacketStream sock,
3159 SilcClientEntry client,
3161 const char *signoff)
3163 SILC_LOG_DEBUG(("Freeing client %p data", client));
3166 /* Check if anyone is watching this nickname */
3167 if (server->server_type == SILC_ROUTER)
3168 silc_server_check_watcher_list(server, client, NULL,
3169 SILC_NOTIFY_TYPE_SIGNOFF);
3171 /* Send SIGNOFF notify to routers. */
3173 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3174 SILC_BROADCAST(server), client->id,
3178 /* Remove client from all channels */
3180 silc_server_remove_from_channels(server, NULL, client,
3181 TRUE, (char *)signoff, TRUE, FALSE);
3183 silc_server_remove_from_channels(server, NULL, client,
3184 FALSE, NULL, FALSE, FALSE);
3186 /* Remove this client from watcher list if it is */
3187 silc_server_del_from_watcher_list(server, client);
3189 /* Remove client's public key from repository, this will free it too. */
3190 if (client->data.public_key) {
3191 silc_skr_del_public_key(server->repository, client->data.public_key,
3193 client->data.public_key = NULL;
3196 /* Update statistics */
3198 /* Local detached clients aren't counted. */
3199 if (!client->local_detached)
3200 server->stat.my_clients--;
3201 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3202 server->stat.clients - 1));
3203 SILC_VERIFY(server->stat.clients > 0);
3204 server->stat.clients--;
3205 if (server->stat.cell_clients)
3206 server->stat.cell_clients--;
3207 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3208 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3209 silc_schedule_task_del_by_context(server->schedule, client);
3211 if (client->data.sconn) {
3212 silc_server_connection_free(client->data.sconn);
3213 client->data.sconn = NULL;
3216 /* We will not delete the client entry right away. We will take it
3217 into history (for WHOWAS command) for 5 minutes, unless we're
3218 shutting down server. */
3219 if (!server->server_shutdown) {
3220 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3222 client->router = NULL;
3223 client->connection = NULL;
3224 client->data.created = silc_time();
3225 silc_dlist_del(server->expired_clients, client);
3226 silc_dlist_add(server->expired_clients, client);
3228 /* Delete directly since we're shutting down server */
3229 SILC_LOG_DEBUG(("Delete client directly"));
3230 silc_idlist_del_data(client);
3231 silc_idlist_del_client(server->local_list, client);
3235 /* Frees user_data pointer from socket connection object. This also sends
3236 appropriate notify packets to the network to inform about leaving
3239 void silc_server_free_sock_user_data(SilcServer server,
3240 SilcPacketStream sock,
3241 const char *signoff_message)
3243 SilcIDListData idata;
3250 SILC_LOG_DEBUG(("Start, sock %p", sock));
3252 idata = silc_packet_get_context(sock);
3256 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3258 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_heartbeat,
3261 /* Cancel active protocols */
3263 if (idata->sconn && idata->sconn->op) {
3264 SILC_LOG_DEBUG(("Abort active protocol"));
3265 silc_async_abort(idata->sconn->op, NULL, NULL);
3266 idata->sconn->op = NULL;
3268 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3269 ((SilcUnknownEntry)idata)->op) {
3270 SILC_LOG_DEBUG(("Abort active protocol"));
3271 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3272 ((SilcUnknownEntry)idata)->op = NULL;
3276 switch (idata->conn_type) {
3277 case SILC_CONN_CLIENT:
3279 SilcClientEntry client_entry = (SilcClientEntry)idata;
3280 silc_server_free_client_data(server, sock, client_entry, TRUE,
3282 silc_packet_set_context(sock, NULL);
3286 case SILC_CONN_SERVER:
3287 case SILC_CONN_ROUTER:
3289 SilcServerEntry user_data = (SilcServerEntry)idata;
3290 SilcServerEntry backup_router = NULL;
3292 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3295 backup_router = silc_server_backup_get(server, user_data->id);
3297 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3298 backup_router == server->id_entry &&
3299 idata->conn_type != SILC_CONN_ROUTER)
3300 backup_router = NULL;
3302 if (server->server_shutdown || server->backup_noswitch)
3303 backup_router = NULL;
3305 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3306 NULL, NULL, &ip, &port);
3308 /* If this was our primary router connection then we're lost to
3309 the outside world. */
3310 if (server->router == user_data) {
3311 /* Check whether we have a backup router connection */
3312 if (!backup_router || backup_router == user_data) {
3313 if (!server->no_reconnect)
3314 silc_server_create_connections(server);
3315 server->id_entry->router = NULL;
3316 server->router = NULL;
3317 server->standalone = TRUE;
3318 server->backup_primary = FALSE;
3319 backup_router = NULL;
3321 if (server->id_entry != backup_router) {
3322 SILC_LOG_INFO(("New primary router is backup router %s",
3323 backup_router->server_name));
3324 server->id_entry->router = backup_router;
3325 server->router = backup_router;
3326 server->router_connect = time(0);
3327 server->backup_primary = TRUE;
3328 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3330 /* Send START_USE to backup router to indicate we have switched */
3331 silc_server_backup_send_start_use(server,
3332 backup_router->connection,
3335 SILC_LOG_INFO(("We are now new primary router in this cell"));
3336 server->id_entry->router = NULL;
3337 server->router = NULL;
3338 server->standalone = TRUE;
3341 /* We stop here to take a breath */
3344 if (server->backup_router) {
3345 server->server_type = SILC_ROUTER;
3347 /* We'll need to constantly try to reconnect to the primary
3348 router so that we'll see when it comes back online. */
3349 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3350 silc_server_backup_connected,
3354 /* Mark this connection as replaced */
3355 silc_server_backup_replaced_add(server, user_data->id,
3358 } else if (backup_router) {
3359 SILC_LOG_INFO(("Enabling the use of backup router %s",
3360 backup_router->server_name));
3362 /* Mark this connection as replaced */
3363 silc_server_backup_replaced_add(server, user_data->id,
3365 } else if (server->server_type == SILC_SERVER &&
3366 idata->conn_type == SILC_CONN_ROUTER) {
3367 /* Reconnect to the router (backup) */
3368 if (!server->no_reconnect)
3369 silc_server_create_connections(server);
3372 if (user_data->server_name)
3373 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3374 ("Server %s signoff", user_data->server_name));
3376 if (!backup_router) {
3377 /* Remove all servers that are originated from this server, and
3378 remove the clients of those servers too. */
3379 silc_server_remove_servers_by_server(server, user_data, TRUE);
3382 /* Remove the clients that this server owns as they will become
3383 invalid now too. For backup router the server is actually
3384 coming from the primary router, so mark that as the owner
3386 if (server->server_type == SILC_BACKUP_ROUTER &&
3387 sock->type == SILC_CONN_SERVER)
3388 silc_server_remove_clients_by_server(server, server->router,
3392 silc_server_remove_clients_by_server(server, user_data,
3395 /* Remove channels owned by this server */
3396 if (server->server_type == SILC_SERVER)
3397 silc_server_remove_channels_by_server(server, user_data);
3399 /* Enable local server connections that may be disabled */
3400 silc_server_local_servers_toggle_enabled(server, TRUE);
3402 /* Update the client entries of this server to the new backup
3403 router. If we are the backup router we also resolve the real
3404 servers for the clients. After updating is over this also
3405 removes the clients that this server explicitly owns. */
3406 silc_server_update_clients_by_server(server, user_data,
3407 backup_router, TRUE);
3409 /* If we are router and just lost our primary router (now standlaone)
3410 we remove everything that was behind it, since we don't know
3412 if (server->server_type == SILC_ROUTER && server->standalone)
3413 /* Remove all servers that are originated from this server, and
3414 remove the clients of those servers too. */
3415 silc_server_remove_servers_by_server(server, user_data, TRUE);
3417 /* Finally remove the clients that are explicitly owned by this
3418 server. They go down with the server. */
3419 silc_server_remove_clients_by_server(server, user_data,
3422 /* Update our server cache to use the new backup router too. */
3423 silc_server_update_servers_by_server(server, user_data, backup_router);
3424 if (server->server_type == SILC_SERVER)
3425 silc_server_update_channels_by_server(server, user_data,
3428 /* Send notify about primary router going down to local operators */
3429 if (server->backup_router)
3430 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3431 SILC_NOTIFY_TYPE_NONE,
3432 ("%s switched to backup router %s "
3433 "(we are primary router now)",
3434 server->server_name, server->server_name));
3435 else if (server->router)
3436 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3437 SILC_NOTIFY_TYPE_NONE,
3438 ("%s switched to backup router %s",
3439 server->server_name,
3440 server->router->server_name));
3442 server->backup_noswitch = FALSE;
3445 silc_server_connection_free(idata->sconn);
3446 idata->sconn = NULL;
3450 if (idata->conn_type == SILC_CONN_SERVER) {
3451 server->stat.my_servers--;
3452 server->stat.servers--;
3453 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3454 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3455 server->stat.my_routers--;
3456 server->stat.routers--;
3457 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3459 if (server->server_type == SILC_ROUTER)
3460 server->stat.cell_servers--;
3462 /* Free the server entry */
3463 silc_server_backup_del(server, user_data);
3464 silc_server_backup_replaced_del(server, user_data);
3465 silc_idlist_del_data(user_data);
3466 if (!silc_idlist_del_server(server->local_list, user_data))
3467 silc_idlist_del_server(server->global_list, user_data);
3469 if (backup_router && backup_router != server->id_entry) {
3470 /* Announce all of our stuff that was created about 5 minutes ago.
3471 The backup router knows all the other stuff already. */
3472 if (server->server_type == SILC_ROUTER)
3473 silc_server_announce_servers(server, FALSE, time(0) - 300,
3474 backup_router->connection);
3476 /* Announce our clients and channels to the router */
3477 silc_server_announce_clients(server, time(0) - 300,
3478 backup_router->connection);
3479 silc_server_announce_channels(server, time(0) - 300,
3480 backup_router->connection);
3483 silc_packet_set_context(sock, NULL);
3489 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3491 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3494 if (server->router_conn == idata->sconn) {
3495 if (!server->no_reconnect)
3496 silc_server_create_connections(server);
3497 server->router_conn = NULL;
3500 silc_server_connection_free(idata->sconn);
3501 idata->sconn = NULL;
3503 silc_idlist_del_data(idata);
3505 silc_packet_set_context(sock, NULL);
3511 /* Removes client from all channels it has joined. This is used when client
3512 connection is disconnected. If the client on a channel is last, the
3513 channel is removed as well. This sends the SIGNOFF notify types. */
3515 void silc_server_remove_from_channels(SilcServer server,
3516 SilcPacketStream sock,
3517 SilcClientEntry client,
3519 const char *signoff_message,
3523 SilcChannelEntry channel;
3524 SilcChannelClientEntry chl;
3525 SilcHashTableList htl;
3526 SilcBuffer clidp = NULL;
3531 if (notify && !client->id)
3534 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3535 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3538 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3543 /* Remove the client from all channels. The client is removed from
3544 the channels' user list. */
3545 silc_hash_table_list(client->channels, &htl);
3546 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3547 channel = chl->channel;
3549 /* Remove channel if this is last client leaving the channel, unless
3550 the channel is permanent. */
3551 if (server->server_type != SILC_SERVER &&
3552 silc_hash_table_count(channel->user_list) < 2) {
3553 silc_server_channel_delete(server, channel);
3557 silc_hash_table_del(client->channels, channel);
3558 silc_hash_table_del(channel->user_list, client);
3559 channel->user_count--;
3561 /* If there is no global users on the channel anymore mark the channel
3562 as local channel. Do not check if the removed client is local client. */
3563 if (server->server_type == SILC_SERVER && channel->global_users &&
3564 chl->client->router && !silc_server_channel_has_global(channel))
3565 channel->global_users = FALSE;
3567 memset(chl, 'A', sizeof(*chl));
3570 /* Update statistics */
3571 if (SILC_IS_LOCAL(client))
3572 server->stat.my_chanclients--;
3573 if (server->server_type == SILC_ROUTER) {
3574 server->stat.cell_chanclients--;
3575 server->stat.chanclients--;
3578 /* If there is not at least one local user on the channel then we don't
3579 need the channel entry anymore, we can remove it safely, unless the
3580 channel is permanent channel */
3581 if (server->server_type == SILC_SERVER &&
3582 !silc_server_channel_has_local(channel)) {
3583 /* Notify about leaving client if this channel has global users. */
3584 if (notify && channel->global_users)
3585 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3586 SILC_NOTIFY_TYPE_SIGNOFF,
3587 signoff_message ? 2 : 1,
3588 clidp->data, silc_buffer_len(clidp),
3589 signoff_message, signoff_message ?
3590 strlen(signoff_message) : 0);
3592 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3593 silc_server_channel_delete(server, channel);
3597 /* Send notify to channel about client leaving SILC and channel too */
3599 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3600 SILC_NOTIFY_TYPE_SIGNOFF,
3601 signoff_message ? 2 : 1,
3602 clidp->data, silc_buffer_len(clidp),
3603 signoff_message, signoff_message ?
3604 strlen(signoff_message) : 0);
3606 if (killed && clidp) {
3607 /* Remove the client from channel's invite list */
3608 if (channel->invite_list &&
3609 silc_hash_table_count(channel->invite_list)) {
3611 SilcArgumentPayload iargs;
3612 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3613 silc_buffer_len(clidp), 3);
3614 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3615 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3616 silc_buffer_free(ab);
3617 silc_argument_payload_free(iargs);
3621 /* Don't create keys if we are shutting down */
3622 if (server->server_shutdown)
3625 /* Re-generate channel key if needed */
3626 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3627 if (!silc_server_create_channel_key(server, channel, 0))
3630 /* Send the channel key to the channel. The key of course is not sent
3631 to the client who was removed from the channel. */
3632 silc_server_send_channel_key(server, client->connection, channel,
3633 server->server_type == SILC_ROUTER ?
3634 FALSE : !server->standalone);
3638 silc_hash_table_list_reset(&htl);
3640 silc_buffer_free(clidp);
3643 /* Removes client from one channel. This is used for example when client
3644 calls LEAVE command to remove itself from the channel. Returns TRUE
3645 if channel still exists and FALSE if the channel is removed when
3646 last client leaves the channel. If `notify' is FALSE notify messages
3649 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3650 SilcPacketStream sock,
3651 SilcChannelEntry channel,
3652 SilcClientEntry client,
3655 SilcChannelClientEntry chl;
3658 SILC_LOG_DEBUG(("Removing %s from channel %s",
3659 silc_id_render(client->id, SILC_ID_CLIENT),
3660 channel->channel_name));
3662 /* Get the entry to the channel, if this client is not on the channel
3664 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3667 /* Remove channel if this is last client leaving the channel, unless
3668 the channel is permanent. */
3669 if (server->server_type != SILC_SERVER &&
3670 silc_hash_table_count(channel->user_list) < 2) {
3671 silc_server_channel_delete(server, channel);
3675 silc_hash_table_del(client->channels, channel);
3676 silc_hash_table_del(channel->user_list, client);
3677 channel->user_count--;
3679 /* If there is no global users on the channel anymore mark the channel
3680 as local channel. Do not check if the client is local client. */
3681 if (server->server_type == SILC_SERVER && channel->global_users &&
3682 chl->client->router && !silc_server_channel_has_global(channel))
3683 channel->global_users = FALSE;
3685 memset(chl, 'O', sizeof(*chl));
3688 /* Update statistics */
3689 if (SILC_IS_LOCAL(client))
3690 server->stat.my_chanclients--;
3691 if (server->server_type == SILC_ROUTER) {
3692 server->stat.cell_chanclients--;
3693 server->stat.chanclients--;
3696 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3700 /* If there is not at least one local user on the channel then we don't
3701 need the channel entry anymore, we can remove it safely, unless the
3702 channel is permanent channel */
3703 if (server->server_type == SILC_SERVER &&
3704 !silc_server_channel_has_local(channel)) {
3705 /* Notify about leaving client if this channel has global users. */
3706 if (notify && channel->global_users)
3707 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3708 SILC_NOTIFY_TYPE_LEAVE, 1,
3709 clidp->data, silc_buffer_len(clidp));
3711 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3712 silc_server_channel_delete(server, channel);
3713 silc_buffer_free(clidp);
3717 /* Send notify to channel about client leaving the channel */
3719 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3720 SILC_NOTIFY_TYPE_LEAVE, 1,
3721 clidp->data, silc_buffer_len(clidp));
3723 silc_buffer_free(clidp);
3727 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3728 function may be used only by router. In real SILC network all channels
3729 are created by routers thus this function is never used by normal
3732 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3733 SilcServerID *router_id,
3739 SilcChannelID *channel_id;
3740 SilcChannelEntry entry;
3741 SilcCipher send_key, receive_key;
3744 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3747 cipher = SILC_DEFAULT_CIPHER;
3749 hmac = SILC_DEFAULT_HMAC;
3751 /* Allocate cipher */
3752 if (!silc_cipher_alloc(cipher, &send_key))
3754 if (!silc_cipher_alloc(cipher, &receive_key)) {
3755 silc_cipher_free(send_key);
3760 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3761 silc_cipher_free(send_key);
3762 silc_cipher_free(receive_key);
3766 channel_name = strdup(channel_name);
3768 /* Create the channel ID */
3769 if (!silc_id_create_channel_id(server, router_id, server->rng,
3771 silc_free(channel_name);
3772 silc_cipher_free(send_key);
3773 silc_cipher_free(receive_key);
3774 silc_hmac_free(newhmac);
3778 /* Create the channel */
3779 entry = silc_idlist_add_channel(server->local_list, channel_name,
3780 SILC_CHANNEL_MODE_NONE, channel_id,
3781 NULL, send_key, receive_key, newhmac);
3783 silc_free(channel_name);
3784 silc_cipher_free(send_key);
3785 silc_cipher_free(receive_key);
3786 silc_hmac_free(newhmac);
3787 silc_free(channel_id);
3791 entry->cipher = strdup(cipher);
3792 entry->hmac_name = strdup(hmac);
3794 /* Now create the actual key material */
3795 if (!silc_server_create_channel_key(server, entry,
3796 silc_cipher_get_key_len(send_key) / 8)) {
3797 silc_idlist_del_channel(server->local_list, entry);
3801 /* Notify other routers about the new channel. We send the packet
3802 to our primary route. */
3804 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3805 channel_name, entry->id,
3806 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3809 /* Distribute to backup routers */
3810 if (broadcast && server->server_type == SILC_ROUTER) {
3812 unsigned char cid[32];
3813 SilcUInt32 name_len = strlen(channel_name);
3816 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3817 packet = silc_channel_payload_encode(channel_name, name_len,
3818 cid, id_len, entry->mode);
3819 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3820 packet->data, silc_buffer_len(packet), FALSE,
3822 silc_buffer_free(packet);
3825 server->stat.my_channels++;
3826 if (server->server_type == SILC_ROUTER) {
3827 server->stat.channels++;
3828 server->stat.cell_channels++;
3829 entry->users_resolved = TRUE;
3835 /* Same as above but creates the channel with Channel ID `channel_id. */
3838 silc_server_create_new_channel_with_id(SilcServer server,
3842 SilcChannelID *channel_id,
3845 SilcChannelEntry entry;
3846 SilcCipher send_key, receive_key;
3849 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3852 cipher = SILC_DEFAULT_CIPHER;
3854 hmac = SILC_DEFAULT_HMAC;
3856 /* Allocate cipher */
3857 if (!silc_cipher_alloc(cipher, &send_key))
3859 if (!silc_cipher_alloc(cipher, &receive_key)) {
3860 silc_cipher_free(send_key);
3865 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3866 silc_cipher_free(send_key);
3867 silc_cipher_free(receive_key);
3871 channel_name = strdup(channel_name);
3873 /* Create the channel */
3874 entry = silc_idlist_add_channel(server->local_list, channel_name,
3875 SILC_CHANNEL_MODE_NONE, channel_id,
3876 NULL, send_key, receive_key, newhmac);
3878 silc_cipher_free(send_key);
3879 silc_cipher_free(receive_key);
3880 silc_hmac_free(newhmac);
3881 silc_free(channel_name);
3885 /* Now create the actual key material */
3886 if (!silc_server_create_channel_key(server, entry,
3887 silc_cipher_get_key_len(send_key) / 8)) {
3888 silc_idlist_del_channel(server->local_list, entry);
3892 /* Notify other routers about the new channel. We send the packet
3893 to our primary route. */
3895 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3896 channel_name, entry->id,
3897 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3900 /* Distribute to backup routers */
3901 if (broadcast && server->server_type == SILC_ROUTER) {
3903 unsigned char cid[32];
3904 SilcUInt32 name_len = strlen(channel_name);
3907 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3908 packet = silc_channel_payload_encode(channel_name, name_len,
3909 cid, id_len, entry->mode);
3910 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3911 packet->data, silc_buffer_len(packet), FALSE,
3913 silc_buffer_free(packet);
3916 server->stat.my_channels++;
3917 if (server->server_type == SILC_ROUTER) {
3918 server->stat.channels++;
3919 server->stat.cell_channels++;
3920 entry->users_resolved = TRUE;
3926 /* Channel's key re-key timeout callback. */
3928 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3930 SilcServer server = app_context;
3931 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3935 /* Return now if we are shutting down */
3936 if (server->server_shutdown)
3939 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3942 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3945 /* Generates new channel key. This is used to create the initial channel key
3946 but also to re-generate new key for channel. If `key_len' is provided
3947 it is the bytes of the key length. */
3949 SilcBool silc_server_create_channel_key(SilcServer server,
3950 SilcChannelEntry channel,
3954 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3957 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3958 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3962 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3964 if (!channel->send_key)
3965 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3966 channel->send_key = NULL;
3969 if (!channel->receive_key)
3970 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3971 silc_cipher_free(channel->send_key);
3972 channel->send_key = channel->receive_key = NULL;
3978 else if (channel->key_len)
3979 len = channel->key_len / 8;
3981 len = silc_cipher_get_key_len(channel->send_key) / 8;
3983 /* Create channel key */
3984 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3987 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3988 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3990 /* Remove old key if exists */
3992 memset(channel->key, 0, channel->key_len / 8);
3993 silc_free(channel->key);
3997 channel->key_len = len * 8;
3998 channel->key = silc_memdup(channel_key, len);
3999 memset(channel_key, 0, sizeof(channel_key));
4001 /* Generate HMAC key from the channel key data and set it */
4003 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4004 memset(channel->key, 0, channel->key_len / 8);
4005 silc_free(channel->key);
4006 silc_cipher_free(channel->send_key);
4007 silc_cipher_free(channel->receive_key);
4008 channel->send_key = channel->receive_key = NULL;
4011 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
4012 silc_hmac_set_key(channel->hmac, hash,
4013 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4014 memset(hash, 0, sizeof(hash));
4016 if (server->server_type == SILC_ROUTER) {
4017 if (!channel->rekey)
4018 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4019 channel->rekey->channel = channel;
4020 channel->rekey->key_len = key_len;
4021 if (channel->rekey->task)
4022 silc_schedule_task_del(server->schedule, channel->rekey->task);
4024 channel->rekey->task =
4025 silc_schedule_task_add_timeout(server->schedule,
4026 silc_server_channel_key_rekey,
4027 (void *)channel->rekey,
4028 server->config->channel_rekey_secs, 0);
4034 /* Saves the channel key found in the encoded `key_payload' buffer. This
4035 function is used when we receive Channel Key Payload and also when we're
4036 processing JOIN command reply. Returns entry to the channel. */
4038 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4039 SilcBuffer key_payload,
4040 SilcChannelEntry channel)
4042 SilcChannelKeyPayload payload = NULL;
4044 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4048 /* Decode channel key payload */
4049 payload = silc_channel_key_payload_parse(key_payload->data,
4050 silc_buffer_len(key_payload));
4052 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4057 /* Get the channel entry */
4060 /* Get channel ID */
4061 tmp = silc_channel_key_get_id(payload, &tmp_len);
4062 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4067 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4069 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4071 if (server->server_type == SILC_ROUTER)
4072 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4073 silc_id_render(&id, SILC_ID_CHANNEL)));
4079 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4081 tmp = silc_channel_key_get_key(payload, &tmp_len);
4087 cipher = silc_channel_key_get_cipher(payload, NULL);
4093 /* Remove old key if exists */
4095 memset(channel->key, 0, channel->key_len / 8);
4096 silc_free(channel->key);
4097 silc_cipher_free(channel->send_key);
4098 silc_cipher_free(channel->receive_key);
4101 /* Create new cipher */
4102 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4103 channel->send_key = NULL;
4107 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4108 silc_cipher_free(channel->send_key);
4109 channel->send_key = channel->receive_key = NULL;
4114 if (channel->cipher)
4115 silc_free(channel->cipher);
4116 channel->cipher = strdup(cipher);
4119 channel->key_len = tmp_len * 8;
4120 channel->key = silc_memdup(tmp, tmp_len);
4121 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4122 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4124 /* Generate HMAC key from the channel key data and set it */
4126 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4127 memset(channel->key, 0, channel->key_len / 8);
4128 silc_free(channel->key);
4129 silc_cipher_free(channel->send_key);
4130 silc_cipher_free(channel->receive_key);
4131 channel->send_key = channel->receive_key = NULL;
4134 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4135 silc_hmac_set_key(channel->hmac, hash,
4136 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4138 memset(hash, 0, sizeof(hash));
4139 memset(tmp, 0, tmp_len);
4141 if (server->server_type == SILC_ROUTER) {
4142 if (!channel->rekey)
4143 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4144 channel->rekey->channel = channel;
4145 if (channel->rekey->task)
4146 silc_schedule_task_del(server->schedule, channel->rekey->task);
4148 channel->rekey->task =
4149 silc_schedule_task_add_timeout(server->schedule,
4150 silc_server_channel_key_rekey,
4151 (void *)channel->rekey,
4152 server->config->channel_rekey_secs, 0);
4157 silc_channel_key_payload_free(payload);
4162 /* Returns assembled of all servers in the given ID list. The packet's
4163 form is dictated by the New ID payload. */
4165 static void silc_server_announce_get_servers(SilcServer server,
4166 SilcServerEntry remote,
4168 SilcBuffer *servers,
4169 unsigned long creation_time)
4172 SilcIDCacheEntry id_cache;
4173 SilcServerEntry entry;
4177 /* Go through all clients in the list */
4178 if (silc_idcache_get_all(id_list->servers, &list)) {
4179 silc_list_start(list);
4180 while ((id_cache = silc_list_get(list))) {
4181 entry = (SilcServerEntry)id_cache->context;
4183 /* Do not announce the one we've sending our announcements and
4184 do not announce ourself. Also check the creation time if it's
4186 if ((entry == remote) || (entry == server->id_entry) ||
4187 (creation_time && entry->data.created < creation_time))
4190 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4192 tmp = silc_buffer_realloc(*servers,
4194 silc_buffer_truelen((*servers)) +
4195 silc_buffer_len(idp) :
4196 silc_buffer_len(idp)));
4200 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4201 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4202 silc_buffer_pull(*servers, silc_buffer_len(idp));
4203 silc_buffer_free(idp);
4209 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4215 p = silc_notify_payload_encode(notify, argc, ap);
4221 /* This function is used by router to announce existing servers to our
4222 primary router when we've connected to it. If `creation_time' is non-zero
4223 then only the servers that has been created after the `creation_time'
4224 will be announced. */
4226 void silc_server_announce_servers(SilcServer server, SilcBool global,
4227 unsigned long creation_time,
4228 SilcPacketStream remote)
4230 SilcBuffer servers = NULL;
4232 SILC_LOG_DEBUG(("Announcing servers"));
4234 /* Get servers in local list */
4235 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4236 server->local_list, &servers,
4240 /* Get servers in global list */
4241 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4242 server->global_list, &servers,
4246 silc_buffer_push(servers, servers->data - servers->head);
4247 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4249 /* Send the packet */
4250 silc_server_packet_send(server, remote,
4251 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4252 servers->data, silc_buffer_len(servers));
4254 silc_buffer_free(servers);
4258 /* Returns assembled packet of all clients in the given ID list. The
4259 packet's form is dictated by the New ID Payload. */
4261 static void silc_server_announce_get_clients(SilcServer server,
4263 SilcBuffer *clients,
4265 unsigned long creation_time)
4268 SilcIDCacheEntry id_cache;
4269 SilcClientEntry client;
4272 unsigned char mode[4];
4275 /* Go through all clients in the list */
4276 if (silc_idcache_get_all(id_list->clients, &list)) {
4277 silc_list_start(list);
4278 while ((id_cache = silc_list_get(list))) {
4279 client = (SilcClientEntry)id_cache->context;
4281 if (creation_time && client->data.created < creation_time)
4283 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4285 if (!client->connection && !client->router)
4288 SILC_LOG_DEBUG(("Announce Client ID %s",
4289 silc_id_render(client->id, SILC_ID_CLIENT)));
4291 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4295 tmp2 = silc_buffer_realloc(*clients,
4297 silc_buffer_truelen((*clients)) +
4298 silc_buffer_len(idp) :
4299 silc_buffer_len(idp)));
4303 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4304 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4305 silc_buffer_pull(*clients, silc_buffer_len(idp));
4307 SILC_PUT32_MSB(client->mode, mode);
4309 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4310 2, idp->data, silc_buffer_len(idp),
4312 tmp2 = silc_buffer_realloc(*umodes,
4314 silc_buffer_truelen((*umodes)) +
4315 silc_buffer_len(tmp) :
4316 silc_buffer_len(tmp)));
4320 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4321 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4322 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4323 silc_buffer_free(tmp);
4325 silc_buffer_free(idp);
4330 /* This function is used to announce our existing clients to our router
4331 when we've connected to it. If `creation_time' is non-zero then only
4332 the clients that has been created after the `creation_time' will be
4335 void silc_server_announce_clients(SilcServer server,
4336 unsigned long creation_time,
4337 SilcPacketStream remote)
4339 SilcBuffer clients = NULL;
4340 SilcBuffer umodes = NULL;
4342 SILC_LOG_DEBUG(("Announcing clients"));
4344 /* Get clients in local list */
4345 silc_server_announce_get_clients(server, server->local_list,
4346 &clients, &umodes, creation_time);
4348 /* As router we announce our global list as well */
4349 if (server->server_type == SILC_ROUTER)
4350 silc_server_announce_get_clients(server, server->global_list,
4351 &clients, &umodes, creation_time);
4354 silc_buffer_push(clients, clients->data - clients->head);
4355 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4357 /* Send the packet */
4358 silc_server_packet_send(server, remote,
4359 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4360 clients->data, silc_buffer_len(clients));
4362 silc_buffer_free(clients);
4366 silc_buffer_push(umodes, umodes->data - umodes->head);
4367 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4369 /* Send the packet */
4370 silc_server_packet_send(server, remote,
4371 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4372 umodes->data, silc_buffer_len(umodes));
4374 silc_buffer_free(umodes);
4378 /* Returns channel's topic for announcing it */
4380 void silc_server_announce_get_channel_topic(SilcServer server,
4381 SilcChannelEntry channel,
4386 if (channel->topic) {
4387 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4388 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4390 silc_buffer_len(chidp),
4392 strlen(channel->topic));
4393 silc_buffer_free(chidp);
4397 /* Returns channel's invite and ban lists */
4399 void silc_server_announce_get_inviteban(SilcServer server,
4400 SilcChannelEntry channel,
4404 SilcBuffer list, idp, idp2, tmp2;
4407 SilcHashTableList htl;
4408 const unsigned char a[1] = { 0x03 };
4410 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4412 /* Encode invite list */
4413 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4414 list = silc_buffer_alloc_size(2);
4415 type = silc_hash_table_count(channel->invite_list);
4416 SILC_PUT16_MSB(type, list->data);
4417 silc_hash_table_list(channel->invite_list, &htl);
4418 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4419 list = silc_argument_payload_encode_one(list, tmp2->data,
4420 silc_buffer_len(tmp2),
4421 SILC_PTR_TO_32(ptype));
4422 silc_hash_table_list_reset(&htl);
4424 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4426 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4427 idp->data, silc_buffer_len(idp),
4428 channel->channel_name,
4429 strlen(channel->channel_name),
4430 idp2->data, silc_buffer_len(idp2),
4432 list->data, silc_buffer_len(list));
4433 silc_buffer_free(idp2);
4434 silc_buffer_free(list);
4437 /* Encode ban list */
4438 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4439 list = silc_buffer_alloc_size(2);
4440 type = silc_hash_table_count(channel->ban_list);
4441 SILC_PUT16_MSB(type, list->data);
4442 silc_hash_table_list(channel->ban_list, &htl);
4443 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4444 list = silc_argument_payload_encode_one(list, tmp2->data,
4445 silc_buffer_len(tmp2),
4446 SILC_PTR_TO_32(ptype));
4447 silc_hash_table_list_reset(&htl);
4450 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4451 idp->data, silc_buffer_len(idp),
4453 list->data, silc_buffer_len(list));
4454 silc_buffer_free(list);
4457 silc_buffer_free(idp);
4460 /* Returns assembled packets for channel users of the `channel'. */
4462 void silc_server_announce_get_channel_users(SilcServer server,
4463 SilcChannelEntry channel,
4464 SilcBuffer *channel_modes,
4465 SilcBuffer *channel_users,
4466 SilcBuffer *channel_users_modes)
4468 SilcChannelClientEntry chl;
4469 SilcHashTableList htl;
4470 SilcBuffer chidp, clidp, csidp;
4471 SilcBuffer tmp, fkey = NULL, chpklist;
4473 unsigned char mode[4], ulimit[4];
4477 SILC_LOG_DEBUG(("Start"));
4479 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4480 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4481 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4484 SILC_PUT32_MSB(channel->mode, mode);
4485 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4486 SILC_PUT32_MSB(channel->user_limit, ulimit);
4487 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4488 if (channel->founder_key)
4489 fkey = silc_public_key_payload_encode(channel->founder_key);
4491 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4493 silc_buffer_len(csidp),
4496 hmac, hmac ? strlen(hmac) : 0,
4497 channel->passphrase,
4498 channel->passphrase ?
4499 strlen(channel->passphrase) : 0,
4500 fkey ? fkey->data : NULL,
4501 fkey ? silc_buffer_len(fkey) : 0,
4502 chpklist ? chpklist->data : NULL,
4504 silc_buffer_len(chpklist) : 0,
4506 SILC_CHANNEL_MODE_ULIMIT ?
4509 SILC_CHANNEL_MODE_ULIMIT ?
4510 sizeof(ulimit) : 0));
4511 len = silc_buffer_len(tmp);
4513 silc_buffer_realloc(*channel_modes,
4515 silc_buffer_truelen((*channel_modes)) + len : len));
4518 *channel_modes = tmp2;
4519 silc_buffer_pull_tail(*channel_modes,
4520 ((*channel_modes)->end -
4521 (*channel_modes)->data));
4522 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4523 silc_buffer_pull(*channel_modes, len);
4524 silc_buffer_free(tmp);
4525 silc_buffer_free(fkey);
4528 /* Now find all users on the channel */
4529 silc_hash_table_list(channel->user_list, &htl);
4530 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4531 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4533 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4537 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4539 silc_buffer_len(clidp),
4541 silc_buffer_len(chidp));
4542 len = silc_buffer_len(tmp);
4544 silc_buffer_realloc(*channel_users,
4546 silc_buffer_truelen((*channel_users)) + len : len));
4549 *channel_users = tmp2;
4550 silc_buffer_pull_tail(*channel_users,
4551 ((*channel_users)->end -
4552 (*channel_users)->data));
4554 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4555 silc_buffer_pull(*channel_users, len);
4556 silc_buffer_free(tmp);
4558 /* CUMODE notify for mode change on the channel */
4559 SILC_PUT32_MSB(chl->mode, mode);
4560 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4561 fkey = silc_public_key_payload_encode(channel->founder_key);
4562 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4564 silc_buffer_len(csidp),
4567 silc_buffer_len(clidp),
4568 fkey ? fkey->data : NULL,
4569 fkey ? silc_buffer_len(fkey) : 0);
4570 len = silc_buffer_len(tmp);
4572 silc_buffer_realloc(*channel_users_modes,
4573 (*channel_users_modes ?
4574 silc_buffer_truelen((*channel_users_modes)) +
4578 *channel_users_modes = tmp2;
4579 silc_buffer_pull_tail(*channel_users_modes,
4580 ((*channel_users_modes)->end -
4581 (*channel_users_modes)->data));
4583 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4584 silc_buffer_pull(*channel_users_modes, len);
4585 silc_buffer_free(tmp);
4586 silc_buffer_free(fkey);
4588 silc_buffer_free(clidp);
4590 silc_hash_table_list_reset(&htl);
4591 silc_buffer_free(chidp);
4592 silc_buffer_free(csidp);
4595 /* Returns assembled packets for all channels and users on those channels
4596 from the given ID List. The packets are in the form dictated by the
4597 New Channel and New Channel User payloads. */
4599 void silc_server_announce_get_channels(SilcServer server,
4601 SilcBuffer *channels,
4602 SilcBuffer **channel_modes,
4603 SilcBuffer *channel_users,
4604 SilcBuffer **channel_users_modes,
4605 SilcUInt32 *channel_users_modes_c,
4606 SilcBuffer **channel_topics,
4607 SilcBuffer **channel_invites,
4608 SilcBuffer **channel_bans,
4609 SilcChannelID ***channel_ids,
4610 unsigned long creation_time)
4613 SilcIDCacheEntry id_cache;
4614 SilcChannelEntry channel;
4615 unsigned char cid[32];
4617 SilcUInt16 name_len;
4619 int i = *channel_users_modes_c;
4623 SILC_LOG_DEBUG(("Start"));
4625 /* Go through all channels in the list */
4626 if (silc_idcache_get_all(id_list->channels, &list)) {
4627 silc_list_start(list);
4628 while ((id_cache = silc_list_get(list))) {
4629 channel = (SilcChannelEntry)id_cache->context;
4631 if (creation_time && channel->created < creation_time)
4636 SILC_LOG_DEBUG(("Announce Channel ID %s",
4637 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4639 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4640 name_len = strlen(channel->channel_name);
4643 len = 4 + name_len + id_len + 4;
4645 silc_buffer_realloc(*channels,
4647 silc_buffer_truelen((*channels)) +
4653 silc_buffer_pull_tail(*channels,
4654 ((*channels)->end - (*channels)->data));
4655 silc_buffer_format(*channels,
4656 SILC_STR_UI_SHORT(name_len),
4657 SILC_STR_UI_XNSTRING(channel->channel_name,
4659 SILC_STR_UI_SHORT(id_len),
4660 SILC_STR_UI_XNSTRING(cid, id_len),
4661 SILC_STR_UI_INT(channel->mode),
4663 silc_buffer_pull(*channels, len);
4666 if (creation_time && channel->updated < creation_time)
4672 /* Channel user modes */
4673 tmp = silc_realloc(*channel_users_modes,
4674 sizeof(**channel_users_modes) * (i + 1));
4677 *channel_users_modes = tmp;
4678 (*channel_users_modes)[i] = NULL;
4679 tmp = silc_realloc(*channel_modes,
4680 sizeof(**channel_modes) * (i + 1));
4683 *channel_modes = tmp;
4684 (*channel_modes)[i] = NULL;
4685 tmp = silc_realloc(*channel_ids,
4686 sizeof(**channel_ids) * (i + 1));
4690 (*channel_ids)[i] = NULL;
4691 silc_server_announce_get_channel_users(server, channel,
4692 &(*channel_modes)[i],
4694 &(*channel_users_modes)[i]);
4695 (*channel_ids)[i] = channel->id;
4697 /* Channel's topic */
4698 tmp = silc_realloc(*channel_topics,
4699 sizeof(**channel_topics) * (i + 1));
4702 *channel_topics = tmp;
4703 (*channel_topics)[i] = NULL;
4704 silc_server_announce_get_channel_topic(server, channel,
4705 &(*channel_topics)[i]);
4707 /* Channel's invite and ban list */
4708 tmp = silc_realloc(*channel_invites,
4709 sizeof(**channel_invites) * (i + 1));
4712 *channel_invites = tmp;
4713 (*channel_invites)[i] = NULL;
4714 tmp = silc_realloc(*channel_bans,
4715 sizeof(**channel_bans) * (i + 1));
4718 *channel_bans = tmp;
4719 (*channel_bans)[i] = NULL;
4720 silc_server_announce_get_inviteban(server, channel,
4721 &(*channel_invites)[i],
4722 &(*channel_bans)[i]);
4724 (*channel_users_modes_c)++;
4732 /* This function is used to announce our existing channels to our router
4733 when we've connected to it. This also announces the users on the
4734 channels to the router. If the `creation_time' is non-zero only the
4735 channels that was created after the `creation_time' are announced.
4736 Note that the channel users are still announced even if the `creation_time'
4739 void silc_server_announce_channels(SilcServer server,
4740 unsigned long creation_time,
4741 SilcPacketStream remote)
4743 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4744 SilcBuffer *channel_users_modes = NULL;
4745 SilcBuffer *channel_topics = NULL;
4746 SilcBuffer *channel_invites = NULL;
4747 SilcBuffer *channel_bans = NULL;
4748 SilcUInt32 channel_users_modes_c = 0;
4749 SilcChannelID **channel_ids = NULL;
4751 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4753 /* Get channels and channel users in local list */
4754 silc_server_announce_get_channels(server, server->local_list,
4755 &channels, &channel_modes,
4757 &channel_users_modes,
4758 &channel_users_modes_c,
4762 &channel_ids, creation_time);
4764 /* Get channels and channel users in global list */
4765 if (server->server_type != SILC_SERVER)
4766 silc_server_announce_get_channels(server, server->global_list,
4767 &channels, &channel_modes,
4769 &channel_users_modes,
4770 &channel_users_modes_c,
4774 &channel_ids, creation_time);
4777 silc_buffer_push(channels, channels->data - channels->head);
4778 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4780 /* Send the packet */
4781 silc_server_packet_send(server, remote,
4782 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4783 channels->data, silc_buffer_len(channels));
4785 silc_buffer_free(channels);
4788 if (channel_users) {
4789 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4790 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4791 silc_buffer_len(channel_users));
4793 /* Send the packet */
4794 silc_server_packet_send(server, remote,
4795 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4796 channel_users->data, silc_buffer_len(channel_users));
4798 silc_buffer_free(channel_users);
4801 if (channel_modes) {
4804 for (i = 0; i < channel_users_modes_c; i++) {
4805 if (!channel_modes[i])
4807 silc_buffer_push(channel_modes[i],
4808 channel_modes[i]->data -
4809 channel_modes[i]->head);
4810 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4811 silc_buffer_len(channel_modes[i]));
4812 silc_server_packet_send_dest(server, remote,
4813 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4814 channel_ids[i], SILC_ID_CHANNEL,
4815 channel_modes[i]->data,
4816 silc_buffer_len(channel_modes[i]));
4817 silc_buffer_free(channel_modes[i]);
4819 silc_free(channel_modes);
4822 if (channel_users_modes) {
4825 for (i = 0; i < channel_users_modes_c; i++) {
4826 if (!channel_users_modes[i])
4828 silc_buffer_push(channel_users_modes[i],
4829 channel_users_modes[i]->data -
4830 channel_users_modes[i]->head);
4831 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4832 silc_buffer_len(channel_users_modes[i]));
4833 silc_server_packet_send_dest(server, remote,
4834 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4835 channel_ids[i], SILC_ID_CHANNEL,
4836 channel_users_modes[i]->data,
4837 silc_buffer_len(channel_users_modes[i]));
4838 silc_buffer_free(channel_users_modes[i]);
4840 silc_free(channel_users_modes);
4843 if (channel_topics) {
4846 for (i = 0; i < channel_users_modes_c; i++) {
4847 if (!channel_topics[i])
4850 silc_buffer_push(channel_topics[i],
4851 channel_topics[i]->data -
4852 channel_topics[i]->head);
4853 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4854 silc_buffer_len(channel_topics[i]));
4855 silc_server_packet_send_dest(server, remote,
4856 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4857 channel_ids[i], SILC_ID_CHANNEL,
4858 channel_topics[i]->data,
4859 silc_buffer_len(channel_topics[i]));
4860 silc_buffer_free(channel_topics[i]);
4862 silc_free(channel_topics);
4865 if (channel_invites) {
4868 for (i = 0; i < channel_users_modes_c; i++) {
4869 if (!channel_invites[i])
4872 silc_buffer_push(channel_invites[i],
4873 channel_invites[i]->data -
4874 channel_invites[i]->head);
4875 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4876 silc_buffer_len(channel_invites[i]));
4877 silc_server_packet_send_dest(server, remote,
4878 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4879 channel_ids[i], SILC_ID_CHANNEL,
4880 channel_invites[i]->data,
4881 silc_buffer_len(channel_invites[i]));
4882 silc_buffer_free(channel_invites[i]);
4884 silc_free(channel_invites);
4890 for (i = 0; i < channel_users_modes_c; i++) {
4891 if (!channel_bans[i])
4894 silc_buffer_push(channel_bans[i],
4895 channel_bans[i]->data -
4896 channel_bans[i]->head);
4897 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4898 silc_buffer_len(channel_bans[i]));
4899 silc_server_packet_send_dest(server, remote,
4900 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4901 channel_ids[i], SILC_ID_CHANNEL,
4902 channel_bans[i]->data,
4903 silc_buffer_len(channel_bans[i]));
4904 silc_buffer_free(channel_bans[i]);
4906 silc_free(channel_bans);
4909 silc_free(channel_ids);
4912 /* Announces WATCH list. */
4914 void silc_server_announce_watches(SilcServer server,
4915 SilcPacketStream remote)
4917 SilcHashTableList htl;
4918 SilcBuffer buffer, idp, args, pkp;
4919 SilcClientEntry client;
4922 SILC_LOG_DEBUG(("Announcing watch list"));
4924 /* XXX because way we save the nicks (hash) we cannot announce them. */
4926 /* XXX we should send all public keys in one command if client is
4927 watching more than one key */
4928 silc_hash_table_list(server->watcher_list_pk, &htl);
4929 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4930 if (!client || !client->id)
4933 server->stat.commands_sent++;
4935 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4936 args = silc_buffer_alloc_size(2);
4937 silc_buffer_format(args,
4938 SILC_STR_UI_SHORT(1),
4940 pkp = silc_public_key_payload_encode(key);
4941 args = silc_argument_payload_encode_one(args, pkp->data,
4942 silc_buffer_len(pkp), 0x00);
4943 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4944 ++server->cmd_ident, 2,
4945 1, idp->data, silc_buffer_len(idp),
4947 silc_buffer_len(args));
4950 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4951 buffer->data, silc_buffer_len(buffer));
4953 silc_buffer_free(pkp);
4954 silc_buffer_free(args);
4955 silc_buffer_free(idp);
4956 silc_buffer_free(buffer);
4958 silc_hash_table_list_reset(&htl);
4961 /* Assembles user list and users mode list from the `channel'. */
4963 SilcBool silc_server_get_users_on_channel(SilcServer server,
4964 SilcChannelEntry channel,
4965 SilcBuffer *user_list,
4966 SilcBuffer *mode_list,
4967 SilcUInt32 *user_count)
4969 SilcChannelClientEntry chl;
4970 SilcHashTableList htl;
4971 SilcBuffer client_id_list;
4972 SilcBuffer client_mode_list;
4974 SilcUInt32 list_count = 0, len = 0;
4976 if (!silc_hash_table_count(channel->user_list))
4979 silc_hash_table_list(channel->user_list, &htl);
4980 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4981 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4982 silc_hash_table_list_reset(&htl);
4984 client_id_list = silc_buffer_alloc(len);
4986 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4987 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4988 silc_buffer_pull_tail(client_mode_list,
4989 silc_buffer_truelen(client_mode_list));
4991 silc_hash_table_list(channel->user_list, &htl);
4992 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4994 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4995 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4996 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4997 silc_buffer_free(idp);
4999 /* Client's mode on channel */
5000 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
5001 silc_buffer_pull(client_mode_list, 4);
5005 silc_hash_table_list_reset(&htl);
5006 silc_buffer_push(client_id_list,
5007 client_id_list->data - client_id_list->head);
5008 silc_buffer_push(client_mode_list,
5009 client_mode_list->data - client_mode_list->head);
5011 *user_list = client_id_list;
5012 *mode_list = client_mode_list;
5013 *user_count = list_count;
5017 /* Saves users and their modes to the `channel'. */
5019 void silc_server_save_users_on_channel(SilcServer server,
5020 SilcPacketStream sock,
5021 SilcChannelEntry channel,
5022 SilcClientID *noadd,
5023 SilcBuffer user_list,
5024 SilcBuffer mode_list,
5025 SilcUInt32 user_count)
5031 SilcClientEntry client;
5032 SilcIDCacheEntry cache;
5033 SilcChannelClientEntry chl;
5035 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5036 channel->channel_name));
5038 for (i = 0; i < user_count; i++) {
5040 SILC_GET16_MSB(idp_len, user_list->data + 2);
5042 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5044 silc_buffer_pull(user_list, idp_len);
5047 SILC_GET32_MSB(mode, mode_list->data);
5048 silc_buffer_pull(mode_list, 4);
5050 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5055 /* Check if we have this client cached already. */
5056 client = silc_idlist_find_client_by_id(server->local_list,
5058 server->server_type, &cache);
5060 client = silc_idlist_find_client_by_id(server->global_list,
5062 server->server_type, &cache);
5064 /* If router did not find such Client ID in its lists then this must
5065 be bogus client or some router in the net is buggy. */
5066 if (server->server_type != SILC_SERVER)
5069 /* We don't have that client anywhere, add it. The client is added
5070 to global list since server didn't have it in the lists so it must be
5072 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5073 silc_id_dup(&id.u.client_id,
5075 silc_packet_get_context(sock),
5078 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5082 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5084 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
5085 server->stat.clients + 1));
5086 server->stat.clients++;
5089 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5090 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5091 "%s", channel->channel_name));
5095 if (!silc_server_client_on_channel(client, channel, &chl)) {
5096 /* Client was not on the channel, add it. */
5097 chl = silc_calloc(1, sizeof(*chl));
5098 chl->client = client;
5100 chl->channel = channel;
5101 silc_hash_table_add(channel->user_list, chl->client, chl);
5102 silc_hash_table_add(client->channels, chl->channel, chl);
5103 channel->user_count++;
5111 /* Saves channels and channels user modes to the `client'. Removes
5112 the client from those channels that are not sent in the list but
5115 void silc_server_save_user_channels(SilcServer server,
5116 SilcPacketStream sock,
5117 SilcClientEntry client,
5118 SilcBuffer channels,
5119 SilcBuffer channels_user_modes)
5122 SilcUInt32 *chumodes;
5123 SilcChannelPayload entry;
5124 SilcChannelEntry channel;
5125 SilcChannelID channel_id;
5126 SilcChannelClientEntry chl;
5127 SilcHashTable ht = NULL;
5128 SilcHashTableList htl;
5132 if (!channels || !channels_user_modes ||
5133 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5136 ch = silc_channel_payload_parse_list(channels->data,
5137 silc_buffer_len(channels));
5138 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5140 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5141 NULL, NULL, NULL, TRUE);
5142 silc_dlist_start(ch);
5143 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5144 /* Check if we have this channel, and add it if we don't have it.
5145 Also add the client on the channel unless it is there already. */
5146 if (!silc_channel_get_id_parse(entry, &channel_id))
5148 channel = silc_idlist_find_channel_by_id(server->local_list,
5151 channel = silc_idlist_find_channel_by_id(server->global_list,
5154 if (server->server_type != SILC_SERVER) {
5159 /* We don't have that channel anywhere, add it. */
5160 name = silc_channel_get_name(entry, NULL);
5161 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5162 silc_id_dup(&channel_id,
5164 server->router, NULL, NULL, 0);
5171 channel->mode = silc_channel_get_mode(entry);
5173 /* Add the client on the channel */
5174 if (!silc_server_client_on_channel(client, channel, &chl)) {
5175 chl = silc_calloc(1, sizeof(*chl));
5176 chl->client = client;
5177 chl->mode = chumodes[i++];
5178 chl->channel = channel;
5179 silc_hash_table_add(channel->user_list, chl->client, chl);
5180 silc_hash_table_add(client->channels, chl->channel, chl);
5181 channel->user_count++;
5184 chl->mode = chumodes[i++];
5187 silc_hash_table_add(ht, channel, channel);
5189 silc_channel_payload_list_free(ch);
5190 silc_free(chumodes);
5194 /* Go through the list again and remove client from channels that
5195 are no part of the list. */
5197 silc_hash_table_list(client->channels, &htl);
5198 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5199 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5200 silc_hash_table_del(chl->channel->user_list, chl->client);
5201 silc_hash_table_del(chl->client->channels, chl->channel);
5205 silc_hash_table_list_reset(&htl);
5206 silc_hash_table_free(ht);
5208 silc_hash_table_list(client->channels, &htl);
5209 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5210 silc_hash_table_del(chl->channel->user_list, chl->client);
5211 silc_hash_table_del(chl->client->channels, chl->channel);
5214 silc_hash_table_list_reset(&htl);
5218 /* Lookups route to the client indicated by the `id_data'. The connection
5219 object and internal data object is returned. Returns NULL if route
5220 could not be found to the client. If the `client_id' is specified then
5221 it is used and the `id_data' is ignored. */
5224 silc_server_get_client_route(SilcServer server,
5225 unsigned char *id_data,
5227 SilcClientID *client_id,
5228 SilcIDListData *idata,
5229 SilcClientEntry *client_entry)
5231 SilcClientID *id, clid;
5232 SilcClientEntry client;
5234 SILC_LOG_DEBUG(("Start"));
5237 *client_entry = NULL;
5239 /* Decode destination Client ID */
5241 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5243 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5245 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5248 /* If the destination belongs to our server we don't have to route
5249 the packet anywhere but to send it to the local destination. */
5250 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5254 /* If we are router and the client has router then the client is in
5255 our cell but not directly connected to us. */
5256 if (server->server_type == SILC_ROUTER && client->router) {
5257 /* We are of course in this case the client's router thus the route
5258 to the client is the server who owns the client. So, we will send
5259 the packet to that server. */
5261 *idata = (SilcIDListData)client->router;
5262 return client->router->connection;
5265 /* Seems that client really is directly connected to us */
5267 *idata = (SilcIDListData)client;
5269 *client_entry = client;
5270 return client->connection;
5273 /* Destination belongs to someone not in this server. If we are normal
5274 server our action is to send the packet to our router. */
5275 if (server->server_type != SILC_ROUTER && !server->standalone) {
5278 *idata = (SilcIDListData)server->router;
5279 return SILC_PRIMARY_ROUTE(server);
5282 /* We are router and we will perform route lookup for the destination
5283 and send the packet to fastest route. */
5284 if (server->server_type == SILC_ROUTER && !server->standalone) {
5285 /* Check first that the ID is valid */
5286 client = silc_idlist_find_client_by_id(server->global_list, id,
5289 SilcPacketStream dst_sock;
5291 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5294 if (idata && dst_sock)
5295 *idata = silc_packet_get_context(dst_sock);
5304 /* Encodes and returns channel list of channels the `client' has joined.
5305 Secret channels are not put to the list. */
5307 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5308 SilcClientEntry client,
5309 SilcBool get_private,
5310 SilcBool get_secret,
5311 SilcBuffer *user_mode_list)
5313 SilcBuffer buffer = NULL;
5314 SilcChannelEntry channel;
5315 SilcChannelClientEntry chl;
5316 SilcHashTableList htl;
5317 unsigned char cid[32];
5319 SilcUInt16 name_len;
5323 *user_mode_list = NULL;
5325 silc_hash_table_list(client->channels, &htl);
5326 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5327 channel = chl->channel;
5329 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5331 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5334 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5335 name_len = strlen(channel->channel_name);
5337 len = 4 + name_len + id_len + 4;
5338 buffer = silc_buffer_realloc(buffer,
5340 silc_buffer_truelen(buffer) + len : len));
5341 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5342 silc_buffer_format(buffer,
5343 SILC_STR_UI_SHORT(name_len),
5344 SILC_STR_DATA(channel->channel_name, name_len),
5345 SILC_STR_UI_SHORT(id_len),
5346 SILC_STR_DATA(cid, id_len),
5347 SILC_STR_UI_INT(chl->channel->mode),
5349 silc_buffer_pull(buffer, len);
5351 if (user_mode_list) {
5353 silc_buffer_realloc(*user_mode_list,
5355 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5356 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5357 (*user_mode_list)->data));
5358 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5359 silc_buffer_pull(*user_mode_list, 4);
5362 silc_hash_table_list_reset(&htl);
5365 silc_buffer_push(buffer, buffer->data - buffer->head);
5366 if (user_mode_list && *user_mode_list)
5367 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5368 (*user_mode_list)->head));
5373 /* Task callback used to retrieve network statistical information from
5374 router server once in a while. */
5376 SILC_TASK_CALLBACK(silc_server_get_stats)
5378 SilcServer server = (SilcServer)context;
5379 SilcBuffer idp, packet;
5381 if (!server->standalone) {
5382 SILC_LOG_DEBUG(("Retrieving stats from router"));
5383 server->stat.commands_sent++;
5384 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5386 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5387 ++server->cmd_ident, 1,
5389 silc_buffer_len(idp));
5390 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5391 SILC_PACKET_COMMAND, 0, packet->data,
5392 silc_buffer_len(packet));
5393 silc_buffer_free(packet);
5394 silc_buffer_free(idp);
5398 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,