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_PKCS_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 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2407 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2409 /* If we are backup router and this is incoming server connection
2410 and we do not have connection to primary router, do not allow
2412 if (server->server_type == SILC_BACKUP_ROUTER &&
2413 entry->conn_type == SILC_CONN_SERVER &&
2414 !SILC_PRIMARY_ROUTE(server)) {
2415 SILC_LOG_INFO(("Will not accept server connection because we do "
2416 "not have primary router connection established"));
2417 silc_server_disconnect_remote(server, sock,
2418 SILC_STATUS_ERR_PERM_DENIED,
2419 "We do not have connection to primary "
2420 "router established, try later");
2421 silc_server_config_unref(&entry->cconfig);
2422 silc_server_config_unref(&entry->sconfig);
2423 silc_server_config_unref(&entry->rconfig);
2424 silc_server_free_sock_user_data(server, sock, NULL);
2425 server->stat.auth_failures++;
2429 if (entry->conn_type == SILC_CONN_ROUTER) {
2430 /* Verify whether this connection is after all allowed to connect */
2431 if (!silc_server_connection_allowed(server, sock,
2433 &server->config->param,
2434 rconn ? rconn->param : NULL,
2435 silc_connauth_get_ske(connauth))) {
2436 silc_server_config_unref(&entry->cconfig);
2437 silc_server_config_unref(&entry->sconfig);
2438 silc_server_config_unref(&entry->rconfig);
2439 server->stat.auth_failures++;
2445 param = rconn->param;
2447 if (!param->keepalive_secs)
2448 param->keepalive_secs = server->config->param.keepalive_secs;
2450 if (!param->qos && server->config->param.qos) {
2451 param->qos = server->config->param.qos;
2452 param->qos_rate_limit = server->config->param.qos_rate_limit;
2453 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2454 param->qos_limit_sec = server->config->param.qos_limit_sec;
2455 param->qos_limit_usec = server->config->param.qos_limit_usec;
2459 initiator = rconn->initiator;
2460 backup_local = rconn->backup_local;
2461 backup_router = rconn->backup_router;
2465 if (entry->conn_type == SILC_CONN_SERVER) {
2466 /* Verify whether this connection is after all allowed to connect */
2467 if (!silc_server_connection_allowed(server, sock,
2469 &server->config->param,
2470 srvconn ? srvconn->param : NULL,
2471 silc_connauth_get_ske(connauth))) {
2472 server->stat.auth_failures++;
2476 if (srvconn->param) {
2477 param = srvconn->param;
2479 if (!param->keepalive_secs)
2480 param->keepalive_secs = server->config->param.keepalive_secs;
2482 if (!param->qos && server->config->param.qos) {
2483 param->qos = server->config->param.qos;
2484 param->qos_rate_limit = server->config->param.qos_rate_limit;
2485 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2486 param->qos_limit_sec = server->config->param.qos_limit_sec;
2487 param->qos_limit_usec = server->config->param.qos_limit_usec;
2491 backup_router = srvconn->backup_router;
2495 /* If we are primary router and we have backup router configured
2496 but it has not connected to use yet, do not accept any other
2498 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2499 !server->backup_router && !backup_router) {
2500 SilcServerConfigRouter *router;
2501 router = silc_server_config_get_backup_router(server);
2502 if (router && strcmp(server->config->server_info->primary->server_ip,
2504 silc_server_find_socket_by_host(server,
2506 router->backup_replace_ip, 0)) {
2507 SILC_LOG_INFO(("Will not accept connections because we do "
2508 "not have backup router connection established"));
2509 silc_server_disconnect_remote(server, sock,
2510 SILC_STATUS_ERR_PERM_DENIED,
2511 "We do not have connection to backup "
2512 "router established, try later");
2513 silc_server_config_unref(&entry->cconfig);
2514 silc_server_config_unref(&entry->sconfig);
2515 silc_server_config_unref(&entry->rconfig);
2516 silc_server_free_sock_user_data(server, sock, NULL);
2517 server->stat.auth_failures++;
2519 /* From here on, wait 20 seconds for the backup router to appear. */
2520 silc_schedule_task_add_timeout(server->schedule,
2521 silc_server_backup_router_wait,
2522 (void *)server, 20, 0);
2527 SILC_LOG_DEBUG(("Remote host is %s",
2528 entry->conn_type == SILC_CONN_SERVER ?
2529 "server" : (backup_router ?
2530 "backup router" : "router")));
2531 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2532 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2533 "server" : (backup_router ?
2534 "backup router" : "router")));
2536 /* Add the server into server cache. The server name and Server ID
2537 is updated after we have received NEW_SERVER packet from the
2538 server. We mark ourselves as router for this server if we really
2541 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2542 server->local_list : (backup_router ?
2543 server->local_list :
2544 server->global_list)),
2546 (entry->conn_type == SILC_CONN_SERVER ?
2547 SILC_SERVER : SILC_ROUTER),
2549 (entry->conn_type == SILC_CONN_SERVER ?
2550 server->id_entry : (backup_router ?
2551 server->id_entry : NULL)),
2554 SILC_LOG_ERROR(("Could not add new server to cache"));
2555 silc_server_disconnect_remote(server, sock,
2556 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2557 silc_server_config_unref(&entry->cconfig);
2558 silc_server_config_unref(&entry->sconfig);
2559 silc_server_config_unref(&entry->rconfig);
2560 silc_server_free_sock_user_data(server, sock, NULL);
2561 server->stat.auth_failures++;
2564 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2565 entry->data.conn_type = entry->conn_type;
2567 id_entry = (void *)new_server;
2569 /* If the incoming connection is router and marked as backup router
2570 then add it to be one of our backups */
2571 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2572 /* Change it back to SERVER type since that's what it really is. */
2574 entry->data.conn_type = SILC_CONN_SERVER;
2575 new_server->server_type = SILC_BACKUP_ROUTER;
2577 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2578 ("Backup router %s is now online",
2581 /* Remove the backup waiting with timeout */
2582 silc_schedule_task_add_timeout(server->schedule,
2583 silc_server_backup_router_wait,
2584 (void *)server, 10, 0);
2588 if (entry->data.conn_type == SILC_CONN_SERVER) {
2589 server->stat.my_servers++;
2590 server->stat.servers++;
2591 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2593 server->stat.my_routers++;
2594 server->stat.routers++;
2595 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2598 /* Check whether this connection is to be our primary router connection
2599 if we do not already have the primary route. */
2600 if (!backup_router &&
2601 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2602 if (silc_server_config_is_primary_route(server) && !initiator)
2605 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2606 server->standalone = FALSE;
2607 if (!server->id_entry->router) {
2608 server->id_entry->router = id_entry;
2609 server->router = id_entry;
2621 /* Add connection to server->conns so that we know we have connection
2623 sconn = silc_calloc(1, sizeof(*sconn));
2626 sconn->server = server;
2628 sconn->remote_host = strdup(hostname);
2629 sconn->remote_port = port;
2630 silc_dlist_add(server->conns, sconn);
2631 idata->sconn = sconn;
2632 idata->sconn->callback = NULL;
2633 idata->last_receive = time(NULL);
2635 /* Add the common data structure to the ID entry. */
2636 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2637 silc_packet_set_context(sock, id_entry);
2639 /* Connection has been fully established now. Everything is ok. */
2640 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2642 /* Perform Quality of Service */
2644 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2645 param->qos_rate_limit, param->qos_bytes_limit,
2646 param->qos_limit_sec, param->qos_limit_usec);
2648 /* Perform heartbeat */
2649 if (param->keepalive_secs) {
2650 SILC_LOG_DEBUG(("Perform heartbeat every %d seconds",
2651 param->keepalive_secs));
2652 silc_schedule_task_add_timeout(server->schedule, silc_server_do_heartbeat,
2653 sock, param->keepalive_secs, 0);
2656 silc_server_config_unref(&entry->cconfig);
2657 silc_server_config_unref(&entry->sconfig);
2658 silc_server_config_unref(&entry->rconfig);
2662 silc_ske_free(silc_connauth_get_ske(connauth));
2663 silc_connauth_free(connauth);
2666 /* SKE completion callback. We set the new keys into use here. */
2669 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2670 SilcSKESecurityProperties prop,
2671 SilcSKEKeyMaterial keymat,
2672 SilcSKERekeyMaterial rekey,
2675 SilcPacketStream sock = context;
2676 SilcUnknownEntry entry = silc_packet_get_context(sock);
2677 SilcIDListData idata = (SilcIDListData)entry;
2678 SilcServer server = entry->server;
2679 SilcConnAuth connauth;
2680 SilcCipher send_key, receive_key;
2681 SilcHmac hmac_send, hmac_receive;
2688 if (status != SILC_SKE_STATUS_OK) {
2690 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2691 silc_ske_map_status(status), entry->hostname, entry->ip));
2693 silc_server_disconnect_remote(server, sock,
2694 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2695 silc_server_config_unref(&entry->cconfig);
2696 silc_server_config_unref(&entry->sconfig);
2697 silc_server_config_unref(&entry->rconfig);
2698 silc_server_free_sock_user_data(server, sock, NULL);
2702 SILC_LOG_DEBUG(("Setting keys into use"));
2704 /* Set the keys into use. The data will be encrypted after this. */
2705 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2706 &hmac_send, &hmac_receive, &hash)) {
2707 /* Error setting keys */
2709 silc_server_disconnect_remote(server, sock,
2710 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2711 silc_server_free_sock_user_data(server, sock, NULL);
2714 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2715 hmac_receive, FALSE);
2717 idata->rekey = rekey;
2718 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2719 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2721 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2726 SILC_LOG_DEBUG(("Starting connection authentication"));
2727 server->stat.auth_attempts++;
2729 connauth = silc_connauth_alloc(server->schedule, ske,
2730 server->config->conn_auth_timeout);
2732 /** Error allocating auth protocol */
2734 silc_server_disconnect_remote(server, sock,
2735 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2736 silc_server_config_unref(&entry->cconfig);
2737 silc_server_config_unref(&entry->sconfig);
2738 silc_server_config_unref(&entry->rconfig);
2739 silc_server_free_sock_user_data(server, sock, NULL);
2743 /* Start connection authentication */
2745 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2746 silc_server_accept_auth_compl, sock);
2749 /* Accept new TCP connection */
2751 static void silc_server_accept_new_connection(SilcNetStatus status,
2755 SilcServer server = context;
2756 SilcPacketStream packet_stream;
2757 SilcServerConfigClient *cconfig = NULL;
2758 SilcServerConfigServer *sconfig = NULL;
2759 SilcServerConfigRouter *rconfig = NULL;
2760 SilcServerConfigDeny *deny;
2761 SilcUnknownEntry entry;
2763 SilcSKEParamsStruct params;
2764 char *hostname, *ip;
2767 SILC_LOG_DEBUG(("Accepting new connection"));
2769 /* Check for maximum allowed connections */
2770 server->stat.conn_attempts++;
2771 if (silc_dlist_count(server->conns) >
2772 server->config->param.connections_max) {
2773 SILC_LOG_ERROR(("Refusing connection, server is full"));
2774 server->stat.conn_failures++;
2775 silc_stream_destroy(stream);
2779 /* Get hostname, IP and port */
2780 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2781 (const char **)&ip, &port)) {
2782 /* Bad socket stream */
2783 server->stat.conn_failures++;
2784 silc_stream_destroy(stream);
2788 /* Create packet stream */
2789 packet_stream = silc_packet_stream_create(server->packet_engine,
2790 server->schedule, stream);
2791 if (!packet_stream) {
2792 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2793 server->stat.conn_failures++;
2794 silc_stream_destroy(stream);
2797 server->stat.conn_num++;
2799 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2801 /* Set source ID to packet stream */
2802 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2805 server->stat.conn_failures++;
2806 silc_packet_stream_destroy(packet_stream);
2810 /* Check whether this connection is denied to connect to us. */
2811 deny = silc_server_config_find_denied(server, ip);
2813 deny = silc_server_config_find_denied(server, hostname);
2815 /* The connection is denied */
2816 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2817 silc_server_disconnect_remote(server, packet_stream,
2818 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2820 silc_server_free_sock_user_data(server, packet_stream, NULL);
2824 /* Check whether we have configured this sort of connection at all. We
2825 have to check all configurations since we don't know what type of
2826 connection this is. */
2827 if (!(cconfig = silc_server_config_find_client(server, ip)))
2828 cconfig = silc_server_config_find_client(server, hostname);
2829 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2830 sconfig = silc_server_config_find_server_conn(server, hostname);
2831 if (server->server_type == SILC_ROUTER)
2832 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2833 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2834 if (!cconfig && !sconfig && !rconfig) {
2835 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2836 server->stat.conn_failures++;
2837 silc_server_disconnect_remote(server, packet_stream,
2838 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2839 silc_server_free_sock_user_data(server, packet_stream, NULL);
2843 /* The connection is allowed */
2844 entry = silc_calloc(1, sizeof(*entry));
2846 server->stat.conn_failures++;
2847 silc_server_disconnect_remote(server, packet_stream,
2848 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2849 silc_server_free_sock_user_data(server, packet_stream, NULL);
2852 entry->hostname = hostname;
2855 entry->server = server;
2856 entry->data.conn_type = SILC_CONN_UNKNOWN;
2857 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2858 silc_packet_set_context(packet_stream, entry);
2860 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2862 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2863 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2864 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2866 /* Take flags for key exchange. Since we do not know what type of connection
2867 this is, we go through all found configurations and use the global ones
2868 as well. This will result always into strictest key exchange flags. */
2869 memset(¶ms, 0, sizeof(params));
2870 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2871 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2872 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2873 if (server->config->param.key_exchange_pfs)
2874 params.flags |= SILC_SKE_SP_FLAG_PFS;
2876 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2877 server->stat.conn_attempts++;
2879 /* Start SILC Key Exchange protocol */
2880 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2881 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2882 server->public_key, server->private_key,
2885 server->stat.conn_failures++;
2886 silc_server_disconnect_remote(server, packet_stream,
2887 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2888 silc_server_free_sock_user_data(server, packet_stream, NULL);
2891 silc_ske_set_callbacks(ske, silc_server_verify_key,
2892 silc_server_accept_completed, packet_stream);
2894 /* Start key exchange protocol */
2895 params.version = silc_version_string;
2896 params.timeout_secs = server->config->key_exchange_timeout;
2897 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2900 /* Perform heartbeat */
2902 SILC_TASK_CALLBACK(silc_server_do_heartbeat)
2904 SilcServer server = app_context;
2905 SilcPacketStream sock = context;
2906 silc_server_send_heartbeat(server, sock);
2910 /********************************** Rekey ***********************************/
2912 /* Initiator rekey completion callback */
2914 static void silc_server_rekey_completion(SilcSKE ske,
2915 SilcSKEStatus status,
2916 const SilcSKESecurityProperties prop,
2917 const SilcSKEKeyMaterial keymat,
2918 SilcSKERekeyMaterial rekey,
2921 SilcPacketStream sock = context;
2922 SilcIDListData idata = silc_packet_get_context(sock);
2923 SilcServer server = idata->sconn->server;
2925 idata->sconn->op = NULL;
2926 if (status != SILC_SKE_STATUS_OK) {
2927 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2928 idata->sconn->remote_host));
2932 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2933 idata->sconn->remote_host, idata->sconn->remote_port,
2934 SILC_CONNTYPE_STRING(idata->conn_type)));
2936 /* Save rekey data for next rekey */
2937 idata->rekey = rekey;
2939 /* Register new rekey timeout */
2940 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2941 sock, idata->sconn->rekey_timeout, 0);
2944 /* Helper to stop future rekeys on a link. */
2945 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2947 if (!client->connection)
2950 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2952 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2953 client->connection);
2956 /* Rekey callback. Start rekey as initiator */
2958 SILC_TASK_CALLBACK(silc_server_do_rekey)
2960 SilcServer server = app_context;
2961 SilcPacketStream sock = context;
2962 SilcIDListData idata = silc_packet_get_context(sock);
2965 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2967 /* Do not execute rekey with disabled connections */
2968 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2971 /* If another protocol is active do not start rekey */
2972 if (idata->sconn->op) {
2973 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2974 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2979 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2980 idata->sconn->remote_host, idata->sconn->remote_port,
2981 SILC_CONNTYPE_STRING(idata->conn_type)));
2984 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2985 server->public_key, NULL, sock);
2989 /* Set SKE callbacks */
2990 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2993 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2996 /* Responder rekey completion callback */
2999 silc_server_rekey_resp_completion(SilcSKE ske,
3000 SilcSKEStatus status,
3001 const SilcSKESecurityProperties prop,
3002 const SilcSKEKeyMaterial keymat,
3003 SilcSKERekeyMaterial rekey,
3006 SilcPacketStream sock = context;
3007 SilcIDListData idata = silc_packet_get_context(sock);
3009 idata->sconn->op = NULL;
3010 if (status != SILC_SKE_STATUS_OK) {
3011 SILC_LOG_ERROR(("Error during rekey protocol with %s",
3012 idata->sconn->remote_host));
3016 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
3017 idata->sconn->remote_host, idata->sconn->remote_port,
3018 SILC_CONNTYPE_STRING(idata->conn_type)));
3020 /* Save rekey data for next rekey */
3021 idata->rekey = rekey;
3024 /* Start rekey as responder */
3026 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
3029 SilcIDListData idata = silc_packet_get_context(sock);
3032 if (!idata->rekey) {
3033 silc_packet_free(packet);
3036 if (idata->conn_type == SILC_CONN_UNKNOWN) {
3037 silc_packet_free(packet);
3041 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3042 idata->sconn->remote_host, idata->sconn->remote_port,
3043 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3046 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3047 server->public_key, NULL, sock);
3049 silc_packet_free(packet);
3053 /* Set SKE callbacks */
3054 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3057 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3062 /****************************** Disconnection *******************************/
3064 /* Destroys packet stream. */
3066 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3068 silc_packet_stream_unref(context);
3071 /* Closes connection to socket connection */
3073 void silc_server_close_connection(SilcServer server,
3074 SilcPacketStream sock)
3076 SilcIDListData idata = silc_packet_get_context(sock);
3078 const char *hostname;
3081 if (!silc_packet_stream_is_valid(sock))
3084 memset(tmp, 0, sizeof(tmp));
3085 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3086 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3087 NULL, &hostname, NULL, &port);
3088 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3089 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3090 tmp[0] ? tmp : ""));
3092 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3094 if (idata && idata->sconn) {
3095 silc_server_connection_free(idata->sconn);
3096 idata->sconn = NULL;
3099 /* Take a reference and then destroy the stream. The last reference
3100 is released later in a timeout callback. */
3101 silc_packet_stream_ref(sock);
3102 silc_packet_stream_destroy(sock);
3104 /* Close connection with timeout */
3105 server->stat.conn_num--;
3106 silc_schedule_task_del_by_all(server->schedule, 0,
3107 silc_server_close_connection_final, sock);
3108 silc_schedule_task_add_timeout(server->schedule,
3109 silc_server_close_connection_final,
3113 /* Sends disconnect message to remote connection and disconnects the
3116 void silc_server_disconnect_remote(SilcServer server,
3117 SilcPacketStream sock,
3118 SilcStatus status, ...)
3120 unsigned char buf[512];
3127 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3129 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_heartbeat,
3132 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p, status %d", sock,
3135 va_start(ap, status);
3136 cp = va_arg(ap, char *);
3138 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3141 /* Send SILC_PACKET_DISCONNECT */
3142 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3143 SILC_STR_UI_CHAR(status),
3144 SILC_STR_UI8_STRING(cp ? buf : NULL),
3147 /* Close connection */
3148 silc_server_close_connection(server, sock);
3151 /* Frees client data and notifies about client's signoff. */
3153 void silc_server_free_client_data(SilcServer server,
3154 SilcPacketStream sock,
3155 SilcClientEntry client,
3157 const char *signoff)
3159 SILC_LOG_DEBUG(("Freeing client %p data", client));
3162 /* Check if anyone is watching this nickname */
3163 if (server->server_type == SILC_ROUTER)
3164 silc_server_check_watcher_list(server, client, NULL,
3165 SILC_NOTIFY_TYPE_SIGNOFF);
3167 /* Send SIGNOFF notify to routers. */
3169 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3170 SILC_BROADCAST(server), client->id,
3174 /* Remove client from all channels */
3176 silc_server_remove_from_channels(server, NULL, client,
3177 TRUE, (char *)signoff, TRUE, FALSE);
3179 silc_server_remove_from_channels(server, NULL, client,
3180 FALSE, NULL, FALSE, FALSE);
3182 /* Remove this client from watcher list if it is */
3183 silc_server_del_from_watcher_list(server, client);
3185 /* Remove client's public key from repository, this will free it too. */
3186 if (client->data.public_key) {
3187 silc_skr_del_public_key(server->repository, client->data.public_key,
3189 client->data.public_key = NULL;
3192 /* Update statistics */
3194 /* Local detached clients aren't counted. */
3195 if (!client->local_detached)
3196 server->stat.my_clients--;
3197 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3198 server->stat.clients - 1));
3199 SILC_VERIFY(server->stat.clients > 0);
3200 server->stat.clients--;
3201 if (server->stat.cell_clients)
3202 server->stat.cell_clients--;
3203 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3204 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3205 silc_schedule_task_del_by_context(server->schedule, client);
3207 if (client->data.sconn) {
3208 silc_server_connection_free(client->data.sconn);
3209 client->data.sconn = NULL;
3212 /* We will not delete the client entry right away. We will take it
3213 into history (for WHOWAS command) for 5 minutes, unless we're
3214 shutting down server. */
3215 if (!server->server_shutdown) {
3216 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3218 client->router = NULL;
3219 client->connection = NULL;
3220 client->data.created = silc_time();
3221 silc_dlist_del(server->expired_clients, client);
3222 silc_dlist_add(server->expired_clients, client);
3224 /* Delete directly since we're shutting down server */
3225 SILC_LOG_DEBUG(("Delete client directly"));
3226 silc_idlist_del_data(client);
3227 silc_idlist_del_client(server->local_list, client);
3231 /* Frees user_data pointer from socket connection object. This also sends
3232 appropriate notify packets to the network to inform about leaving
3235 void silc_server_free_sock_user_data(SilcServer server,
3236 SilcPacketStream sock,
3237 const char *signoff_message)
3239 SilcIDListData idata;
3246 SILC_LOG_DEBUG(("Start, sock %p", sock));
3248 idata = silc_packet_get_context(sock);
3252 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3254 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_heartbeat,
3257 /* Cancel active protocols */
3259 if (idata->sconn && idata->sconn->op) {
3260 SILC_LOG_DEBUG(("Abort active protocol"));
3261 silc_async_abort(idata->sconn->op, NULL, NULL);
3262 idata->sconn->op = NULL;
3264 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3265 ((SilcUnknownEntry)idata)->op) {
3266 SILC_LOG_DEBUG(("Abort active protocol"));
3267 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3268 ((SilcUnknownEntry)idata)->op = NULL;
3272 switch (idata->conn_type) {
3273 case SILC_CONN_CLIENT:
3275 SilcClientEntry client_entry = (SilcClientEntry)idata;
3276 silc_server_free_client_data(server, sock, client_entry, TRUE,
3278 silc_packet_set_context(sock, NULL);
3282 case SILC_CONN_SERVER:
3283 case SILC_CONN_ROUTER:
3285 SilcServerEntry user_data = (SilcServerEntry)idata;
3286 SilcServerEntry backup_router = NULL;
3288 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3291 backup_router = silc_server_backup_get(server, user_data->id);
3293 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3294 backup_router == server->id_entry &&
3295 idata->conn_type != SILC_CONN_ROUTER)
3296 backup_router = NULL;
3298 if (server->server_shutdown || server->backup_noswitch)
3299 backup_router = NULL;
3301 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3302 NULL, NULL, &ip, &port);
3304 /* If this was our primary router connection then we're lost to
3305 the outside world. */
3306 if (server->router == user_data) {
3307 /* Check whether we have a backup router connection */
3308 if (!backup_router || backup_router == user_data) {
3309 if (!server->no_reconnect)
3310 silc_server_create_connections(server);
3311 server->id_entry->router = NULL;
3312 server->router = NULL;
3313 server->standalone = TRUE;
3314 server->backup_primary = FALSE;
3315 backup_router = NULL;
3317 if (server->id_entry != backup_router) {
3318 SILC_LOG_INFO(("New primary router is backup router %s",
3319 backup_router->server_name));
3320 server->id_entry->router = backup_router;
3321 server->router = backup_router;
3322 server->router_connect = time(0);
3323 server->backup_primary = TRUE;
3324 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3326 /* Send START_USE to backup router to indicate we have switched */
3327 silc_server_backup_send_start_use(server,
3328 backup_router->connection,
3331 SILC_LOG_INFO(("We are now new primary router in this cell"));
3332 server->id_entry->router = NULL;
3333 server->router = NULL;
3334 server->standalone = TRUE;
3337 /* We stop here to take a breath */
3340 if (server->backup_router) {
3341 server->server_type = SILC_ROUTER;
3343 /* We'll need to constantly try to reconnect to the primary
3344 router so that we'll see when it comes back online. */
3345 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3346 silc_server_backup_connected,
3350 /* Mark this connection as replaced */
3351 silc_server_backup_replaced_add(server, user_data->id,
3354 } else if (backup_router) {
3355 SILC_LOG_INFO(("Enabling the use of backup router %s",
3356 backup_router->server_name));
3358 /* Mark this connection as replaced */
3359 silc_server_backup_replaced_add(server, user_data->id,
3361 } else if (server->server_type == SILC_SERVER &&
3362 idata->conn_type == SILC_CONN_ROUTER) {
3363 /* Reconnect to the router (backup) */
3364 if (!server->no_reconnect)
3365 silc_server_create_connections(server);
3368 if (user_data->server_name)
3369 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3370 ("Server %s signoff", user_data->server_name));
3372 if (!backup_router) {
3373 /* Remove all servers that are originated from this server, and
3374 remove the clients of those servers too. */
3375 silc_server_remove_servers_by_server(server, user_data, TRUE);
3378 /* Remove the clients that this server owns as they will become
3379 invalid now too. For backup router the server is actually
3380 coming from the primary router, so mark that as the owner
3382 if (server->server_type == SILC_BACKUP_ROUTER &&
3383 sock->type == SILC_CONN_SERVER)
3384 silc_server_remove_clients_by_server(server, server->router,
3388 silc_server_remove_clients_by_server(server, user_data,
3391 /* Remove channels owned by this server */
3392 if (server->server_type == SILC_SERVER)
3393 silc_server_remove_channels_by_server(server, user_data);
3395 /* Enable local server connections that may be disabled */
3396 silc_server_local_servers_toggle_enabled(server, TRUE);
3398 /* Update the client entries of this server to the new backup
3399 router. If we are the backup router we also resolve the real
3400 servers for the clients. After updating is over this also
3401 removes the clients that this server explicitly owns. */
3402 silc_server_update_clients_by_server(server, user_data,
3403 backup_router, TRUE);
3405 /* If we are router and just lost our primary router (now standlaone)
3406 we remove everything that was behind it, since we don't know
3408 if (server->server_type == SILC_ROUTER && server->standalone)
3409 /* Remove all servers that are originated from this server, and
3410 remove the clients of those servers too. */
3411 silc_server_remove_servers_by_server(server, user_data, TRUE);
3413 /* Finally remove the clients that are explicitly owned by this
3414 server. They go down with the server. */
3415 silc_server_remove_clients_by_server(server, user_data,
3418 /* Update our server cache to use the new backup router too. */
3419 silc_server_update_servers_by_server(server, user_data, backup_router);
3420 if (server->server_type == SILC_SERVER)
3421 silc_server_update_channels_by_server(server, user_data,
3424 /* Send notify about primary router going down to local operators */
3425 if (server->backup_router)
3426 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3427 SILC_NOTIFY_TYPE_NONE,
3428 ("%s switched to backup router %s "
3429 "(we are primary router now)",
3430 server->server_name, server->server_name));
3431 else if (server->router)
3432 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3433 SILC_NOTIFY_TYPE_NONE,
3434 ("%s switched to backup router %s",
3435 server->server_name,
3436 server->router->server_name));
3438 server->backup_noswitch = FALSE;
3441 silc_server_connection_free(idata->sconn);
3442 idata->sconn = NULL;
3446 if (idata->conn_type == SILC_CONN_SERVER) {
3447 server->stat.my_servers--;
3448 server->stat.servers--;
3449 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3450 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3451 server->stat.my_routers--;
3452 server->stat.routers--;
3453 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3455 if (server->server_type == SILC_ROUTER)
3456 server->stat.cell_servers--;
3458 /* Free the server entry */
3459 silc_server_backup_del(server, user_data);
3460 silc_server_backup_replaced_del(server, user_data);
3461 silc_idlist_del_data(user_data);
3462 if (!silc_idlist_del_server(server->local_list, user_data))
3463 silc_idlist_del_server(server->global_list, user_data);
3465 if (backup_router && backup_router != server->id_entry) {
3466 /* Announce all of our stuff that was created about 5 minutes ago.
3467 The backup router knows all the other stuff already. */
3468 if (server->server_type == SILC_ROUTER)
3469 silc_server_announce_servers(server, FALSE, time(0) - 300,
3470 backup_router->connection);
3472 /* Announce our clients and channels to the router */
3473 silc_server_announce_clients(server, time(0) - 300,
3474 backup_router->connection);
3475 silc_server_announce_channels(server, time(0) - 300,
3476 backup_router->connection);
3479 silc_packet_set_context(sock, NULL);
3485 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3487 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3490 if (server->router_conn == idata->sconn) {
3491 if (!server->no_reconnect)
3492 silc_server_create_connections(server);
3493 server->router_conn = NULL;
3496 silc_server_connection_free(idata->sconn);
3497 idata->sconn = NULL;
3499 silc_idlist_del_data(idata);
3501 silc_packet_set_context(sock, NULL);
3507 /* Removes client from all channels it has joined. This is used when client
3508 connection is disconnected. If the client on a channel is last, the
3509 channel is removed as well. This sends the SIGNOFF notify types. */
3511 void silc_server_remove_from_channels(SilcServer server,
3512 SilcPacketStream sock,
3513 SilcClientEntry client,
3515 const char *signoff_message,
3519 SilcChannelEntry channel;
3520 SilcChannelClientEntry chl;
3521 SilcHashTableList htl;
3522 SilcBuffer clidp = NULL;
3527 if (notify && !client->id)
3530 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3531 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3534 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3539 /* Remove the client from all channels. The client is removed from
3540 the channels' user list. */
3541 silc_hash_table_list(client->channels, &htl);
3542 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3543 channel = chl->channel;
3545 /* Remove channel if this is last client leaving the channel, unless
3546 the channel is permanent. */
3547 if (server->server_type != SILC_SERVER &&
3548 silc_hash_table_count(channel->user_list) < 2) {
3549 silc_server_channel_delete(server, channel);
3553 silc_hash_table_del(client->channels, channel);
3554 silc_hash_table_del(channel->user_list, client);
3555 channel->user_count--;
3557 /* If there is no global users on the channel anymore mark the channel
3558 as local channel. Do not check if the removed client is local client. */
3559 if (server->server_type == SILC_SERVER && channel->global_users &&
3560 chl->client->router && !silc_server_channel_has_global(channel))
3561 channel->global_users = FALSE;
3563 memset(chl, 'A', sizeof(*chl));
3566 /* Update statistics */
3567 if (SILC_IS_LOCAL(client))
3568 server->stat.my_chanclients--;
3569 if (server->server_type == SILC_ROUTER) {
3570 server->stat.cell_chanclients--;
3571 server->stat.chanclients--;
3574 /* If there is not at least one local user on the channel then we don't
3575 need the channel entry anymore, we can remove it safely, unless the
3576 channel is permanent channel */
3577 if (server->server_type == SILC_SERVER &&
3578 !silc_server_channel_has_local(channel)) {
3579 /* Notify about leaving client if this channel has global users. */
3580 if (notify && channel->global_users)
3581 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3582 SILC_NOTIFY_TYPE_SIGNOFF,
3583 signoff_message ? 2 : 1,
3584 clidp->data, silc_buffer_len(clidp),
3585 signoff_message, signoff_message ?
3586 strlen(signoff_message) : 0);
3588 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3589 silc_server_channel_delete(server, channel);
3593 /* Send notify to channel about client leaving SILC and channel too */
3595 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3596 SILC_NOTIFY_TYPE_SIGNOFF,
3597 signoff_message ? 2 : 1,
3598 clidp->data, silc_buffer_len(clidp),
3599 signoff_message, signoff_message ?
3600 strlen(signoff_message) : 0);
3602 if (killed && clidp) {
3603 /* Remove the client from channel's invite list */
3604 if (channel->invite_list &&
3605 silc_hash_table_count(channel->invite_list)) {
3607 SilcArgumentPayload iargs;
3608 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3609 silc_buffer_len(clidp), 3);
3610 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3611 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3612 silc_buffer_free(ab);
3613 silc_argument_payload_free(iargs);
3617 /* Don't create keys if we are shutting down */
3618 if (server->server_shutdown)
3621 /* Re-generate channel key if needed */
3622 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3623 if (!silc_server_create_channel_key(server, channel, 0))
3626 /* Send the channel key to the channel. The key of course is not sent
3627 to the client who was removed from the channel. */
3628 silc_server_send_channel_key(server, client->connection, channel,
3629 server->server_type == SILC_ROUTER ?
3630 FALSE : !server->standalone);
3634 silc_hash_table_list_reset(&htl);
3636 silc_buffer_free(clidp);
3639 /* Removes client from one channel. This is used for example when client
3640 calls LEAVE command to remove itself from the channel. Returns TRUE
3641 if channel still exists and FALSE if the channel is removed when
3642 last client leaves the channel. If `notify' is FALSE notify messages
3645 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3646 SilcPacketStream sock,
3647 SilcChannelEntry channel,
3648 SilcClientEntry client,
3651 SilcChannelClientEntry chl;
3654 SILC_LOG_DEBUG(("Removing %s from channel %s",
3655 silc_id_render(client->id, SILC_ID_CLIENT),
3656 channel->channel_name));
3658 /* Get the entry to the channel, if this client is not on the channel
3660 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3663 /* Remove channel if this is last client leaving the channel, unless
3664 the channel is permanent. */
3665 if (server->server_type != SILC_SERVER &&
3666 silc_hash_table_count(channel->user_list) < 2) {
3667 silc_server_channel_delete(server, channel);
3671 silc_hash_table_del(client->channels, channel);
3672 silc_hash_table_del(channel->user_list, client);
3673 channel->user_count--;
3675 /* If there is no global users on the channel anymore mark the channel
3676 as local channel. Do not check if the client is local client. */
3677 if (server->server_type == SILC_SERVER && channel->global_users &&
3678 chl->client->router && !silc_server_channel_has_global(channel))
3679 channel->global_users = FALSE;
3681 memset(chl, 'O', sizeof(*chl));
3684 /* Update statistics */
3685 if (SILC_IS_LOCAL(client))
3686 server->stat.my_chanclients--;
3687 if (server->server_type == SILC_ROUTER) {
3688 server->stat.cell_chanclients--;
3689 server->stat.chanclients--;
3692 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3696 /* If there is not at least one local user on the channel then we don't
3697 need the channel entry anymore, we can remove it safely, unless the
3698 channel is permanent channel */
3699 if (server->server_type == SILC_SERVER &&
3700 !silc_server_channel_has_local(channel)) {
3701 /* Notify about leaving client if this channel has global users. */
3702 if (notify && channel->global_users)
3703 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3704 SILC_NOTIFY_TYPE_LEAVE, 1,
3705 clidp->data, silc_buffer_len(clidp));
3707 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3708 silc_server_channel_delete(server, channel);
3709 silc_buffer_free(clidp);
3713 /* Send notify to channel about client leaving the channel */
3715 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3716 SILC_NOTIFY_TYPE_LEAVE, 1,
3717 clidp->data, silc_buffer_len(clidp));
3719 silc_buffer_free(clidp);
3723 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3724 function may be used only by router. In real SILC network all channels
3725 are created by routers thus this function is never used by normal
3728 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3729 SilcServerID *router_id,
3735 SilcChannelID *channel_id;
3736 SilcChannelEntry entry;
3737 SilcCipher send_key, receive_key;
3740 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3743 cipher = SILC_DEFAULT_CIPHER;
3745 hmac = SILC_DEFAULT_HMAC;
3747 /* Allocate cipher */
3748 if (!silc_cipher_alloc(cipher, &send_key))
3750 if (!silc_cipher_alloc(cipher, &receive_key)) {
3751 silc_cipher_free(send_key);
3756 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3757 silc_cipher_free(send_key);
3758 silc_cipher_free(receive_key);
3762 channel_name = strdup(channel_name);
3764 /* Create the channel ID */
3765 if (!silc_id_create_channel_id(server, router_id, server->rng,
3767 silc_free(channel_name);
3768 silc_cipher_free(send_key);
3769 silc_cipher_free(receive_key);
3770 silc_hmac_free(newhmac);
3774 /* Create the channel */
3775 entry = silc_idlist_add_channel(server->local_list, channel_name,
3776 SILC_CHANNEL_MODE_NONE, channel_id,
3777 NULL, send_key, receive_key, newhmac);
3779 silc_free(channel_name);
3780 silc_cipher_free(send_key);
3781 silc_cipher_free(receive_key);
3782 silc_hmac_free(newhmac);
3783 silc_free(channel_id);
3787 entry->cipher = strdup(cipher);
3788 entry->hmac_name = strdup(hmac);
3790 /* Now create the actual key material */
3791 if (!silc_server_create_channel_key(server, entry,
3792 silc_cipher_get_key_len(send_key) / 8)) {
3793 silc_idlist_del_channel(server->local_list, entry);
3797 /* Notify other routers about the new channel. We send the packet
3798 to our primary route. */
3800 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3801 channel_name, entry->id,
3802 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3805 /* Distribute to backup routers */
3806 if (broadcast && server->server_type == SILC_ROUTER) {
3808 unsigned char cid[32];
3809 SilcUInt32 name_len = strlen(channel_name);
3812 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3813 packet = silc_channel_payload_encode(channel_name, name_len,
3814 cid, id_len, entry->mode);
3815 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3816 packet->data, silc_buffer_len(packet), FALSE,
3818 silc_buffer_free(packet);
3821 server->stat.my_channels++;
3822 if (server->server_type == SILC_ROUTER) {
3823 server->stat.channels++;
3824 server->stat.cell_channels++;
3825 entry->users_resolved = TRUE;
3831 /* Same as above but creates the channel with Channel ID `channel_id. */
3834 silc_server_create_new_channel_with_id(SilcServer server,
3838 SilcChannelID *channel_id,
3841 SilcChannelEntry entry;
3842 SilcCipher send_key, receive_key;
3845 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3848 cipher = SILC_DEFAULT_CIPHER;
3850 hmac = SILC_DEFAULT_HMAC;
3852 /* Allocate cipher */
3853 if (!silc_cipher_alloc(cipher, &send_key))
3855 if (!silc_cipher_alloc(cipher, &receive_key)) {
3856 silc_cipher_free(send_key);
3861 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3862 silc_cipher_free(send_key);
3863 silc_cipher_free(receive_key);
3867 channel_name = strdup(channel_name);
3869 /* Create the channel */
3870 entry = silc_idlist_add_channel(server->local_list, channel_name,
3871 SILC_CHANNEL_MODE_NONE, channel_id,
3872 NULL, send_key, receive_key, newhmac);
3874 silc_cipher_free(send_key);
3875 silc_cipher_free(receive_key);
3876 silc_hmac_free(newhmac);
3877 silc_free(channel_name);
3881 /* Now create the actual key material */
3882 if (!silc_server_create_channel_key(server, entry,
3883 silc_cipher_get_key_len(send_key) / 8)) {
3884 silc_idlist_del_channel(server->local_list, entry);
3888 /* Notify other routers about the new channel. We send the packet
3889 to our primary route. */
3891 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3892 channel_name, entry->id,
3893 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3896 /* Distribute to backup routers */
3897 if (broadcast && server->server_type == SILC_ROUTER) {
3899 unsigned char cid[32];
3900 SilcUInt32 name_len = strlen(channel_name);
3903 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3904 packet = silc_channel_payload_encode(channel_name, name_len,
3905 cid, id_len, entry->mode);
3906 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3907 packet->data, silc_buffer_len(packet), FALSE,
3909 silc_buffer_free(packet);
3912 server->stat.my_channels++;
3913 if (server->server_type == SILC_ROUTER) {
3914 server->stat.channels++;
3915 server->stat.cell_channels++;
3916 entry->users_resolved = TRUE;
3922 /* Channel's key re-key timeout callback. */
3924 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3926 SilcServer server = app_context;
3927 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3931 /* Return now if we are shutting down */
3932 if (server->server_shutdown)
3935 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3938 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3941 /* Generates new channel key. This is used to create the initial channel key
3942 but also to re-generate new key for channel. If `key_len' is provided
3943 it is the bytes of the key length. */
3945 SilcBool silc_server_create_channel_key(SilcServer server,
3946 SilcChannelEntry channel,
3950 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3953 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3954 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3958 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3960 if (!channel->send_key)
3961 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3962 channel->send_key = NULL;
3965 if (!channel->receive_key)
3966 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3967 silc_cipher_free(channel->send_key);
3968 channel->send_key = channel->receive_key = NULL;
3974 else if (channel->key_len)
3975 len = channel->key_len / 8;
3977 len = silc_cipher_get_key_len(channel->send_key) / 8;
3979 /* Create channel key */
3980 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3983 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3984 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3986 /* Remove old key if exists */
3988 memset(channel->key, 0, channel->key_len / 8);
3989 silc_free(channel->key);
3993 channel->key_len = len * 8;
3994 channel->key = silc_memdup(channel_key, len);
3995 memset(channel_key, 0, sizeof(channel_key));
3997 /* Generate HMAC key from the channel key data and set it */
3999 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4000 memset(channel->key, 0, channel->key_len / 8);
4001 silc_free(channel->key);
4002 silc_cipher_free(channel->send_key);
4003 silc_cipher_free(channel->receive_key);
4004 channel->send_key = channel->receive_key = NULL;
4007 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
4008 silc_hmac_set_key(channel->hmac, hash,
4009 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4010 memset(hash, 0, sizeof(hash));
4012 if (server->server_type == SILC_ROUTER) {
4013 if (!channel->rekey)
4014 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4015 if (!channel->rekey) {
4016 memset(channel->key, 0, channel->key_len / 8);
4017 silc_free(channel->key);
4018 silc_cipher_free(channel->send_key);
4019 silc_cipher_free(channel->receive_key);
4020 channel->send_key = channel->receive_key = NULL;
4023 channel->rekey->channel = channel;
4024 channel->rekey->key_len = key_len;
4025 if (channel->rekey->task)
4026 silc_schedule_task_del(server->schedule, channel->rekey->task);
4028 channel->rekey->task =
4029 silc_schedule_task_add_timeout(server->schedule,
4030 silc_server_channel_key_rekey,
4031 (void *)channel->rekey,
4032 server->config->channel_rekey_secs, 0);
4038 /* Saves the channel key found in the encoded `key_payload' buffer. This
4039 function is used when we receive Channel Key Payload and also when we're
4040 processing JOIN command reply. Returns entry to the channel. */
4042 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4043 SilcBuffer key_payload,
4044 SilcChannelEntry channel)
4046 SilcChannelKeyPayload payload = NULL;
4048 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4052 /* Decode channel key payload */
4053 payload = silc_channel_key_payload_parse(key_payload->data,
4054 silc_buffer_len(key_payload));
4056 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4061 /* Get the channel entry */
4064 /* Get channel ID */
4065 tmp = silc_channel_key_get_id(payload, &tmp_len);
4066 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4071 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4073 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4075 if (server->server_type == SILC_ROUTER)
4076 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4077 silc_id_render(&id, SILC_ID_CHANNEL)));
4083 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4085 tmp = silc_channel_key_get_key(payload, &tmp_len);
4091 cipher = silc_channel_key_get_cipher(payload, NULL);
4097 /* Remove old key if exists */
4099 memset(channel->key, 0, channel->key_len / 8);
4100 silc_free(channel->key);
4101 silc_cipher_free(channel->send_key);
4102 silc_cipher_free(channel->receive_key);
4105 /* Create new cipher */
4106 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4107 channel->send_key = NULL;
4111 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4112 silc_cipher_free(channel->send_key);
4113 channel->send_key = channel->receive_key = NULL;
4118 if (channel->cipher)
4119 silc_free(channel->cipher);
4120 channel->cipher = strdup(cipher);
4123 channel->key_len = tmp_len * 8;
4124 channel->key = silc_memdup(tmp, tmp_len);
4125 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4126 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4128 /* Generate HMAC key from the channel key data and set it */
4130 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4131 memset(channel->key, 0, channel->key_len / 8);
4132 silc_free(channel->key);
4133 silc_cipher_free(channel->send_key);
4134 silc_cipher_free(channel->receive_key);
4135 channel->send_key = channel->receive_key = NULL;
4138 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4139 silc_hmac_set_key(channel->hmac, hash,
4140 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4142 memset(hash, 0, sizeof(hash));
4143 memset(tmp, 0, tmp_len);
4145 if (server->server_type == SILC_ROUTER) {
4146 if (!channel->rekey)
4147 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4148 if (!channel->rekey) {
4149 memset(channel->key, 0, channel->key_len / 8);
4150 silc_free(channel->key);
4151 silc_cipher_free(channel->send_key);
4152 silc_cipher_free(channel->receive_key);
4153 channel->send_key = channel->receive_key = NULL;
4156 channel->rekey->channel = channel;
4157 if (channel->rekey->task)
4158 silc_schedule_task_del(server->schedule, channel->rekey->task);
4160 channel->rekey->task =
4161 silc_schedule_task_add_timeout(server->schedule,
4162 silc_server_channel_key_rekey,
4163 (void *)channel->rekey,
4164 server->config->channel_rekey_secs, 0);
4169 silc_channel_key_payload_free(payload);
4174 /* Returns assembled of all servers in the given ID list. The packet's
4175 form is dictated by the New ID payload. */
4177 static void silc_server_announce_get_servers(SilcServer server,
4178 SilcServerEntry remote,
4180 SilcBuffer *servers,
4181 unsigned long creation_time)
4184 SilcIDCacheEntry id_cache;
4185 SilcServerEntry entry;
4189 /* Go through all clients in the list */
4190 if (silc_idcache_get_all(id_list->servers, &list)) {
4191 silc_list_start(list);
4192 while ((id_cache = silc_list_get(list))) {
4193 entry = (SilcServerEntry)id_cache->context;
4195 /* Do not announce the one we've sending our announcements and
4196 do not announce ourself. Also check the creation time if it's
4198 if ((entry == remote) || (entry == server->id_entry) ||
4199 (creation_time && entry->data.created < creation_time))
4202 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4204 tmp = silc_buffer_realloc(*servers,
4206 silc_buffer_truelen((*servers)) +
4207 silc_buffer_len(idp) :
4208 silc_buffer_len(idp)));
4212 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4213 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4214 silc_buffer_pull(*servers, silc_buffer_len(idp));
4215 silc_buffer_free(idp);
4221 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4227 p = silc_notify_payload_encode(notify, argc, ap);
4233 /* This function is used by router to announce existing servers to our
4234 primary router when we've connected to it. If `creation_time' is non-zero
4235 then only the servers that has been created after the `creation_time'
4236 will be announced. */
4238 void silc_server_announce_servers(SilcServer server, SilcBool global,
4239 unsigned long creation_time,
4240 SilcPacketStream remote)
4242 SilcBuffer servers = NULL;
4244 SILC_LOG_DEBUG(("Announcing servers"));
4246 /* Get servers in local list */
4247 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4248 server->local_list, &servers,
4252 /* Get servers in global list */
4253 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4254 server->global_list, &servers,
4258 silc_buffer_push(servers, servers->data - servers->head);
4259 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4261 /* Send the packet */
4262 silc_server_packet_send(server, remote,
4263 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4264 servers->data, silc_buffer_len(servers));
4266 silc_buffer_free(servers);
4270 /* Returns assembled packet of all clients in the given ID list. The
4271 packet's form is dictated by the New ID Payload. */
4273 static void silc_server_announce_get_clients(SilcServer server,
4275 SilcBuffer *clients,
4277 unsigned long creation_time)
4280 SilcIDCacheEntry id_cache;
4281 SilcClientEntry client;
4284 unsigned char mode[4];
4287 /* Go through all clients in the list */
4288 if (silc_idcache_get_all(id_list->clients, &list)) {
4289 silc_list_start(list);
4290 while ((id_cache = silc_list_get(list))) {
4291 client = (SilcClientEntry)id_cache->context;
4293 if (creation_time && client->data.created < creation_time)
4295 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4297 if (!client->connection && !client->router)
4300 SILC_LOG_DEBUG(("Announce Client ID %s",
4301 silc_id_render(client->id, SILC_ID_CLIENT)));
4303 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4307 tmp2 = silc_buffer_realloc(*clients,
4309 silc_buffer_truelen((*clients)) +
4310 silc_buffer_len(idp) :
4311 silc_buffer_len(idp)));
4315 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4316 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4317 silc_buffer_pull(*clients, silc_buffer_len(idp));
4319 SILC_PUT32_MSB(client->mode, mode);
4321 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4322 2, idp->data, silc_buffer_len(idp),
4324 tmp2 = silc_buffer_realloc(*umodes,
4326 silc_buffer_truelen((*umodes)) +
4327 silc_buffer_len(tmp) :
4328 silc_buffer_len(tmp)));
4332 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4333 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4334 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4335 silc_buffer_free(tmp);
4337 silc_buffer_free(idp);
4342 /* This function is used to announce our existing clients to our router
4343 when we've connected to it. If `creation_time' is non-zero then only
4344 the clients that has been created after the `creation_time' will be
4347 void silc_server_announce_clients(SilcServer server,
4348 unsigned long creation_time,
4349 SilcPacketStream remote)
4351 SilcBuffer clients = NULL;
4352 SilcBuffer umodes = NULL;
4354 SILC_LOG_DEBUG(("Announcing clients"));
4356 /* Get clients in local list */
4357 silc_server_announce_get_clients(server, server->local_list,
4358 &clients, &umodes, creation_time);
4360 /* As router we announce our global list as well */
4361 if (server->server_type == SILC_ROUTER)
4362 silc_server_announce_get_clients(server, server->global_list,
4363 &clients, &umodes, creation_time);
4366 silc_buffer_push(clients, clients->data - clients->head);
4367 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4369 /* Send the packet */
4370 silc_server_packet_send(server, remote,
4371 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4372 clients->data, silc_buffer_len(clients));
4374 silc_buffer_free(clients);
4378 silc_buffer_push(umodes, umodes->data - umodes->head);
4379 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4381 /* Send the packet */
4382 silc_server_packet_send(server, remote,
4383 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4384 umodes->data, silc_buffer_len(umodes));
4386 silc_buffer_free(umodes);
4390 /* Returns channel's topic for announcing it */
4392 void silc_server_announce_get_channel_topic(SilcServer server,
4393 SilcChannelEntry channel,
4398 if (channel->topic) {
4399 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4400 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4402 silc_buffer_len(chidp),
4404 strlen(channel->topic));
4405 silc_buffer_free(chidp);
4409 /* Returns channel's invite and ban lists */
4411 void silc_server_announce_get_inviteban(SilcServer server,
4412 SilcChannelEntry channel,
4416 SilcBuffer list, idp, idp2, tmp2;
4419 SilcHashTableList htl;
4420 const unsigned char a[1] = { 0x03 };
4422 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4424 /* Encode invite list */
4425 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4426 list = silc_buffer_alloc_size(2);
4427 type = silc_hash_table_count(channel->invite_list);
4428 SILC_PUT16_MSB(type, list->data);
4429 silc_hash_table_list(channel->invite_list, &htl);
4430 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4431 list = silc_argument_payload_encode_one(list, tmp2->data,
4432 silc_buffer_len(tmp2),
4433 SILC_PTR_TO_32(ptype));
4434 silc_hash_table_list_reset(&htl);
4436 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4438 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4439 idp->data, silc_buffer_len(idp),
4440 channel->channel_name,
4441 strlen(channel->channel_name),
4442 idp2->data, silc_buffer_len(idp2),
4444 list->data, silc_buffer_len(list));
4445 silc_buffer_free(idp2);
4446 silc_buffer_free(list);
4449 /* Encode ban list */
4450 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4451 list = silc_buffer_alloc_size(2);
4452 type = silc_hash_table_count(channel->ban_list);
4453 SILC_PUT16_MSB(type, list->data);
4454 silc_hash_table_list(channel->ban_list, &htl);
4455 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4456 list = silc_argument_payload_encode_one(list, tmp2->data,
4457 silc_buffer_len(tmp2),
4458 SILC_PTR_TO_32(ptype));
4459 silc_hash_table_list_reset(&htl);
4462 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4463 idp->data, silc_buffer_len(idp),
4465 list->data, silc_buffer_len(list));
4466 silc_buffer_free(list);
4469 silc_buffer_free(idp);
4472 /* Returns assembled packets for channel users of the `channel'. */
4474 void silc_server_announce_get_channel_users(SilcServer server,
4475 SilcChannelEntry channel,
4476 SilcBuffer *channel_modes,
4477 SilcBuffer *channel_users,
4478 SilcBuffer *channel_users_modes)
4480 SilcChannelClientEntry chl;
4481 SilcHashTableList htl;
4482 SilcBuffer chidp, clidp, csidp;
4483 SilcBuffer tmp, fkey = NULL, chpklist;
4485 unsigned char mode[4], ulimit[4];
4489 SILC_LOG_DEBUG(("Start"));
4491 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4492 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4493 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4496 SILC_PUT32_MSB(channel->mode, mode);
4497 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4498 SILC_PUT32_MSB(channel->user_limit, ulimit);
4499 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4500 if (channel->founder_key)
4501 fkey = silc_public_key_payload_encode(channel->founder_key);
4503 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4505 silc_buffer_len(csidp),
4508 hmac, hmac ? strlen(hmac) : 0,
4509 channel->passphrase,
4510 channel->passphrase ?
4511 strlen(channel->passphrase) : 0,
4512 fkey ? fkey->data : NULL,
4513 fkey ? silc_buffer_len(fkey) : 0,
4514 chpklist ? chpklist->data : NULL,
4516 silc_buffer_len(chpklist) : 0,
4518 SILC_CHANNEL_MODE_ULIMIT ?
4521 SILC_CHANNEL_MODE_ULIMIT ?
4522 sizeof(ulimit) : 0));
4523 len = silc_buffer_len(tmp);
4525 silc_buffer_realloc(*channel_modes,
4527 silc_buffer_truelen((*channel_modes)) + len : len));
4530 *channel_modes = tmp2;
4531 silc_buffer_pull_tail(*channel_modes,
4532 ((*channel_modes)->end -
4533 (*channel_modes)->data));
4534 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4535 silc_buffer_pull(*channel_modes, len);
4536 silc_buffer_free(tmp);
4537 silc_buffer_free(fkey);
4540 /* Now find all users on the channel */
4541 silc_hash_table_list(channel->user_list, &htl);
4542 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4543 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4545 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4549 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4551 silc_buffer_len(clidp),
4553 silc_buffer_len(chidp));
4554 len = silc_buffer_len(tmp);
4556 silc_buffer_realloc(*channel_users,
4558 silc_buffer_truelen((*channel_users)) + len : len));
4561 *channel_users = tmp2;
4562 silc_buffer_pull_tail(*channel_users,
4563 ((*channel_users)->end -
4564 (*channel_users)->data));
4566 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4567 silc_buffer_pull(*channel_users, len);
4568 silc_buffer_free(tmp);
4570 /* CUMODE notify for mode change on the channel */
4571 SILC_PUT32_MSB(chl->mode, mode);
4572 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4573 fkey = silc_public_key_payload_encode(channel->founder_key);
4574 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4576 silc_buffer_len(csidp),
4579 silc_buffer_len(clidp),
4580 fkey ? fkey->data : NULL,
4581 fkey ? silc_buffer_len(fkey) : 0);
4582 len = silc_buffer_len(tmp);
4584 silc_buffer_realloc(*channel_users_modes,
4585 (*channel_users_modes ?
4586 silc_buffer_truelen((*channel_users_modes)) +
4590 *channel_users_modes = tmp2;
4591 silc_buffer_pull_tail(*channel_users_modes,
4592 ((*channel_users_modes)->end -
4593 (*channel_users_modes)->data));
4595 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4596 silc_buffer_pull(*channel_users_modes, len);
4597 silc_buffer_free(tmp);
4598 silc_buffer_free(fkey);
4600 silc_buffer_free(clidp);
4602 silc_hash_table_list_reset(&htl);
4603 silc_buffer_free(chidp);
4604 silc_buffer_free(csidp);
4607 /* Returns assembled packets for all channels and users on those channels
4608 from the given ID List. The packets are in the form dictated by the
4609 New Channel and New Channel User payloads. */
4611 void silc_server_announce_get_channels(SilcServer server,
4613 SilcBuffer *channels,
4614 SilcBuffer **channel_modes,
4615 SilcBuffer *channel_users,
4616 SilcBuffer **channel_users_modes,
4617 SilcUInt32 *channel_users_modes_c,
4618 SilcBuffer **channel_topics,
4619 SilcBuffer **channel_invites,
4620 SilcBuffer **channel_bans,
4621 SilcChannelID ***channel_ids,
4622 unsigned long creation_time)
4625 SilcIDCacheEntry id_cache;
4626 SilcChannelEntry channel;
4627 unsigned char cid[32];
4629 SilcUInt16 name_len;
4631 int i = *channel_users_modes_c;
4635 SILC_LOG_DEBUG(("Start"));
4637 /* Go through all channels in the list */
4638 if (silc_idcache_get_all(id_list->channels, &list)) {
4639 silc_list_start(list);
4640 while ((id_cache = silc_list_get(list))) {
4641 channel = (SilcChannelEntry)id_cache->context;
4643 if (creation_time && channel->created < creation_time)
4648 SILC_LOG_DEBUG(("Announce Channel ID %s",
4649 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4651 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4652 name_len = strlen(channel->channel_name);
4655 len = 4 + name_len + id_len + 4;
4657 silc_buffer_realloc(*channels,
4659 silc_buffer_truelen((*channels)) +
4665 silc_buffer_pull_tail(*channels,
4666 ((*channels)->end - (*channels)->data));
4667 silc_buffer_format(*channels,
4668 SILC_STR_UI_SHORT(name_len),
4669 SILC_STR_UI_XNSTRING(channel->channel_name,
4671 SILC_STR_UI_SHORT(id_len),
4672 SILC_STR_UI_XNSTRING(cid, id_len),
4673 SILC_STR_UI_INT(channel->mode),
4675 silc_buffer_pull(*channels, len);
4678 if (creation_time && channel->updated < creation_time)
4684 /* Channel user modes */
4685 tmp = silc_realloc(*channel_users_modes,
4686 sizeof(**channel_users_modes) * (i + 1));
4689 *channel_users_modes = tmp;
4690 (*channel_users_modes)[i] = NULL;
4691 tmp = silc_realloc(*channel_modes,
4692 sizeof(**channel_modes) * (i + 1));
4695 *channel_modes = tmp;
4696 (*channel_modes)[i] = NULL;
4697 tmp = silc_realloc(*channel_ids,
4698 sizeof(**channel_ids) * (i + 1));
4702 (*channel_ids)[i] = NULL;
4703 silc_server_announce_get_channel_users(server, channel,
4704 &(*channel_modes)[i],
4706 &(*channel_users_modes)[i]);
4707 (*channel_ids)[i] = channel->id;
4709 /* Channel's topic */
4710 tmp = silc_realloc(*channel_topics,
4711 sizeof(**channel_topics) * (i + 1));
4714 *channel_topics = tmp;
4715 (*channel_topics)[i] = NULL;
4716 silc_server_announce_get_channel_topic(server, channel,
4717 &(*channel_topics)[i]);
4719 /* Channel's invite and ban list */
4720 tmp = silc_realloc(*channel_invites,
4721 sizeof(**channel_invites) * (i + 1));
4724 *channel_invites = tmp;
4725 (*channel_invites)[i] = NULL;
4726 tmp = silc_realloc(*channel_bans,
4727 sizeof(**channel_bans) * (i + 1));
4730 *channel_bans = tmp;
4731 (*channel_bans)[i] = NULL;
4732 silc_server_announce_get_inviteban(server, channel,
4733 &(*channel_invites)[i],
4734 &(*channel_bans)[i]);
4736 (*channel_users_modes_c)++;
4744 /* This function is used to announce our existing channels to our router
4745 when we've connected to it. This also announces the users on the
4746 channels to the router. If the `creation_time' is non-zero only the
4747 channels that was created after the `creation_time' are announced.
4748 Note that the channel users are still announced even if the `creation_time'
4751 void silc_server_announce_channels(SilcServer server,
4752 unsigned long creation_time,
4753 SilcPacketStream remote)
4755 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4756 SilcBuffer *channel_users_modes = NULL;
4757 SilcBuffer *channel_topics = NULL;
4758 SilcBuffer *channel_invites = NULL;
4759 SilcBuffer *channel_bans = NULL;
4760 SilcUInt32 channel_users_modes_c = 0;
4761 SilcChannelID **channel_ids = NULL;
4763 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4765 /* Get channels and channel users in local list */
4766 silc_server_announce_get_channels(server, server->local_list,
4767 &channels, &channel_modes,
4769 &channel_users_modes,
4770 &channel_users_modes_c,
4774 &channel_ids, creation_time);
4776 /* Get channels and channel users in global list */
4777 if (server->server_type != SILC_SERVER)
4778 silc_server_announce_get_channels(server, server->global_list,
4779 &channels, &channel_modes,
4781 &channel_users_modes,
4782 &channel_users_modes_c,
4786 &channel_ids, creation_time);
4789 silc_buffer_push(channels, channels->data - channels->head);
4790 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4792 /* Send the packet */
4793 silc_server_packet_send(server, remote,
4794 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4795 channels->data, silc_buffer_len(channels));
4797 silc_buffer_free(channels);
4800 if (channel_users) {
4801 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4802 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4803 silc_buffer_len(channel_users));
4805 /* Send the packet */
4806 silc_server_packet_send(server, remote,
4807 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4808 channel_users->data, silc_buffer_len(channel_users));
4810 silc_buffer_free(channel_users);
4813 if (channel_modes) {
4816 for (i = 0; i < channel_users_modes_c; i++) {
4817 if (!channel_modes[i])
4819 silc_buffer_push(channel_modes[i],
4820 channel_modes[i]->data -
4821 channel_modes[i]->head);
4822 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4823 silc_buffer_len(channel_modes[i]));
4824 silc_server_packet_send_dest(server, remote,
4825 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4826 channel_ids[i], SILC_ID_CHANNEL,
4827 channel_modes[i]->data,
4828 silc_buffer_len(channel_modes[i]));
4829 silc_buffer_free(channel_modes[i]);
4831 silc_free(channel_modes);
4834 if (channel_users_modes) {
4837 for (i = 0; i < channel_users_modes_c; i++) {
4838 if (!channel_users_modes[i])
4840 silc_buffer_push(channel_users_modes[i],
4841 channel_users_modes[i]->data -
4842 channel_users_modes[i]->head);
4843 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4844 silc_buffer_len(channel_users_modes[i]));
4845 silc_server_packet_send_dest(server, remote,
4846 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4847 channel_ids[i], SILC_ID_CHANNEL,
4848 channel_users_modes[i]->data,
4849 silc_buffer_len(channel_users_modes[i]));
4850 silc_buffer_free(channel_users_modes[i]);
4852 silc_free(channel_users_modes);
4855 if (channel_topics) {
4858 for (i = 0; i < channel_users_modes_c; i++) {
4859 if (!channel_topics[i])
4862 silc_buffer_push(channel_topics[i],
4863 channel_topics[i]->data -
4864 channel_topics[i]->head);
4865 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4866 silc_buffer_len(channel_topics[i]));
4867 silc_server_packet_send_dest(server, remote,
4868 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4869 channel_ids[i], SILC_ID_CHANNEL,
4870 channel_topics[i]->data,
4871 silc_buffer_len(channel_topics[i]));
4872 silc_buffer_free(channel_topics[i]);
4874 silc_free(channel_topics);
4877 if (channel_invites) {
4880 for (i = 0; i < channel_users_modes_c; i++) {
4881 if (!channel_invites[i])
4884 silc_buffer_push(channel_invites[i],
4885 channel_invites[i]->data -
4886 channel_invites[i]->head);
4887 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4888 silc_buffer_len(channel_invites[i]));
4889 silc_server_packet_send_dest(server, remote,
4890 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4891 channel_ids[i], SILC_ID_CHANNEL,
4892 channel_invites[i]->data,
4893 silc_buffer_len(channel_invites[i]));
4894 silc_buffer_free(channel_invites[i]);
4896 silc_free(channel_invites);
4902 for (i = 0; i < channel_users_modes_c; i++) {
4903 if (!channel_bans[i])
4906 silc_buffer_push(channel_bans[i],
4907 channel_bans[i]->data -
4908 channel_bans[i]->head);
4909 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4910 silc_buffer_len(channel_bans[i]));
4911 silc_server_packet_send_dest(server, remote,
4912 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4913 channel_ids[i], SILC_ID_CHANNEL,
4914 channel_bans[i]->data,
4915 silc_buffer_len(channel_bans[i]));
4916 silc_buffer_free(channel_bans[i]);
4918 silc_free(channel_bans);
4921 silc_free(channel_ids);
4924 /* Announces WATCH list. */
4926 void silc_server_announce_watches(SilcServer server,
4927 SilcPacketStream remote)
4929 SilcHashTableList htl;
4930 SilcBuffer buffer, idp, args, pkp;
4931 SilcClientEntry client;
4934 SILC_LOG_DEBUG(("Announcing watch list"));
4936 /* XXX because way we save the nicks (hash) we cannot announce them. */
4938 /* XXX we should send all public keys in one command if client is
4939 watching more than one key */
4940 silc_hash_table_list(server->watcher_list_pk, &htl);
4941 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4942 if (!client || !client->id)
4945 server->stat.commands_sent++;
4947 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4948 args = silc_buffer_alloc_size(2);
4949 silc_buffer_format(args,
4950 SILC_STR_UI_SHORT(1),
4952 pkp = silc_public_key_payload_encode(key);
4953 args = silc_argument_payload_encode_one(args, pkp->data,
4954 silc_buffer_len(pkp), 0x00);
4955 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4956 ++server->cmd_ident, 2,
4957 1, idp->data, silc_buffer_len(idp),
4959 silc_buffer_len(args));
4962 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4963 buffer->data, silc_buffer_len(buffer));
4965 silc_buffer_free(pkp);
4966 silc_buffer_free(args);
4967 silc_buffer_free(idp);
4968 silc_buffer_free(buffer);
4970 silc_hash_table_list_reset(&htl);
4973 /* Assembles user list and users mode list from the `channel'. */
4975 SilcBool silc_server_get_users_on_channel(SilcServer server,
4976 SilcChannelEntry channel,
4977 SilcBuffer *user_list,
4978 SilcBuffer *mode_list,
4979 SilcUInt32 *user_count)
4981 SilcChannelClientEntry chl;
4982 SilcHashTableList htl;
4983 SilcBuffer client_id_list;
4984 SilcBuffer client_mode_list;
4986 SilcUInt32 list_count = 0, len = 0;
4988 if (!silc_hash_table_count(channel->user_list))
4991 silc_hash_table_list(channel->user_list, &htl);
4992 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4993 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4994 silc_hash_table_list_reset(&htl);
4996 client_id_list = silc_buffer_alloc(len);
4998 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4999 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
5000 silc_buffer_pull_tail(client_mode_list,
5001 silc_buffer_truelen(client_mode_list));
5003 silc_hash_table_list(channel->user_list, &htl);
5004 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5006 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
5007 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
5008 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
5009 silc_buffer_free(idp);
5011 /* Client's mode on channel */
5012 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
5013 silc_buffer_pull(client_mode_list, 4);
5017 silc_hash_table_list_reset(&htl);
5018 silc_buffer_push(client_id_list,
5019 client_id_list->data - client_id_list->head);
5020 silc_buffer_push(client_mode_list,
5021 client_mode_list->data - client_mode_list->head);
5023 *user_list = client_id_list;
5024 *mode_list = client_mode_list;
5025 *user_count = list_count;
5029 /* Saves users and their modes to the `channel'. */
5031 void silc_server_save_users_on_channel(SilcServer server,
5032 SilcPacketStream sock,
5033 SilcChannelEntry channel,
5034 SilcClientID *noadd,
5035 SilcBuffer user_list,
5036 SilcBuffer mode_list,
5037 SilcUInt32 user_count)
5043 SilcClientEntry client;
5044 SilcIDCacheEntry cache;
5045 SilcChannelClientEntry chl;
5047 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5048 channel->channel_name));
5050 for (i = 0; i < user_count; i++) {
5052 SILC_GET16_MSB(idp_len, user_list->data + 2);
5054 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5056 silc_buffer_pull(user_list, idp_len);
5059 SILC_GET32_MSB(mode, mode_list->data);
5060 silc_buffer_pull(mode_list, 4);
5062 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5067 /* Check if we have this client cached already. */
5068 client = silc_idlist_find_client_by_id(server->local_list,
5070 server->server_type, &cache);
5072 client = silc_idlist_find_client_by_id(server->global_list,
5074 server->server_type, &cache);
5076 /* If router did not find such Client ID in its lists then this must
5077 be bogus client or some router in the net is buggy. */
5078 if (server->server_type != SILC_SERVER)
5081 /* We don't have that client anywhere, add it. The client is added
5082 to global list since server didn't have it in the lists so it must be
5084 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5085 silc_id_dup(&id.u.client_id,
5087 silc_packet_get_context(sock),
5090 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5094 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5096 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
5097 server->stat.clients + 1));
5098 server->stat.clients++;
5101 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5102 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5103 "%s", channel->channel_name));
5107 if (!silc_server_client_on_channel(client, channel, &chl)) {
5108 /* Client was not on the channel, add it. */
5109 chl = silc_calloc(1, sizeof(*chl));
5112 chl->client = client;
5114 chl->channel = channel;
5115 silc_hash_table_add(channel->user_list, chl->client, chl);
5116 silc_hash_table_add(client->channels, chl->channel, chl);
5117 channel->user_count++;
5125 /* Saves channels and channels user modes to the `client'. Removes
5126 the client from those channels that are not sent in the list but
5129 void silc_server_save_user_channels(SilcServer server,
5130 SilcPacketStream sock,
5131 SilcClientEntry client,
5132 SilcBuffer channels,
5133 SilcBuffer channels_user_modes)
5136 SilcUInt32 *chumodes;
5137 SilcChannelPayload entry;
5138 SilcChannelEntry channel;
5139 SilcChannelID channel_id;
5140 SilcChannelClientEntry chl;
5141 SilcHashTable ht = NULL;
5142 SilcHashTableList htl;
5146 if (!channels || !channels_user_modes ||
5147 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5150 ch = silc_channel_payload_parse_list(channels->data,
5151 silc_buffer_len(channels));
5152 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5154 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5155 NULL, NULL, NULL, TRUE);
5156 silc_dlist_start(ch);
5157 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5158 /* Check if we have this channel, and add it if we don't have it.
5159 Also add the client on the channel unless it is there already. */
5160 if (!silc_channel_get_id_parse(entry, &channel_id))
5162 channel = silc_idlist_find_channel_by_id(server->local_list,
5165 channel = silc_idlist_find_channel_by_id(server->global_list,
5168 if (server->server_type != SILC_SERVER) {
5173 /* We don't have that channel anywhere, add it. */
5174 name = silc_channel_get_name(entry, NULL);
5175 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5176 silc_id_dup(&channel_id,
5178 server->router, NULL, NULL, 0);
5185 channel->mode = silc_channel_get_mode(entry);
5187 /* Add the client on the channel */
5188 if (!silc_server_client_on_channel(client, channel, &chl)) {
5189 chl = silc_calloc(1, sizeof(*chl));
5192 chl->client = client;
5193 chl->mode = chumodes[i++];
5194 chl->channel = channel;
5195 silc_hash_table_add(channel->user_list, chl->client, chl);
5196 silc_hash_table_add(client->channels, chl->channel, chl);
5197 channel->user_count++;
5200 chl->mode = chumodes[i++];
5203 silc_hash_table_add(ht, channel, channel);
5205 silc_channel_payload_list_free(ch);
5206 silc_free(chumodes);
5210 /* Go through the list again and remove client from channels that
5211 are no part of the list. */
5213 silc_hash_table_list(client->channels, &htl);
5214 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5215 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5216 silc_hash_table_del(chl->channel->user_list, chl->client);
5217 silc_hash_table_del(chl->client->channels, chl->channel);
5221 silc_hash_table_list_reset(&htl);
5222 silc_hash_table_free(ht);
5224 silc_hash_table_list(client->channels, &htl);
5225 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5226 silc_hash_table_del(chl->channel->user_list, chl->client);
5227 silc_hash_table_del(chl->client->channels, chl->channel);
5230 silc_hash_table_list_reset(&htl);
5234 /* Lookups route to the client indicated by the `id_data'. The connection
5235 object and internal data object is returned. Returns NULL if route
5236 could not be found to the client. If the `client_id' is specified then
5237 it is used and the `id_data' is ignored. */
5240 silc_server_get_client_route(SilcServer server,
5241 unsigned char *id_data,
5243 SilcClientID *client_id,
5244 SilcIDListData *idata,
5245 SilcClientEntry *client_entry)
5247 SilcClientID *id, clid;
5248 SilcClientEntry client;
5250 SILC_LOG_DEBUG(("Start"));
5253 *client_entry = NULL;
5255 /* Decode destination Client ID */
5257 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5259 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5261 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5264 /* If the destination belongs to our server we don't have to route
5265 the packet anywhere but to send it to the local destination. */
5266 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5270 /* If we are router and the client has router then the client is in
5271 our cell but not directly connected to us. */
5272 if (server->server_type == SILC_ROUTER && client->router) {
5273 /* We are of course in this case the client's router thus the route
5274 to the client is the server who owns the client. So, we will send
5275 the packet to that server. */
5277 *idata = (SilcIDListData)client->router;
5278 return client->router->connection;
5281 /* Seems that client really is directly connected to us */
5283 *idata = (SilcIDListData)client;
5285 *client_entry = client;
5286 return client->connection;
5289 /* Destination belongs to someone not in this server. If we are normal
5290 server our action is to send the packet to our router. */
5291 if (server->server_type != SILC_ROUTER && !server->standalone) {
5294 *idata = (SilcIDListData)server->router;
5295 return SILC_PRIMARY_ROUTE(server);
5298 /* We are router and we will perform route lookup for the destination
5299 and send the packet to fastest route. */
5300 if (server->server_type == SILC_ROUTER && !server->standalone) {
5301 /* Check first that the ID is valid */
5302 client = silc_idlist_find_client_by_id(server->global_list, id,
5305 SilcPacketStream dst_sock;
5307 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5310 if (idata && dst_sock)
5311 *idata = silc_packet_get_context(dst_sock);
5320 /* Encodes and returns channel list of channels the `client' has joined.
5321 Secret channels are not put to the list. */
5323 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5324 SilcClientEntry client,
5325 SilcBool get_private,
5326 SilcBool get_secret,
5327 SilcBuffer *user_mode_list)
5329 SilcBuffer buffer = NULL;
5330 SilcChannelEntry channel;
5331 SilcChannelClientEntry chl;
5332 SilcHashTableList htl;
5333 unsigned char cid[32];
5335 SilcUInt16 name_len;
5339 *user_mode_list = NULL;
5341 silc_hash_table_list(client->channels, &htl);
5342 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5343 channel = chl->channel;
5345 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5347 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5350 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5351 name_len = strlen(channel->channel_name);
5353 len = 4 + name_len + id_len + 4;
5354 buffer = silc_buffer_realloc(buffer,
5356 silc_buffer_truelen(buffer) + len : len));
5359 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5360 silc_buffer_format(buffer,
5361 SILC_STR_UI_SHORT(name_len),
5362 SILC_STR_DATA(channel->channel_name, name_len),
5363 SILC_STR_UI_SHORT(id_len),
5364 SILC_STR_DATA(cid, id_len),
5365 SILC_STR_UI_INT(chl->channel->mode),
5367 silc_buffer_pull(buffer, len);
5369 if (user_mode_list) {
5371 silc_buffer_realloc(*user_mode_list,
5373 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5374 if (!(*user_mode_list))
5376 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5377 (*user_mode_list)->data));
5378 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5379 silc_buffer_pull(*user_mode_list, 4);
5382 silc_hash_table_list_reset(&htl);
5385 silc_buffer_push(buffer, buffer->data - buffer->head);
5386 if (user_mode_list && *user_mode_list)
5387 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5388 (*user_mode_list)->head));
5393 /* Task callback used to retrieve network statistical information from
5394 router server once in a while. */
5396 SILC_TASK_CALLBACK(silc_server_get_stats)
5398 SilcServer server = (SilcServer)context;
5399 SilcBuffer idp, packet;
5401 if (!server->standalone) {
5402 SILC_LOG_DEBUG(("Retrieving stats from router"));
5403 server->stat.commands_sent++;
5404 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5406 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5407 ++server->cmd_ident, 1,
5409 silc_buffer_len(idp));
5410 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5411 SILC_PACKET_COMMAND, 0, packet->data,
5412 silc_buffer_len(packet));
5413 silc_buffer_free(packet);
5414 silc_buffer_free(idp);
5418 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,