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_LOG_DEBUG(("Disconnecting remote host, sock %p, status %d", sock,
3134 va_start(ap, status);
3135 cp = va_arg(ap, char *);
3137 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3140 /* Send SILC_PACKET_DISCONNECT */
3141 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3142 SILC_STR_UI_CHAR(status),
3143 SILC_STR_UI8_STRING(cp ? buf : NULL),
3146 /* Close connection */
3147 silc_server_close_connection(server, sock);
3150 /* Frees client data and notifies about client's signoff. */
3152 void silc_server_free_client_data(SilcServer server,
3153 SilcPacketStream sock,
3154 SilcClientEntry client,
3156 const char *signoff)
3158 SILC_LOG_DEBUG(("Freeing client %p data", client));
3161 /* Check if anyone is watching this nickname */
3162 if (server->server_type == SILC_ROUTER)
3163 silc_server_check_watcher_list(server, client, NULL,
3164 SILC_NOTIFY_TYPE_SIGNOFF);
3166 /* Send SIGNOFF notify to routers. */
3168 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3169 SILC_BROADCAST(server), client->id,
3173 /* Remove client from all channels */
3175 silc_server_remove_from_channels(server, NULL, client,
3176 TRUE, (char *)signoff, TRUE, FALSE);
3178 silc_server_remove_from_channels(server, NULL, client,
3179 FALSE, NULL, FALSE, FALSE);
3181 /* Remove this client from watcher list if it is */
3182 silc_server_del_from_watcher_list(server, client);
3184 /* Remove client's public key from repository, this will free it too. */
3185 if (client->data.public_key) {
3186 silc_skr_del_public_key(server->repository, client->data.public_key,
3188 client->data.public_key = NULL;
3191 /* Update statistics */
3193 /* Local detached clients aren't counted. */
3194 if (!client->local_detached)
3195 server->stat.my_clients--;
3196 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3197 server->stat.clients - 1));
3198 SILC_VERIFY(server->stat.clients > 0);
3199 server->stat.clients--;
3200 if (server->stat.cell_clients)
3201 server->stat.cell_clients--;
3202 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3203 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3204 silc_schedule_task_del_by_context(server->schedule, client);
3206 if (client->data.sconn) {
3207 silc_server_connection_free(client->data.sconn);
3208 client->data.sconn = NULL;
3211 /* We will not delete the client entry right away. We will take it
3212 into history (for WHOWAS command) for 5 minutes, unless we're
3213 shutting down server. */
3214 if (!server->server_shutdown) {
3215 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3217 client->router = NULL;
3218 client->connection = NULL;
3219 client->data.created = silc_time();
3220 silc_dlist_del(server->expired_clients, client);
3221 silc_dlist_add(server->expired_clients, client);
3223 /* Delete directly since we're shutting down server */
3224 SILC_LOG_DEBUG(("Delete client directly"));
3225 silc_idlist_del_data(client);
3226 silc_idlist_del_client(server->local_list, client);
3230 /* Frees user_data pointer from socket connection object. This also sends
3231 appropriate notify packets to the network to inform about leaving
3234 void silc_server_free_sock_user_data(SilcServer server,
3235 SilcPacketStream sock,
3236 const char *signoff_message)
3238 SilcIDListData idata;
3245 SILC_LOG_DEBUG(("Start, sock %p", sock));
3247 idata = silc_packet_get_context(sock);
3251 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3253 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_heartbeat,
3256 /* Cancel active protocols */
3258 if (idata->sconn && idata->sconn->op) {
3259 SILC_LOG_DEBUG(("Abort active protocol"));
3260 silc_async_abort(idata->sconn->op, NULL, NULL);
3261 idata->sconn->op = NULL;
3263 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3264 ((SilcUnknownEntry)idata)->op) {
3265 SILC_LOG_DEBUG(("Abort active protocol"));
3266 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3267 ((SilcUnknownEntry)idata)->op = NULL;
3271 switch (idata->conn_type) {
3272 case SILC_CONN_CLIENT:
3274 SilcClientEntry client_entry = (SilcClientEntry)idata;
3275 silc_server_free_client_data(server, sock, client_entry, TRUE,
3277 silc_packet_set_context(sock, NULL);
3281 case SILC_CONN_SERVER:
3282 case SILC_CONN_ROUTER:
3284 SilcServerEntry user_data = (SilcServerEntry)idata;
3285 SilcServerEntry backup_router = NULL;
3287 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3290 backup_router = silc_server_backup_get(server, user_data->id);
3292 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3293 backup_router == server->id_entry &&
3294 idata->conn_type != SILC_CONN_ROUTER)
3295 backup_router = NULL;
3297 if (server->server_shutdown || server->backup_noswitch)
3298 backup_router = NULL;
3300 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3301 NULL, NULL, &ip, &port);
3303 /* If this was our primary router connection then we're lost to
3304 the outside world. */
3305 if (server->router == user_data) {
3306 /* Check whether we have a backup router connection */
3307 if (!backup_router || backup_router == user_data) {
3308 if (!server->no_reconnect)
3309 silc_server_create_connections(server);
3310 server->id_entry->router = NULL;
3311 server->router = NULL;
3312 server->standalone = TRUE;
3313 server->backup_primary = FALSE;
3314 backup_router = NULL;
3316 if (server->id_entry != backup_router) {
3317 SILC_LOG_INFO(("New primary router is backup router %s",
3318 backup_router->server_name));
3319 server->id_entry->router = backup_router;
3320 server->router = backup_router;
3321 server->router_connect = time(0);
3322 server->backup_primary = TRUE;
3323 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3325 /* Send START_USE to backup router to indicate we have switched */
3326 silc_server_backup_send_start_use(server,
3327 backup_router->connection,
3330 SILC_LOG_INFO(("We are now new primary router in this cell"));
3331 server->id_entry->router = NULL;
3332 server->router = NULL;
3333 server->standalone = TRUE;
3336 /* We stop here to take a breath */
3339 if (server->backup_router) {
3340 server->server_type = SILC_ROUTER;
3342 /* We'll need to constantly try to reconnect to the primary
3343 router so that we'll see when it comes back online. */
3344 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3345 silc_server_backup_connected,
3349 /* Mark this connection as replaced */
3350 silc_server_backup_replaced_add(server, user_data->id,
3353 } else if (backup_router) {
3354 SILC_LOG_INFO(("Enabling the use of backup router %s",
3355 backup_router->server_name));
3357 /* Mark this connection as replaced */
3358 silc_server_backup_replaced_add(server, user_data->id,
3360 } else if (server->server_type == SILC_SERVER &&
3361 idata->conn_type == SILC_CONN_ROUTER) {
3362 /* Reconnect to the router (backup) */
3363 if (!server->no_reconnect)
3364 silc_server_create_connections(server);
3367 if (user_data->server_name)
3368 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3369 ("Server %s signoff", user_data->server_name));
3371 if (!backup_router) {
3372 /* Remove all servers that are originated from this server, and
3373 remove the clients of those servers too. */
3374 silc_server_remove_servers_by_server(server, user_data, TRUE);
3377 /* Remove the clients that this server owns as they will become
3378 invalid now too. For backup router the server is actually
3379 coming from the primary router, so mark that as the owner
3381 if (server->server_type == SILC_BACKUP_ROUTER &&
3382 sock->type == SILC_CONN_SERVER)
3383 silc_server_remove_clients_by_server(server, server->router,
3387 silc_server_remove_clients_by_server(server, user_data,
3390 /* Remove channels owned by this server */
3391 if (server->server_type == SILC_SERVER)
3392 silc_server_remove_channels_by_server(server, user_data);
3394 /* Enable local server connections that may be disabled */
3395 silc_server_local_servers_toggle_enabled(server, TRUE);
3397 /* Update the client entries of this server to the new backup
3398 router. If we are the backup router we also resolve the real
3399 servers for the clients. After updating is over this also
3400 removes the clients that this server explicitly owns. */
3401 silc_server_update_clients_by_server(server, user_data,
3402 backup_router, TRUE);
3404 /* If we are router and just lost our primary router (now standlaone)
3405 we remove everything that was behind it, since we don't know
3407 if (server->server_type == SILC_ROUTER && server->standalone)
3408 /* Remove all servers that are originated from this server, and
3409 remove the clients of those servers too. */
3410 silc_server_remove_servers_by_server(server, user_data, TRUE);
3412 /* Finally remove the clients that are explicitly owned by this
3413 server. They go down with the server. */
3414 silc_server_remove_clients_by_server(server, user_data,
3417 /* Update our server cache to use the new backup router too. */
3418 silc_server_update_servers_by_server(server, user_data, backup_router);
3419 if (server->server_type == SILC_SERVER)
3420 silc_server_update_channels_by_server(server, user_data,
3423 /* Send notify about primary router going down to local operators */
3424 if (server->backup_router)
3425 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3426 SILC_NOTIFY_TYPE_NONE,
3427 ("%s switched to backup router %s "
3428 "(we are primary router now)",
3429 server->server_name, server->server_name));
3430 else if (server->router)
3431 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3432 SILC_NOTIFY_TYPE_NONE,
3433 ("%s switched to backup router %s",
3434 server->server_name,
3435 server->router->server_name));
3437 server->backup_noswitch = FALSE;
3440 silc_server_connection_free(idata->sconn);
3441 idata->sconn = NULL;
3445 if (idata->conn_type == SILC_CONN_SERVER) {
3446 server->stat.my_servers--;
3447 server->stat.servers--;
3448 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3449 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3450 server->stat.my_routers--;
3451 server->stat.routers--;
3452 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3454 if (server->server_type == SILC_ROUTER)
3455 server->stat.cell_servers--;
3457 /* Free the server entry */
3458 silc_server_backup_del(server, user_data);
3459 silc_server_backup_replaced_del(server, user_data);
3460 silc_idlist_del_data(user_data);
3461 if (!silc_idlist_del_server(server->local_list, user_data))
3462 silc_idlist_del_server(server->global_list, user_data);
3464 if (backup_router && backup_router != server->id_entry) {
3465 /* Announce all of our stuff that was created about 5 minutes ago.
3466 The backup router knows all the other stuff already. */
3467 if (server->server_type == SILC_ROUTER)
3468 silc_server_announce_servers(server, FALSE, time(0) - 300,
3469 backup_router->connection);
3471 /* Announce our clients and channels to the router */
3472 silc_server_announce_clients(server, time(0) - 300,
3473 backup_router->connection);
3474 silc_server_announce_channels(server, time(0) - 300,
3475 backup_router->connection);
3478 silc_packet_set_context(sock, NULL);
3484 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3486 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3489 if (server->router_conn == idata->sconn) {
3490 if (!server->no_reconnect)
3491 silc_server_create_connections(server);
3492 server->router_conn = NULL;
3495 silc_server_connection_free(idata->sconn);
3496 idata->sconn = NULL;
3498 silc_idlist_del_data(idata);
3500 silc_packet_set_context(sock, NULL);
3506 /* Removes client from all channels it has joined. This is used when client
3507 connection is disconnected. If the client on a channel is last, the
3508 channel is removed as well. This sends the SIGNOFF notify types. */
3510 void silc_server_remove_from_channels(SilcServer server,
3511 SilcPacketStream sock,
3512 SilcClientEntry client,
3514 const char *signoff_message,
3518 SilcChannelEntry channel;
3519 SilcChannelClientEntry chl;
3520 SilcHashTableList htl;
3521 SilcBuffer clidp = NULL;
3526 if (notify && !client->id)
3529 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3530 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3533 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3538 /* Remove the client from all channels. The client is removed from
3539 the channels' user list. */
3540 silc_hash_table_list(client->channels, &htl);
3541 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3542 channel = chl->channel;
3544 /* Remove channel if this is last client leaving the channel, unless
3545 the channel is permanent. */
3546 if (server->server_type != SILC_SERVER &&
3547 silc_hash_table_count(channel->user_list) < 2) {
3548 silc_server_channel_delete(server, channel);
3552 silc_hash_table_del(client->channels, channel);
3553 silc_hash_table_del(channel->user_list, client);
3554 channel->user_count--;
3556 /* If there is no global users on the channel anymore mark the channel
3557 as local channel. Do not check if the removed client is local client. */
3558 if (server->server_type == SILC_SERVER && channel->global_users &&
3559 chl->client->router && !silc_server_channel_has_global(channel))
3560 channel->global_users = FALSE;
3562 memset(chl, 'A', sizeof(*chl));
3565 /* Update statistics */
3566 if (SILC_IS_LOCAL(client))
3567 server->stat.my_chanclients--;
3568 if (server->server_type == SILC_ROUTER) {
3569 server->stat.cell_chanclients--;
3570 server->stat.chanclients--;
3573 /* If there is not at least one local user on the channel then we don't
3574 need the channel entry anymore, we can remove it safely, unless the
3575 channel is permanent channel */
3576 if (server->server_type == SILC_SERVER &&
3577 !silc_server_channel_has_local(channel)) {
3578 /* Notify about leaving client if this channel has global users. */
3579 if (notify && channel->global_users)
3580 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3581 SILC_NOTIFY_TYPE_SIGNOFF,
3582 signoff_message ? 2 : 1,
3583 clidp->data, silc_buffer_len(clidp),
3584 signoff_message, signoff_message ?
3585 strlen(signoff_message) : 0);
3587 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3588 silc_server_channel_delete(server, channel);
3592 /* Send notify to channel about client leaving SILC and channel too */
3594 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3595 SILC_NOTIFY_TYPE_SIGNOFF,
3596 signoff_message ? 2 : 1,
3597 clidp->data, silc_buffer_len(clidp),
3598 signoff_message, signoff_message ?
3599 strlen(signoff_message) : 0);
3601 if (killed && clidp) {
3602 /* Remove the client from channel's invite list */
3603 if (channel->invite_list &&
3604 silc_hash_table_count(channel->invite_list)) {
3606 SilcArgumentPayload iargs;
3607 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3608 silc_buffer_len(clidp), 3);
3609 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3610 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3611 silc_buffer_free(ab);
3612 silc_argument_payload_free(iargs);
3616 /* Don't create keys if we are shutting down */
3617 if (server->server_shutdown)
3620 /* Re-generate channel key if needed */
3621 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3622 if (!silc_server_create_channel_key(server, channel, 0))
3625 /* Send the channel key to the channel. The key of course is not sent
3626 to the client who was removed from the channel. */
3627 silc_server_send_channel_key(server, client->connection, channel,
3628 server->server_type == SILC_ROUTER ?
3629 FALSE : !server->standalone);
3633 silc_hash_table_list_reset(&htl);
3635 silc_buffer_free(clidp);
3638 /* Removes client from one channel. This is used for example when client
3639 calls LEAVE command to remove itself from the channel. Returns TRUE
3640 if channel still exists and FALSE if the channel is removed when
3641 last client leaves the channel. If `notify' is FALSE notify messages
3644 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3645 SilcPacketStream sock,
3646 SilcChannelEntry channel,
3647 SilcClientEntry client,
3650 SilcChannelClientEntry chl;
3653 SILC_LOG_DEBUG(("Removing %s from channel %s",
3654 silc_id_render(client->id, SILC_ID_CLIENT),
3655 channel->channel_name));
3657 /* Get the entry to the channel, if this client is not on the channel
3659 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3662 /* Remove channel if this is last client leaving the channel, unless
3663 the channel is permanent. */
3664 if (server->server_type != SILC_SERVER &&
3665 silc_hash_table_count(channel->user_list) < 2) {
3666 silc_server_channel_delete(server, channel);
3670 silc_hash_table_del(client->channels, channel);
3671 silc_hash_table_del(channel->user_list, client);
3672 channel->user_count--;
3674 /* If there is no global users on the channel anymore mark the channel
3675 as local channel. Do not check if the client is local client. */
3676 if (server->server_type == SILC_SERVER && channel->global_users &&
3677 chl->client->router && !silc_server_channel_has_global(channel))
3678 channel->global_users = FALSE;
3680 memset(chl, 'O', sizeof(*chl));
3683 /* Update statistics */
3684 if (SILC_IS_LOCAL(client))
3685 server->stat.my_chanclients--;
3686 if (server->server_type == SILC_ROUTER) {
3687 server->stat.cell_chanclients--;
3688 server->stat.chanclients--;
3691 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3695 /* If there is not at least one local user on the channel then we don't
3696 need the channel entry anymore, we can remove it safely, unless the
3697 channel is permanent channel */
3698 if (server->server_type == SILC_SERVER &&
3699 !silc_server_channel_has_local(channel)) {
3700 /* Notify about leaving client if this channel has global users. */
3701 if (notify && channel->global_users)
3702 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3703 SILC_NOTIFY_TYPE_LEAVE, 1,
3704 clidp->data, silc_buffer_len(clidp));
3706 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3707 silc_server_channel_delete(server, channel);
3708 silc_buffer_free(clidp);
3712 /* Send notify to channel about client leaving the channel */
3714 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3715 SILC_NOTIFY_TYPE_LEAVE, 1,
3716 clidp->data, silc_buffer_len(clidp));
3718 silc_buffer_free(clidp);
3722 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3723 function may be used only by router. In real SILC network all channels
3724 are created by routers thus this function is never used by normal
3727 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3728 SilcServerID *router_id,
3734 SilcChannelID *channel_id;
3735 SilcChannelEntry entry;
3736 SilcCipher send_key, receive_key;
3739 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3742 cipher = SILC_DEFAULT_CIPHER;
3744 hmac = SILC_DEFAULT_HMAC;
3746 /* Allocate cipher */
3747 if (!silc_cipher_alloc(cipher, &send_key))
3749 if (!silc_cipher_alloc(cipher, &receive_key)) {
3750 silc_cipher_free(send_key);
3755 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3756 silc_cipher_free(send_key);
3757 silc_cipher_free(receive_key);
3761 channel_name = strdup(channel_name);
3763 /* Create the channel ID */
3764 if (!silc_id_create_channel_id(server, router_id, server->rng,
3766 silc_free(channel_name);
3767 silc_cipher_free(send_key);
3768 silc_cipher_free(receive_key);
3769 silc_hmac_free(newhmac);
3773 /* Create the channel */
3774 entry = silc_idlist_add_channel(server->local_list, channel_name,
3775 SILC_CHANNEL_MODE_NONE, channel_id,
3776 NULL, send_key, receive_key, newhmac);
3778 silc_free(channel_name);
3779 silc_cipher_free(send_key);
3780 silc_cipher_free(receive_key);
3781 silc_hmac_free(newhmac);
3782 silc_free(channel_id);
3786 entry->cipher = strdup(cipher);
3787 entry->hmac_name = strdup(hmac);
3789 /* Now create the actual key material */
3790 if (!silc_server_create_channel_key(server, entry,
3791 silc_cipher_get_key_len(send_key) / 8)) {
3792 silc_idlist_del_channel(server->local_list, entry);
3796 /* Notify other routers about the new channel. We send the packet
3797 to our primary route. */
3799 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3800 channel_name, entry->id,
3801 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3804 /* Distribute to backup routers */
3805 if (broadcast && server->server_type == SILC_ROUTER) {
3807 unsigned char cid[32];
3808 SilcUInt32 name_len = strlen(channel_name);
3811 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3812 packet = silc_channel_payload_encode(channel_name, name_len,
3813 cid, id_len, entry->mode);
3814 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3815 packet->data, silc_buffer_len(packet), FALSE,
3817 silc_buffer_free(packet);
3820 server->stat.my_channels++;
3821 if (server->server_type == SILC_ROUTER) {
3822 server->stat.channels++;
3823 server->stat.cell_channels++;
3824 entry->users_resolved = TRUE;
3830 /* Same as above but creates the channel with Channel ID `channel_id. */
3833 silc_server_create_new_channel_with_id(SilcServer server,
3837 SilcChannelID *channel_id,
3840 SilcChannelEntry entry;
3841 SilcCipher send_key, receive_key;
3844 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3847 cipher = SILC_DEFAULT_CIPHER;
3849 hmac = SILC_DEFAULT_HMAC;
3851 /* Allocate cipher */
3852 if (!silc_cipher_alloc(cipher, &send_key))
3854 if (!silc_cipher_alloc(cipher, &receive_key)) {
3855 silc_cipher_free(send_key);
3860 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3861 silc_cipher_free(send_key);
3862 silc_cipher_free(receive_key);
3866 channel_name = strdup(channel_name);
3868 /* Create the channel */
3869 entry = silc_idlist_add_channel(server->local_list, channel_name,
3870 SILC_CHANNEL_MODE_NONE, channel_id,
3871 NULL, send_key, receive_key, newhmac);
3873 silc_cipher_free(send_key);
3874 silc_cipher_free(receive_key);
3875 silc_hmac_free(newhmac);
3876 silc_free(channel_name);
3880 /* Now create the actual key material */
3881 if (!silc_server_create_channel_key(server, entry,
3882 silc_cipher_get_key_len(send_key) / 8)) {
3883 silc_idlist_del_channel(server->local_list, entry);
3887 /* Notify other routers about the new channel. We send the packet
3888 to our primary route. */
3890 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3891 channel_name, entry->id,
3892 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3895 /* Distribute to backup routers */
3896 if (broadcast && server->server_type == SILC_ROUTER) {
3898 unsigned char cid[32];
3899 SilcUInt32 name_len = strlen(channel_name);
3902 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3903 packet = silc_channel_payload_encode(channel_name, name_len,
3904 cid, id_len, entry->mode);
3905 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3906 packet->data, silc_buffer_len(packet), FALSE,
3908 silc_buffer_free(packet);
3911 server->stat.my_channels++;
3912 if (server->server_type == SILC_ROUTER) {
3913 server->stat.channels++;
3914 server->stat.cell_channels++;
3915 entry->users_resolved = TRUE;
3921 /* Channel's key re-key timeout callback. */
3923 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3925 SilcServer server = app_context;
3926 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3930 /* Return now if we are shutting down */
3931 if (server->server_shutdown)
3934 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3937 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3940 /* Generates new channel key. This is used to create the initial channel key
3941 but also to re-generate new key for channel. If `key_len' is provided
3942 it is the bytes of the key length. */
3944 SilcBool silc_server_create_channel_key(SilcServer server,
3945 SilcChannelEntry channel,
3949 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3952 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3953 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3957 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3959 if (!channel->send_key)
3960 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3961 channel->send_key = NULL;
3964 if (!channel->receive_key)
3965 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3966 silc_cipher_free(channel->send_key);
3967 channel->send_key = channel->receive_key = NULL;
3973 else if (channel->key_len)
3974 len = channel->key_len / 8;
3976 len = silc_cipher_get_key_len(channel->send_key) / 8;
3978 /* Create channel key */
3979 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3982 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3983 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3985 /* Remove old key if exists */
3987 memset(channel->key, 0, channel->key_len / 8);
3988 silc_free(channel->key);
3992 channel->key_len = len * 8;
3993 channel->key = silc_memdup(channel_key, len);
3994 memset(channel_key, 0, sizeof(channel_key));
3996 /* Generate HMAC key from the channel key data and set it */
3998 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3999 memset(channel->key, 0, channel->key_len / 8);
4000 silc_free(channel->key);
4001 silc_cipher_free(channel->send_key);
4002 silc_cipher_free(channel->receive_key);
4003 channel->send_key = channel->receive_key = NULL;
4006 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
4007 silc_hmac_set_key(channel->hmac, hash,
4008 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4009 memset(hash, 0, sizeof(hash));
4011 if (server->server_type == SILC_ROUTER) {
4012 if (!channel->rekey)
4013 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4014 channel->rekey->channel = channel;
4015 channel->rekey->key_len = key_len;
4016 if (channel->rekey->task)
4017 silc_schedule_task_del(server->schedule, channel->rekey->task);
4019 channel->rekey->task =
4020 silc_schedule_task_add_timeout(server->schedule,
4021 silc_server_channel_key_rekey,
4022 (void *)channel->rekey,
4023 server->config->channel_rekey_secs, 0);
4029 /* Saves the channel key found in the encoded `key_payload' buffer. This
4030 function is used when we receive Channel Key Payload and also when we're
4031 processing JOIN command reply. Returns entry to the channel. */
4033 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4034 SilcBuffer key_payload,
4035 SilcChannelEntry channel)
4037 SilcChannelKeyPayload payload = NULL;
4039 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4043 /* Decode channel key payload */
4044 payload = silc_channel_key_payload_parse(key_payload->data,
4045 silc_buffer_len(key_payload));
4047 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4052 /* Get the channel entry */
4055 /* Get channel ID */
4056 tmp = silc_channel_key_get_id(payload, &tmp_len);
4057 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4062 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4064 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4066 if (server->server_type == SILC_ROUTER)
4067 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4068 silc_id_render(&id, SILC_ID_CHANNEL)));
4074 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4076 tmp = silc_channel_key_get_key(payload, &tmp_len);
4082 cipher = silc_channel_key_get_cipher(payload, NULL);
4088 /* Remove old key if exists */
4090 memset(channel->key, 0, channel->key_len / 8);
4091 silc_free(channel->key);
4092 silc_cipher_free(channel->send_key);
4093 silc_cipher_free(channel->receive_key);
4096 /* Create new cipher */
4097 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4098 channel->send_key = NULL;
4102 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4103 silc_cipher_free(channel->send_key);
4104 channel->send_key = channel->receive_key = NULL;
4109 if (channel->cipher)
4110 silc_free(channel->cipher);
4111 channel->cipher = strdup(cipher);
4114 channel->key_len = tmp_len * 8;
4115 channel->key = silc_memdup(tmp, tmp_len);
4116 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4117 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4119 /* Generate HMAC key from the channel key data and set it */
4121 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4122 memset(channel->key, 0, channel->key_len / 8);
4123 silc_free(channel->key);
4124 silc_cipher_free(channel->send_key);
4125 silc_cipher_free(channel->receive_key);
4126 channel->send_key = channel->receive_key = NULL;
4129 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4130 silc_hmac_set_key(channel->hmac, hash,
4131 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4133 memset(hash, 0, sizeof(hash));
4134 memset(tmp, 0, tmp_len);
4136 if (server->server_type == SILC_ROUTER) {
4137 if (!channel->rekey)
4138 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4139 channel->rekey->channel = channel;
4140 if (channel->rekey->task)
4141 silc_schedule_task_del(server->schedule, channel->rekey->task);
4143 channel->rekey->task =
4144 silc_schedule_task_add_timeout(server->schedule,
4145 silc_server_channel_key_rekey,
4146 (void *)channel->rekey,
4147 server->config->channel_rekey_secs, 0);
4152 silc_channel_key_payload_free(payload);
4157 /* Returns assembled of all servers in the given ID list. The packet's
4158 form is dictated by the New ID payload. */
4160 static void silc_server_announce_get_servers(SilcServer server,
4161 SilcServerEntry remote,
4163 SilcBuffer *servers,
4164 unsigned long creation_time)
4167 SilcIDCacheEntry id_cache;
4168 SilcServerEntry entry;
4172 /* Go through all clients in the list */
4173 if (silc_idcache_get_all(id_list->servers, &list)) {
4174 silc_list_start(list);
4175 while ((id_cache = silc_list_get(list))) {
4176 entry = (SilcServerEntry)id_cache->context;
4178 /* Do not announce the one we've sending our announcements and
4179 do not announce ourself. Also check the creation time if it's
4181 if ((entry == remote) || (entry == server->id_entry) ||
4182 (creation_time && entry->data.created < creation_time))
4185 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4187 tmp = silc_buffer_realloc(*servers,
4189 silc_buffer_truelen((*servers)) +
4190 silc_buffer_len(idp) :
4191 silc_buffer_len(idp)));
4195 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4196 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4197 silc_buffer_pull(*servers, silc_buffer_len(idp));
4198 silc_buffer_free(idp);
4204 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4210 p = silc_notify_payload_encode(notify, argc, ap);
4216 /* This function is used by router to announce existing servers to our
4217 primary router when we've connected to it. If `creation_time' is non-zero
4218 then only the servers that has been created after the `creation_time'
4219 will be announced. */
4221 void silc_server_announce_servers(SilcServer server, SilcBool global,
4222 unsigned long creation_time,
4223 SilcPacketStream remote)
4225 SilcBuffer servers = NULL;
4227 SILC_LOG_DEBUG(("Announcing servers"));
4229 /* Get servers in local list */
4230 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4231 server->local_list, &servers,
4235 /* Get servers in global list */
4236 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4237 server->global_list, &servers,
4241 silc_buffer_push(servers, servers->data - servers->head);
4242 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4244 /* Send the packet */
4245 silc_server_packet_send(server, remote,
4246 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4247 servers->data, silc_buffer_len(servers));
4249 silc_buffer_free(servers);
4253 /* Returns assembled packet of all clients in the given ID list. The
4254 packet's form is dictated by the New ID Payload. */
4256 static void silc_server_announce_get_clients(SilcServer server,
4258 SilcBuffer *clients,
4260 unsigned long creation_time)
4263 SilcIDCacheEntry id_cache;
4264 SilcClientEntry client;
4267 unsigned char mode[4];
4270 /* Go through all clients in the list */
4271 if (silc_idcache_get_all(id_list->clients, &list)) {
4272 silc_list_start(list);
4273 while ((id_cache = silc_list_get(list))) {
4274 client = (SilcClientEntry)id_cache->context;
4276 if (creation_time && client->data.created < creation_time)
4278 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4280 if (!client->connection && !client->router)
4283 SILC_LOG_DEBUG(("Announce Client ID %s",
4284 silc_id_render(client->id, SILC_ID_CLIENT)));
4286 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4290 tmp2 = silc_buffer_realloc(*clients,
4292 silc_buffer_truelen((*clients)) +
4293 silc_buffer_len(idp) :
4294 silc_buffer_len(idp)));
4298 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4299 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4300 silc_buffer_pull(*clients, silc_buffer_len(idp));
4302 SILC_PUT32_MSB(client->mode, mode);
4304 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4305 2, idp->data, silc_buffer_len(idp),
4307 tmp2 = silc_buffer_realloc(*umodes,
4309 silc_buffer_truelen((*umodes)) +
4310 silc_buffer_len(tmp) :
4311 silc_buffer_len(tmp)));
4315 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4316 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4317 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4318 silc_buffer_free(tmp);
4320 silc_buffer_free(idp);
4325 /* This function is used to announce our existing clients to our router
4326 when we've connected to it. If `creation_time' is non-zero then only
4327 the clients that has been created after the `creation_time' will be
4330 void silc_server_announce_clients(SilcServer server,
4331 unsigned long creation_time,
4332 SilcPacketStream remote)
4334 SilcBuffer clients = NULL;
4335 SilcBuffer umodes = NULL;
4337 SILC_LOG_DEBUG(("Announcing clients"));
4339 /* Get clients in local list */
4340 silc_server_announce_get_clients(server, server->local_list,
4341 &clients, &umodes, creation_time);
4343 /* As router we announce our global list as well */
4344 if (server->server_type == SILC_ROUTER)
4345 silc_server_announce_get_clients(server, server->global_list,
4346 &clients, &umodes, creation_time);
4349 silc_buffer_push(clients, clients->data - clients->head);
4350 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4352 /* Send the packet */
4353 silc_server_packet_send(server, remote,
4354 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4355 clients->data, silc_buffer_len(clients));
4357 silc_buffer_free(clients);
4361 silc_buffer_push(umodes, umodes->data - umodes->head);
4362 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4364 /* Send the packet */
4365 silc_server_packet_send(server, remote,
4366 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4367 umodes->data, silc_buffer_len(umodes));
4369 silc_buffer_free(umodes);
4373 /* Returns channel's topic for announcing it */
4375 void silc_server_announce_get_channel_topic(SilcServer server,
4376 SilcChannelEntry channel,
4381 if (channel->topic) {
4382 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4383 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4385 silc_buffer_len(chidp),
4387 strlen(channel->topic));
4388 silc_buffer_free(chidp);
4392 /* Returns channel's invite and ban lists */
4394 void silc_server_announce_get_inviteban(SilcServer server,
4395 SilcChannelEntry channel,
4399 SilcBuffer list, idp, idp2, tmp2;
4402 SilcHashTableList htl;
4403 const unsigned char a[1] = { 0x03 };
4405 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4407 /* Encode invite list */
4408 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4409 list = silc_buffer_alloc_size(2);
4410 type = silc_hash_table_count(channel->invite_list);
4411 SILC_PUT16_MSB(type, list->data);
4412 silc_hash_table_list(channel->invite_list, &htl);
4413 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4414 list = silc_argument_payload_encode_one(list, tmp2->data,
4415 silc_buffer_len(tmp2),
4416 SILC_PTR_TO_32(ptype));
4417 silc_hash_table_list_reset(&htl);
4419 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4421 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4422 idp->data, silc_buffer_len(idp),
4423 channel->channel_name,
4424 strlen(channel->channel_name),
4425 idp2->data, silc_buffer_len(idp2),
4427 list->data, silc_buffer_len(list));
4428 silc_buffer_free(idp2);
4429 silc_buffer_free(list);
4432 /* Encode ban list */
4433 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4434 list = silc_buffer_alloc_size(2);
4435 type = silc_hash_table_count(channel->ban_list);
4436 SILC_PUT16_MSB(type, list->data);
4437 silc_hash_table_list(channel->ban_list, &htl);
4438 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4439 list = silc_argument_payload_encode_one(list, tmp2->data,
4440 silc_buffer_len(tmp2),
4441 SILC_PTR_TO_32(ptype));
4442 silc_hash_table_list_reset(&htl);
4445 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4446 idp->data, silc_buffer_len(idp),
4448 list->data, silc_buffer_len(list));
4449 silc_buffer_free(list);
4452 silc_buffer_free(idp);
4455 /* Returns assembled packets for channel users of the `channel'. */
4457 void silc_server_announce_get_channel_users(SilcServer server,
4458 SilcChannelEntry channel,
4459 SilcBuffer *channel_modes,
4460 SilcBuffer *channel_users,
4461 SilcBuffer *channel_users_modes)
4463 SilcChannelClientEntry chl;
4464 SilcHashTableList htl;
4465 SilcBuffer chidp, clidp, csidp;
4466 SilcBuffer tmp, fkey = NULL, chpklist;
4468 unsigned char mode[4], ulimit[4];
4472 SILC_LOG_DEBUG(("Start"));
4474 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4475 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4476 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4479 SILC_PUT32_MSB(channel->mode, mode);
4480 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4481 SILC_PUT32_MSB(channel->user_limit, ulimit);
4482 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4483 if (channel->founder_key)
4484 fkey = silc_public_key_payload_encode(channel->founder_key);
4486 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4488 silc_buffer_len(csidp),
4491 hmac, hmac ? strlen(hmac) : 0,
4492 channel->passphrase,
4493 channel->passphrase ?
4494 strlen(channel->passphrase) : 0,
4495 fkey ? fkey->data : NULL,
4496 fkey ? silc_buffer_len(fkey) : 0,
4497 chpklist ? chpklist->data : NULL,
4499 silc_buffer_len(chpklist) : 0,
4501 SILC_CHANNEL_MODE_ULIMIT ?
4504 SILC_CHANNEL_MODE_ULIMIT ?
4505 sizeof(ulimit) : 0));
4506 len = silc_buffer_len(tmp);
4508 silc_buffer_realloc(*channel_modes,
4510 silc_buffer_truelen((*channel_modes)) + len : len));
4513 *channel_modes = tmp2;
4514 silc_buffer_pull_tail(*channel_modes,
4515 ((*channel_modes)->end -
4516 (*channel_modes)->data));
4517 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4518 silc_buffer_pull(*channel_modes, len);
4519 silc_buffer_free(tmp);
4520 silc_buffer_free(fkey);
4523 /* Now find all users on the channel */
4524 silc_hash_table_list(channel->user_list, &htl);
4525 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4526 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4528 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4532 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4534 silc_buffer_len(clidp),
4536 silc_buffer_len(chidp));
4537 len = silc_buffer_len(tmp);
4539 silc_buffer_realloc(*channel_users,
4541 silc_buffer_truelen((*channel_users)) + len : len));
4544 *channel_users = tmp2;
4545 silc_buffer_pull_tail(*channel_users,
4546 ((*channel_users)->end -
4547 (*channel_users)->data));
4549 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4550 silc_buffer_pull(*channel_users, len);
4551 silc_buffer_free(tmp);
4553 /* CUMODE notify for mode change on the channel */
4554 SILC_PUT32_MSB(chl->mode, mode);
4555 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4556 fkey = silc_public_key_payload_encode(channel->founder_key);
4557 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4559 silc_buffer_len(csidp),
4562 silc_buffer_len(clidp),
4563 fkey ? fkey->data : NULL,
4564 fkey ? silc_buffer_len(fkey) : 0);
4565 len = silc_buffer_len(tmp);
4567 silc_buffer_realloc(*channel_users_modes,
4568 (*channel_users_modes ?
4569 silc_buffer_truelen((*channel_users_modes)) +
4573 *channel_users_modes = tmp2;
4574 silc_buffer_pull_tail(*channel_users_modes,
4575 ((*channel_users_modes)->end -
4576 (*channel_users_modes)->data));
4578 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4579 silc_buffer_pull(*channel_users_modes, len);
4580 silc_buffer_free(tmp);
4581 silc_buffer_free(fkey);
4583 silc_buffer_free(clidp);
4585 silc_hash_table_list_reset(&htl);
4586 silc_buffer_free(chidp);
4587 silc_buffer_free(csidp);
4590 /* Returns assembled packets for all channels and users on those channels
4591 from the given ID List. The packets are in the form dictated by the
4592 New Channel and New Channel User payloads. */
4594 void silc_server_announce_get_channels(SilcServer server,
4596 SilcBuffer *channels,
4597 SilcBuffer **channel_modes,
4598 SilcBuffer *channel_users,
4599 SilcBuffer **channel_users_modes,
4600 SilcUInt32 *channel_users_modes_c,
4601 SilcBuffer **channel_topics,
4602 SilcBuffer **channel_invites,
4603 SilcBuffer **channel_bans,
4604 SilcChannelID ***channel_ids,
4605 unsigned long creation_time)
4608 SilcIDCacheEntry id_cache;
4609 SilcChannelEntry channel;
4610 unsigned char cid[32];
4612 SilcUInt16 name_len;
4614 int i = *channel_users_modes_c;
4618 SILC_LOG_DEBUG(("Start"));
4620 /* Go through all channels in the list */
4621 if (silc_idcache_get_all(id_list->channels, &list)) {
4622 silc_list_start(list);
4623 while ((id_cache = silc_list_get(list))) {
4624 channel = (SilcChannelEntry)id_cache->context;
4626 if (creation_time && channel->created < creation_time)
4631 SILC_LOG_DEBUG(("Announce Channel ID %s",
4632 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4634 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4635 name_len = strlen(channel->channel_name);
4638 len = 4 + name_len + id_len + 4;
4640 silc_buffer_realloc(*channels,
4642 silc_buffer_truelen((*channels)) +
4648 silc_buffer_pull_tail(*channels,
4649 ((*channels)->end - (*channels)->data));
4650 silc_buffer_format(*channels,
4651 SILC_STR_UI_SHORT(name_len),
4652 SILC_STR_UI_XNSTRING(channel->channel_name,
4654 SILC_STR_UI_SHORT(id_len),
4655 SILC_STR_UI_XNSTRING(cid, id_len),
4656 SILC_STR_UI_INT(channel->mode),
4658 silc_buffer_pull(*channels, len);
4661 if (creation_time && channel->updated < creation_time)
4667 /* Channel user modes */
4668 tmp = silc_realloc(*channel_users_modes,
4669 sizeof(**channel_users_modes) * (i + 1));
4672 *channel_users_modes = tmp;
4673 (*channel_users_modes)[i] = NULL;
4674 tmp = silc_realloc(*channel_modes,
4675 sizeof(**channel_modes) * (i + 1));
4678 *channel_modes = tmp;
4679 (*channel_modes)[i] = NULL;
4680 tmp = silc_realloc(*channel_ids,
4681 sizeof(**channel_ids) * (i + 1));
4685 (*channel_ids)[i] = NULL;
4686 silc_server_announce_get_channel_users(server, channel,
4687 &(*channel_modes)[i],
4689 &(*channel_users_modes)[i]);
4690 (*channel_ids)[i] = channel->id;
4692 /* Channel's topic */
4693 tmp = silc_realloc(*channel_topics,
4694 sizeof(**channel_topics) * (i + 1));
4697 *channel_topics = tmp;
4698 (*channel_topics)[i] = NULL;
4699 silc_server_announce_get_channel_topic(server, channel,
4700 &(*channel_topics)[i]);
4702 /* Channel's invite and ban list */
4703 tmp = silc_realloc(*channel_invites,
4704 sizeof(**channel_invites) * (i + 1));
4707 *channel_invites = tmp;
4708 (*channel_invites)[i] = NULL;
4709 tmp = silc_realloc(*channel_bans,
4710 sizeof(**channel_bans) * (i + 1));
4713 *channel_bans = tmp;
4714 (*channel_bans)[i] = NULL;
4715 silc_server_announce_get_inviteban(server, channel,
4716 &(*channel_invites)[i],
4717 &(*channel_bans)[i]);
4719 (*channel_users_modes_c)++;
4727 /* This function is used to announce our existing channels to our router
4728 when we've connected to it. This also announces the users on the
4729 channels to the router. If the `creation_time' is non-zero only the
4730 channels that was created after the `creation_time' are announced.
4731 Note that the channel users are still announced even if the `creation_time'
4734 void silc_server_announce_channels(SilcServer server,
4735 unsigned long creation_time,
4736 SilcPacketStream remote)
4738 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4739 SilcBuffer *channel_users_modes = NULL;
4740 SilcBuffer *channel_topics = NULL;
4741 SilcBuffer *channel_invites = NULL;
4742 SilcBuffer *channel_bans = NULL;
4743 SilcUInt32 channel_users_modes_c = 0;
4744 SilcChannelID **channel_ids = NULL;
4746 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4748 /* Get channels and channel users in local list */
4749 silc_server_announce_get_channels(server, server->local_list,
4750 &channels, &channel_modes,
4752 &channel_users_modes,
4753 &channel_users_modes_c,
4757 &channel_ids, creation_time);
4759 /* Get channels and channel users in global list */
4760 if (server->server_type != SILC_SERVER)
4761 silc_server_announce_get_channels(server, server->global_list,
4762 &channels, &channel_modes,
4764 &channel_users_modes,
4765 &channel_users_modes_c,
4769 &channel_ids, creation_time);
4772 silc_buffer_push(channels, channels->data - channels->head);
4773 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4775 /* Send the packet */
4776 silc_server_packet_send(server, remote,
4777 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4778 channels->data, silc_buffer_len(channels));
4780 silc_buffer_free(channels);
4783 if (channel_users) {
4784 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4785 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4786 silc_buffer_len(channel_users));
4788 /* Send the packet */
4789 silc_server_packet_send(server, remote,
4790 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4791 channel_users->data, silc_buffer_len(channel_users));
4793 silc_buffer_free(channel_users);
4796 if (channel_modes) {
4799 for (i = 0; i < channel_users_modes_c; i++) {
4800 if (!channel_modes[i])
4802 silc_buffer_push(channel_modes[i],
4803 channel_modes[i]->data -
4804 channel_modes[i]->head);
4805 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4806 silc_buffer_len(channel_modes[i]));
4807 silc_server_packet_send_dest(server, remote,
4808 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4809 channel_ids[i], SILC_ID_CHANNEL,
4810 channel_modes[i]->data,
4811 silc_buffer_len(channel_modes[i]));
4812 silc_buffer_free(channel_modes[i]);
4814 silc_free(channel_modes);
4817 if (channel_users_modes) {
4820 for (i = 0; i < channel_users_modes_c; i++) {
4821 if (!channel_users_modes[i])
4823 silc_buffer_push(channel_users_modes[i],
4824 channel_users_modes[i]->data -
4825 channel_users_modes[i]->head);
4826 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4827 silc_buffer_len(channel_users_modes[i]));
4828 silc_server_packet_send_dest(server, remote,
4829 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4830 channel_ids[i], SILC_ID_CHANNEL,
4831 channel_users_modes[i]->data,
4832 silc_buffer_len(channel_users_modes[i]));
4833 silc_buffer_free(channel_users_modes[i]);
4835 silc_free(channel_users_modes);
4838 if (channel_topics) {
4841 for (i = 0; i < channel_users_modes_c; i++) {
4842 if (!channel_topics[i])
4845 silc_buffer_push(channel_topics[i],
4846 channel_topics[i]->data -
4847 channel_topics[i]->head);
4848 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4849 silc_buffer_len(channel_topics[i]));
4850 silc_server_packet_send_dest(server, remote,
4851 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4852 channel_ids[i], SILC_ID_CHANNEL,
4853 channel_topics[i]->data,
4854 silc_buffer_len(channel_topics[i]));
4855 silc_buffer_free(channel_topics[i]);
4857 silc_free(channel_topics);
4860 if (channel_invites) {
4863 for (i = 0; i < channel_users_modes_c; i++) {
4864 if (!channel_invites[i])
4867 silc_buffer_push(channel_invites[i],
4868 channel_invites[i]->data -
4869 channel_invites[i]->head);
4870 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4871 silc_buffer_len(channel_invites[i]));
4872 silc_server_packet_send_dest(server, remote,
4873 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4874 channel_ids[i], SILC_ID_CHANNEL,
4875 channel_invites[i]->data,
4876 silc_buffer_len(channel_invites[i]));
4877 silc_buffer_free(channel_invites[i]);
4879 silc_free(channel_invites);
4885 for (i = 0; i < channel_users_modes_c; i++) {
4886 if (!channel_bans[i])
4889 silc_buffer_push(channel_bans[i],
4890 channel_bans[i]->data -
4891 channel_bans[i]->head);
4892 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4893 silc_buffer_len(channel_bans[i]));
4894 silc_server_packet_send_dest(server, remote,
4895 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4896 channel_ids[i], SILC_ID_CHANNEL,
4897 channel_bans[i]->data,
4898 silc_buffer_len(channel_bans[i]));
4899 silc_buffer_free(channel_bans[i]);
4901 silc_free(channel_bans);
4904 silc_free(channel_ids);
4907 /* Announces WATCH list. */
4909 void silc_server_announce_watches(SilcServer server,
4910 SilcPacketStream remote)
4912 SilcHashTableList htl;
4913 SilcBuffer buffer, idp, args, pkp;
4914 SilcClientEntry client;
4917 SILC_LOG_DEBUG(("Announcing watch list"));
4919 /* XXX because way we save the nicks (hash) we cannot announce them. */
4921 /* XXX we should send all public keys in one command if client is
4922 watching more than one key */
4923 silc_hash_table_list(server->watcher_list_pk, &htl);
4924 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4925 if (!client || !client->id)
4928 server->stat.commands_sent++;
4930 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4931 args = silc_buffer_alloc_size(2);
4932 silc_buffer_format(args,
4933 SILC_STR_UI_SHORT(1),
4935 pkp = silc_public_key_payload_encode(key);
4936 args = silc_argument_payload_encode_one(args, pkp->data,
4937 silc_buffer_len(pkp), 0x00);
4938 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4939 ++server->cmd_ident, 2,
4940 1, idp->data, silc_buffer_len(idp),
4942 silc_buffer_len(args));
4945 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4946 buffer->data, silc_buffer_len(buffer));
4948 silc_buffer_free(pkp);
4949 silc_buffer_free(args);
4950 silc_buffer_free(idp);
4951 silc_buffer_free(buffer);
4953 silc_hash_table_list_reset(&htl);
4956 /* Assembles user list and users mode list from the `channel'. */
4958 SilcBool silc_server_get_users_on_channel(SilcServer server,
4959 SilcChannelEntry channel,
4960 SilcBuffer *user_list,
4961 SilcBuffer *mode_list,
4962 SilcUInt32 *user_count)
4964 SilcChannelClientEntry chl;
4965 SilcHashTableList htl;
4966 SilcBuffer client_id_list;
4967 SilcBuffer client_mode_list;
4969 SilcUInt32 list_count = 0, len = 0;
4971 if (!silc_hash_table_count(channel->user_list))
4974 silc_hash_table_list(channel->user_list, &htl);
4975 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4976 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4977 silc_hash_table_list_reset(&htl);
4979 client_id_list = silc_buffer_alloc(len);
4981 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4982 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4983 silc_buffer_pull_tail(client_mode_list,
4984 silc_buffer_truelen(client_mode_list));
4986 silc_hash_table_list(channel->user_list, &htl);
4987 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4989 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4990 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4991 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4992 silc_buffer_free(idp);
4994 /* Client's mode on channel */
4995 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4996 silc_buffer_pull(client_mode_list, 4);
5000 silc_hash_table_list_reset(&htl);
5001 silc_buffer_push(client_id_list,
5002 client_id_list->data - client_id_list->head);
5003 silc_buffer_push(client_mode_list,
5004 client_mode_list->data - client_mode_list->head);
5006 *user_list = client_id_list;
5007 *mode_list = client_mode_list;
5008 *user_count = list_count;
5012 /* Saves users and their modes to the `channel'. */
5014 void silc_server_save_users_on_channel(SilcServer server,
5015 SilcPacketStream sock,
5016 SilcChannelEntry channel,
5017 SilcClientID *noadd,
5018 SilcBuffer user_list,
5019 SilcBuffer mode_list,
5020 SilcUInt32 user_count)
5026 SilcClientEntry client;
5027 SilcIDCacheEntry cache;
5028 SilcChannelClientEntry chl;
5030 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5031 channel->channel_name));
5033 for (i = 0; i < user_count; i++) {
5035 SILC_GET16_MSB(idp_len, user_list->data + 2);
5037 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5039 silc_buffer_pull(user_list, idp_len);
5042 SILC_GET32_MSB(mode, mode_list->data);
5043 silc_buffer_pull(mode_list, 4);
5045 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5050 /* Check if we have this client cached already. */
5051 client = silc_idlist_find_client_by_id(server->local_list,
5053 server->server_type, &cache);
5055 client = silc_idlist_find_client_by_id(server->global_list,
5057 server->server_type, &cache);
5059 /* If router did not find such Client ID in its lists then this must
5060 be bogus client or some router in the net is buggy. */
5061 if (server->server_type != SILC_SERVER)
5064 /* We don't have that client anywhere, add it. The client is added
5065 to global list since server didn't have it in the lists so it must be
5067 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5068 silc_id_dup(&id.u.client_id,
5070 silc_packet_get_context(sock),
5073 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5077 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5079 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
5080 server->stat.clients + 1));
5081 server->stat.clients++;
5084 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5085 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5086 "%s", channel->channel_name));
5090 if (!silc_server_client_on_channel(client, channel, &chl)) {
5091 /* Client was not on the channel, add it. */
5092 chl = silc_calloc(1, sizeof(*chl));
5093 chl->client = client;
5095 chl->channel = channel;
5096 silc_hash_table_add(channel->user_list, chl->client, chl);
5097 silc_hash_table_add(client->channels, chl->channel, chl);
5098 channel->user_count++;
5106 /* Saves channels and channels user modes to the `client'. Removes
5107 the client from those channels that are not sent in the list but
5110 void silc_server_save_user_channels(SilcServer server,
5111 SilcPacketStream sock,
5112 SilcClientEntry client,
5113 SilcBuffer channels,
5114 SilcBuffer channels_user_modes)
5117 SilcUInt32 *chumodes;
5118 SilcChannelPayload entry;
5119 SilcChannelEntry channel;
5120 SilcChannelID channel_id;
5121 SilcChannelClientEntry chl;
5122 SilcHashTable ht = NULL;
5123 SilcHashTableList htl;
5127 if (!channels || !channels_user_modes ||
5128 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5131 ch = silc_channel_payload_parse_list(channels->data,
5132 silc_buffer_len(channels));
5133 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5135 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5136 NULL, NULL, NULL, TRUE);
5137 silc_dlist_start(ch);
5138 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5139 /* Check if we have this channel, and add it if we don't have it.
5140 Also add the client on the channel unless it is there already. */
5141 if (!silc_channel_get_id_parse(entry, &channel_id))
5143 channel = silc_idlist_find_channel_by_id(server->local_list,
5146 channel = silc_idlist_find_channel_by_id(server->global_list,
5149 if (server->server_type != SILC_SERVER) {
5154 /* We don't have that channel anywhere, add it. */
5155 name = silc_channel_get_name(entry, NULL);
5156 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5157 silc_id_dup(&channel_id,
5159 server->router, NULL, NULL, 0);
5166 channel->mode = silc_channel_get_mode(entry);
5168 /* Add the client on the channel */
5169 if (!silc_server_client_on_channel(client, channel, &chl)) {
5170 chl = silc_calloc(1, sizeof(*chl));
5171 chl->client = client;
5172 chl->mode = chumodes[i++];
5173 chl->channel = channel;
5174 silc_hash_table_add(channel->user_list, chl->client, chl);
5175 silc_hash_table_add(client->channels, chl->channel, chl);
5176 channel->user_count++;
5179 chl->mode = chumodes[i++];
5182 silc_hash_table_add(ht, channel, channel);
5184 silc_channel_payload_list_free(ch);
5185 silc_free(chumodes);
5189 /* Go through the list again and remove client from channels that
5190 are no part of the list. */
5192 silc_hash_table_list(client->channels, &htl);
5193 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5194 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5195 silc_hash_table_del(chl->channel->user_list, chl->client);
5196 silc_hash_table_del(chl->client->channels, chl->channel);
5200 silc_hash_table_list_reset(&htl);
5201 silc_hash_table_free(ht);
5203 silc_hash_table_list(client->channels, &htl);
5204 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5205 silc_hash_table_del(chl->channel->user_list, chl->client);
5206 silc_hash_table_del(chl->client->channels, chl->channel);
5209 silc_hash_table_list_reset(&htl);
5213 /* Lookups route to the client indicated by the `id_data'. The connection
5214 object and internal data object is returned. Returns NULL if route
5215 could not be found to the client. If the `client_id' is specified then
5216 it is used and the `id_data' is ignored. */
5219 silc_server_get_client_route(SilcServer server,
5220 unsigned char *id_data,
5222 SilcClientID *client_id,
5223 SilcIDListData *idata,
5224 SilcClientEntry *client_entry)
5226 SilcClientID *id, clid;
5227 SilcClientEntry client;
5229 SILC_LOG_DEBUG(("Start"));
5232 *client_entry = NULL;
5234 /* Decode destination Client ID */
5236 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5238 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5240 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5243 /* If the destination belongs to our server we don't have to route
5244 the packet anywhere but to send it to the local destination. */
5245 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5249 /* If we are router and the client has router then the client is in
5250 our cell but not directly connected to us. */
5251 if (server->server_type == SILC_ROUTER && client->router) {
5252 /* We are of course in this case the client's router thus the route
5253 to the client is the server who owns the client. So, we will send
5254 the packet to that server. */
5256 *idata = (SilcIDListData)client->router;
5257 return client->router->connection;
5260 /* Seems that client really is directly connected to us */
5262 *idata = (SilcIDListData)client;
5264 *client_entry = client;
5265 return client->connection;
5268 /* Destination belongs to someone not in this server. If we are normal
5269 server our action is to send the packet to our router. */
5270 if (server->server_type != SILC_ROUTER && !server->standalone) {
5273 *idata = (SilcIDListData)server->router;
5274 return SILC_PRIMARY_ROUTE(server);
5277 /* We are router and we will perform route lookup for the destination
5278 and send the packet to fastest route. */
5279 if (server->server_type == SILC_ROUTER && !server->standalone) {
5280 /* Check first that the ID is valid */
5281 client = silc_idlist_find_client_by_id(server->global_list, id,
5284 SilcPacketStream dst_sock;
5286 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5289 if (idata && dst_sock)
5290 *idata = silc_packet_get_context(dst_sock);
5299 /* Encodes and returns channel list of channels the `client' has joined.
5300 Secret channels are not put to the list. */
5302 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5303 SilcClientEntry client,
5304 SilcBool get_private,
5305 SilcBool get_secret,
5306 SilcBuffer *user_mode_list)
5308 SilcBuffer buffer = NULL;
5309 SilcChannelEntry channel;
5310 SilcChannelClientEntry chl;
5311 SilcHashTableList htl;
5312 unsigned char cid[32];
5314 SilcUInt16 name_len;
5318 *user_mode_list = NULL;
5320 silc_hash_table_list(client->channels, &htl);
5321 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5322 channel = chl->channel;
5324 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5326 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5329 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5330 name_len = strlen(channel->channel_name);
5332 len = 4 + name_len + id_len + 4;
5333 buffer = silc_buffer_realloc(buffer,
5335 silc_buffer_truelen(buffer) + len : len));
5336 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5337 silc_buffer_format(buffer,
5338 SILC_STR_UI_SHORT(name_len),
5339 SILC_STR_DATA(channel->channel_name, name_len),
5340 SILC_STR_UI_SHORT(id_len),
5341 SILC_STR_DATA(cid, id_len),
5342 SILC_STR_UI_INT(chl->channel->mode),
5344 silc_buffer_pull(buffer, len);
5346 if (user_mode_list) {
5348 silc_buffer_realloc(*user_mode_list,
5350 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5351 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5352 (*user_mode_list)->data));
5353 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5354 silc_buffer_pull(*user_mode_list, 4);
5357 silc_hash_table_list_reset(&htl);
5360 silc_buffer_push(buffer, buffer->data - buffer->head);
5361 if (user_mode_list && *user_mode_list)
5362 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5363 (*user_mode_list)->head));
5368 /* Task callback used to retrieve network statistical information from
5369 router server once in a while. */
5371 SILC_TASK_CALLBACK(silc_server_get_stats)
5373 SilcServer server = (SilcServer)context;
5374 SilcBuffer idp, packet;
5376 if (!server->standalone) {
5377 SILC_LOG_DEBUG(("Retrieving stats from router"));
5378 server->stat.commands_sent++;
5379 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5381 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5382 ++server->cmd_ident, 1,
5384 silc_buffer_len(idp));
5385 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5386 SILC_PACKET_COMMAND, 0, packet->data,
5387 silc_buffer_len(packet));
5388 silc_buffer_free(packet);
5389 silc_buffer_free(idp);
5393 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,