5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2009 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /************************* Types and definitions ****************************/
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
28 SILC_TASK_CALLBACK(silc_server_do_rekey);
29 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
30 static void silc_server_accept_new_connection(SilcNetStatus status,
33 static void silc_server_packet_parse_type(SilcServer server,
34 SilcPacketStream sock,
36 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
40 /************************ Static utility functions **************************/
42 /* SKE public key verification callback */
45 silc_server_verify_key(SilcSKE ske,
46 SilcPublicKey public_key,
48 SilcSKEVerifyCbCompletion completion,
49 void *completion_context)
51 SilcPacketStream sock = context;
52 SilcUnknownEntry entry = silc_packet_get_context(sock);
54 SILC_LOG_DEBUG(("Verifying public key"));
56 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
57 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
58 entry->hostname, entry->ip, entry->port,
59 silc_pkcs_get_type(public_key)));
60 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
65 /* We accept all keys without explicit verification */
66 completion(ske, SILC_SKE_STATUS_OK, completion_context);
70 /************************ Packet engine callbacks ***************************/
72 /* Packet engine callback to receive a packet */
74 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
75 SilcPacketStream stream,
77 void *callback_context,
80 SilcServer server = callback_context;
81 SilcIDListData idata = stream_context;
86 /* Packets we do not handle */
87 switch (packet->type) {
88 case SILC_PACKET_HEARTBEAT:
89 case SILC_PACKET_SUCCESS:
90 case SILC_PACKET_FAILURE:
91 case SILC_PACKET_REJECT:
92 case SILC_PACKET_KEY_EXCHANGE:
93 case SILC_PACKET_KEY_EXCHANGE_1:
94 case SILC_PACKET_KEY_EXCHANGE_2:
95 case SILC_PACKET_REKEY_DONE:
96 case SILC_PACKET_CONNECTION_AUTH:
101 /* Only specific packets can come without source ID present. */
102 if ((!packet->src_id ||
103 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
104 packet->type != SILC_PACKET_NEW_CLIENT &&
105 packet->type != SILC_PACKET_NEW_SERVER &&
106 packet->type != SILC_PACKET_RESUME_CLIENT &&
107 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
108 packet->type != SILC_PACKET_DISCONNECT)
111 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and
112 for unregistered connection. */
113 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
114 packet->type == SILC_PACKET_NEW_SERVER) &&
115 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
118 /* Ignore packets from disabled connection */
119 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
120 packet->type != SILC_PACKET_HEARTBEAT &&
121 packet->type != SILC_PACKET_RESUME_ROUTER &&
122 packet->type != SILC_PACKET_REKEY)
125 /* Check that the the current client ID is same as in the client's packet. */
126 if (idata->conn_type == SILC_CONN_CLIENT) {
127 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
128 SilcClientID client_id;
130 if (client->id && packet->src_id &&
131 silc_id_str2id(packet->src_id, packet->src_id_len,
132 packet->src_id_type, &client_id, sizeof(client_id))) {
133 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
134 SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
135 silc_get_packet_name(packet->type)));
141 if (server->server_type == SILC_ROUTER) {
142 /* Route the packet if it is not destined to us. Other ID types but
143 server are handled separately after processing them. */
144 if (packet->dst_id &&
145 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
146 packet->dst_id_type == SILC_ID_SERVER &&
147 idata->conn_type != SILC_CONN_CLIENT &&
148 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
149 SilcPacketStream conn;
150 SilcServerID server_id;
152 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
153 &server_id, sizeof(server_id));
155 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
157 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
158 silc_id_render(&server_id, SILC_ID_SERVER)));
162 silc_server_packet_route(server, conn, packet);
163 silc_packet_free(packet);
168 /* Broadcast packet if it is marked as broadcast packet and it is
169 originated from router and we are router. */
170 if (server->server_type == SILC_ROUTER &&
171 idata->conn_type == SILC_CONN_ROUTER &&
172 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
173 /* Broadcast to our primary route */
174 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
176 /* If we have backup routers then we need to feed all broadcast
177 data to those servers. */
178 silc_server_backup_broadcast(server, stream, packet);
182 silc_server_packet_parse_type(server, stream, packet);
187 /* Packet engine callback to indicate end of stream */
189 static void silc_server_packet_eos(SilcPacketEngine engine,
190 SilcPacketStream stream,
191 void *callback_context,
192 void *stream_context)
194 SilcServer server = callback_context;
195 SilcIDListData idata = silc_packet_get_context(stream);
197 SILC_LOG_DEBUG(("End of stream received, sock %p", stream));
199 if (server->router_conn && server->router_conn->sock == stream &&
200 !server->router && server->standalone) {
201 if (idata && idata->sconn && idata->sconn->callback)
202 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
203 silc_server_create_connections(server);
204 silc_server_free_sock_user_data(server, stream, NULL);
206 /* If backup disconnected then mark that resuming will not be allowed */
208 server->server_type == SILC_ROUTER && !server->backup_router &&
209 idata->conn_type == SILC_CONN_SERVER) {
210 SilcServerEntry server_entry = (SilcServerEntry)idata;
211 if (server_entry->server_type == SILC_BACKUP_ROUTER)
212 server->backup_closed = TRUE;
215 if (idata && idata->sconn && idata->sconn->callback)
216 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
217 silc_server_free_sock_user_data(server, stream, NULL);
220 silc_server_close_connection(server, stream);
223 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
225 SilcServer server = app_context;
226 SilcPacketStream stream = context;
227 SilcIDListData idata = silc_packet_get_context(stream);
229 if (!idata || !silc_packet_stream_is_valid(stream)) {
230 silc_packet_stream_unref(stream);
234 if (server->router_conn && server->router_conn->sock == stream &&
235 !server->router && server->standalone) {
236 if (idata->sconn && idata->sconn->callback)
237 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
238 silc_server_create_connections(server);
239 silc_server_free_sock_user_data(server, stream, NULL);
241 /* If backup disconnected then mark that resuming will not be allowed */
242 if (server->server_type == SILC_ROUTER && !server->backup_router &&
243 idata->conn_type == SILC_CONN_SERVER) {
244 SilcServerEntry server_entry = (SilcServerEntry)idata;
245 if (server_entry->server_type == SILC_BACKUP_ROUTER)
246 server->backup_closed = TRUE;
249 if (idata->sconn && idata->sconn->callback)
250 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
251 silc_server_free_sock_user_data(server, stream, NULL);
254 silc_server_close_connection(server, stream);
256 /* Release our stream reference */
257 silc_packet_stream_unref(stream);
260 /* Packet engine callback to indicate error */
262 static void silc_server_packet_error(SilcPacketEngine engine,
263 SilcPacketStream stream,
264 SilcPacketError error,
265 void *callback_context,
266 void *stream_context)
268 SilcServer server = callback_context;
269 SilcIDListData idata = silc_packet_get_context(stream);
270 SilcStream sock = silc_packet_stream_get_stream(stream);
274 SILC_LOG_DEBUG(("Packet error %d, sock %p", error, stream));
279 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
282 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
283 SILC_CONNTYPE_STRING(idata->conn_type),
284 silc_packet_error_string(error)));
286 if (!silc_packet_stream_is_valid(stream))
289 /* We must take reference of the stream */
290 silc_packet_stream_ref(stream);
292 /* In case we get here many times, register only one timeout */
293 silc_schedule_task_del_by_all(server->schedule, 0,
294 silc_server_packet_error_timeout, stream);
296 /* Close connection with random timeout */
297 silc_schedule_task_add_timeout(server->schedule,
298 silc_server_packet_error_timeout, stream,
299 silc_rng_get_byte(server->rng) % 10, 0);
302 /* Packet stream callbacks */
303 static SilcPacketCallbacks silc_server_stream_cbs =
305 silc_server_packet_receive,
306 silc_server_packet_eos,
307 silc_server_packet_error
310 /* Parses the packet type and calls what ever routines the packet type
311 requires. This is done for all incoming packets. */
313 static void silc_server_packet_parse_type(SilcServer server,
314 SilcPacketStream sock,
317 SilcPacketType type = packet->type;
318 SilcIDListData idata = silc_packet_get_context(sock);
323 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
324 NULL, NULL, &ip, &port);
325 #endif /* SILC_DEBUG */
327 SILC_LOG_DEBUG(("Received %s packet [flags %d] from %s:%d",
328 silc_get_packet_name(type), packet->flags, ip, port));
330 /* Parse the packet type */
332 case SILC_PACKET_NOTIFY:
334 * Received notify packet. Server can receive notify packets from
335 * router. Server then relays the notify messages to clients if needed.
337 if (packet->flags & SILC_PACKET_FLAG_LIST)
338 silc_server_notify_list(server, sock, packet);
340 silc_server_notify(server, sock, packet);
344 * Private Message packets
346 case SILC_PACKET_PRIVATE_MESSAGE:
348 * Received private message packet. The packet is coming from either
351 if (packet->flags & SILC_PACKET_FLAG_LIST)
353 idata->last_receive = time(NULL);
354 silc_server_private_message(server, sock, packet);
360 case SILC_PACKET_CHANNEL_MESSAGE:
362 * Received channel message. Channel messages are special packets
363 * (although probably most common ones) thus they are handled
366 if (packet->flags & SILC_PACKET_FLAG_LIST)
368 idata->last_receive = time(NULL);
369 silc_server_channel_message(server, sock, packet);
375 case SILC_PACKET_COMMAND:
377 * Recived command. Processes the command request and allocates the
378 * command context and calls the command.
380 if (packet->flags & SILC_PACKET_FLAG_LIST)
382 server->stat.commands_received++;
383 silc_server_command_process(server, sock, packet);
386 case SILC_PACKET_COMMAND_REPLY:
388 * Received command reply packet. Received command reply to command. It
389 * may be reply to command sent by us or reply to command sent by client
390 * that we've routed further.
392 if (packet->flags & SILC_PACKET_FLAG_LIST)
394 server->stat.commands_received++;
395 silc_server_command_reply(server, sock, packet);
398 case SILC_PACKET_DISCONNECT:
401 char *message = NULL;
402 const char *hostname, *ip;
404 if (packet->flags & SILC_PACKET_FLAG_LIST)
406 if (silc_buffer_len(&packet->buffer) < 1)
409 status = (SilcStatus)packet->buffer.data[0];
410 if (silc_buffer_len(&packet->buffer) > 1 &&
411 silc_utf8_valid(packet->buffer.data + 1,
412 silc_buffer_len(&packet->buffer) - 1))
413 message = silc_memdup(packet->buffer.data + 1,
414 silc_buffer_len(&packet->buffer) - 1);
416 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
417 NULL, &hostname, &ip, NULL))
420 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
421 silc_get_status_message(status), status,
422 message ? message : ""));
426 /* Do not switch to backup in case of error */
427 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
429 /* If backup disconnected then mark that resuming will not be allowed */
430 if (server->server_type == SILC_ROUTER && !server->backup_router &&
431 idata->conn_type == SILC_CONN_SERVER) {
432 SilcServerEntry server_entry = (SilcServerEntry)idata;
433 if (server_entry->server_type == SILC_BACKUP_ROUTER)
434 server->backup_closed = TRUE;
437 /* Handle the disconnection from our end too */
438 if (SILC_IS_LOCAL(idata))
439 silc_server_free_sock_user_data(server, sock, NULL);
440 silc_server_close_connection(server, sock);
441 server->backup_noswitch = FALSE;
445 case SILC_PACKET_CHANNEL_KEY:
447 * Received key for channel. As channels are created by the router
448 * the keys are as well. We will distribute the key to all of our
449 * locally connected clients on the particular channel. Router
450 * never receives this channel and thus is ignored.
452 if (packet->flags & SILC_PACKET_FLAG_LIST)
454 silc_server_channel_key(server, sock, packet);
457 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
459 * Private message key packet.
461 if (packet->flags & SILC_PACKET_FLAG_LIST)
463 silc_server_private_message_key(server, sock, packet);
466 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
468 * Connection authentication request packet. When we receive this packet
469 * we will send to the other end information about our mandatory
470 * authentication method for the connection. This packet maybe received
473 if (packet->flags & SILC_PACKET_FLAG_LIST)
475 silc_server_connection_auth_request(server, sock, packet);
478 case SILC_PACKET_NEW_ID:
480 * Received New ID packet. This includes some new ID that has been
481 * created. It may be for client, server or channel. This is the way
482 * to distribute information about new registered entities in the
485 if (packet->flags & SILC_PACKET_FLAG_LIST)
486 silc_server_new_id_list(server, sock, packet);
488 silc_server_new_id(server, sock, packet);
491 case SILC_PACKET_NEW_CLIENT:
493 * Received new client packet. This includes client information that
494 * we will use to create initial client ID. After creating new
495 * ID we will send it to the client.
497 if (packet->flags & SILC_PACKET_FLAG_LIST)
499 silc_server_new_client(server, sock, packet);
502 case SILC_PACKET_NEW_SERVER:
504 * Received new server packet. This includes Server ID and some other
505 * information that we may save. This is received after server has
508 if (packet->flags & SILC_PACKET_FLAG_LIST)
510 silc_server_new_server(server, sock, packet);
513 case SILC_PACKET_NEW_CHANNEL:
515 * Received new channel packet. Information about new channel in the
516 * network are distributed using this packet.
518 if (packet->flags & SILC_PACKET_FLAG_LIST)
519 silc_server_new_channel_list(server, sock, packet);
521 silc_server_new_channel(server, sock, packet);
524 case SILC_PACKET_HEARTBEAT:
526 * Received heartbeat.
528 if (packet->flags & SILC_PACKET_FLAG_LIST)
532 case SILC_PACKET_KEY_AGREEMENT:
534 * Received heartbeat.
536 if (packet->flags & SILC_PACKET_FLAG_LIST)
538 silc_server_key_agreement(server, sock, packet);
541 case SILC_PACKET_REKEY:
543 * Received re-key packet. The sender wants to regenerate the session
546 if (packet->flags & SILC_PACKET_FLAG_LIST)
548 silc_server_rekey(server, sock, packet);
551 case SILC_PACKET_FTP:
553 if (packet->flags & SILC_PACKET_FLAG_LIST)
555 silc_server_ftp(server, sock, packet);
558 case SILC_PACKET_RESUME_CLIENT:
560 if (packet->flags & SILC_PACKET_FLAG_LIST)
562 silc_server_resume_client(server, sock, packet);
565 case SILC_PACKET_RESUME_ROUTER:
566 /* Resume router packet received. This packet is received for backup
567 router resuming protocol. */
568 if (packet->flags & SILC_PACKET_FLAG_LIST)
570 silc_server_backup_resume_router(server, sock, packet);
574 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
579 /****************************** Server API **********************************/
581 /* Allocates a new SILC server object. This has to be done before the server
582 can be used. After allocation one must call silc_server_init to initialize
583 the server. The new allocated server object is returned to the new_server
586 SilcBool silc_server_alloc(SilcServer *new_server)
590 SILC_LOG_DEBUG(("Allocating new server object"));
592 server = silc_calloc(1, sizeof(*server));
595 server->server_type = SILC_SERVER;
596 server->standalone = TRUE;
597 server->local_list = silc_calloc(1, sizeof(*server->local_list));
598 if (!server->local_list)
600 server->global_list = silc_calloc(1, sizeof(*server->global_list));
601 if (!server->global_list)
603 server->pending_commands = silc_dlist_init();
604 if (!server->pending_commands)
606 server->listeners = silc_dlist_init();
607 if (!server->listeners)
609 server->repository = silc_skr_alloc();
610 if (!server->repository)
612 server->conns = silc_dlist_init();
615 server->expired_clients = silc_dlist_init();
616 if (!server->expired_clients)
619 *new_server = server;
624 /* Free's the SILC server object. This is called at the very end before
627 void silc_server_free(SilcServer server)
630 SilcIDCacheEntry cache;
631 SilcIDListData idata;
633 SILC_LOG_DEBUG(("Free server %p", server));
638 silc_server_backup_free(server);
639 silc_server_config_unref(&server->config_ref);
641 silc_rng_free(server->rng);
642 if (server->public_key)
643 silc_pkcs_public_key_free(server->public_key);
644 if (server->private_key)
645 silc_pkcs_private_key_free(server->private_key);
646 if (server->pending_commands)
647 silc_dlist_uninit(server->pending_commands);
648 if (server->id_entry) {
649 if (server->id_entry->data.sconn)
650 silc_schedule_task_del_by_context(server->schedule,
651 server->id_entry->data.sconn->sock);
652 silc_idlist_del_server(server->local_list, server->id_entry);
655 /* Delete all channels */
656 if (silc_idcache_get_all(server->local_list->channels, &list)) {
657 silc_list_start(list);
658 while ((cache = silc_list_get(list)))
659 silc_idlist_del_channel(server->local_list, cache->context);
661 if (silc_idcache_get_all(server->global_list->channels, &list)) {
662 silc_list_start(list);
663 while ((cache = silc_list_get(list)))
664 silc_idlist_del_channel(server->global_list, cache->context);
667 /* Delete all clients */
668 if (silc_idcache_get_all(server->local_list->clients, &list)) {
669 silc_list_start(list);
670 while ((cache = silc_list_get(list))) {
671 silc_schedule_task_del_by_context(server->schedule, cache->context);
672 silc_idlist_del_client(server->local_list, cache->context);
675 if (silc_idcache_get_all(server->global_list->clients, &list)) {
676 silc_list_start(list);
677 while ((cache = silc_list_get(list))) {
678 silc_schedule_task_del_by_context(server->schedule, cache->context);
679 silc_idlist_del_client(server->global_list, cache->context);
683 /* Delete all servers */
684 if (silc_idcache_get_all(server->local_list->servers, &list)) {
685 silc_list_start(list);
686 while ((cache = silc_list_get(list))) {
687 idata = (SilcIDListData)cache->context;
689 silc_schedule_task_del_by_context(server->schedule,
691 silc_idlist_del_server(server->local_list, cache->context);
694 if (silc_idcache_get_all(server->global_list->servers, &list)) {
695 while ((cache = silc_list_get(list))) {
696 idata = (SilcIDListData)cache->context;
698 silc_schedule_task_del_by_context(server->schedule,
700 silc_idlist_del_server(server->global_list, cache->context);
704 silc_schedule_task_del_by_context(server->schedule, server);
705 silc_schedule_uninit(server->schedule);
706 server->schedule = NULL;
708 silc_idcache_free(server->local_list->clients);
709 silc_idcache_free(server->local_list->servers);
710 silc_idcache_free(server->local_list->channels);
711 silc_idcache_free(server->global_list->clients);
712 silc_idcache_free(server->global_list->servers);
713 silc_idcache_free(server->global_list->channels);
714 silc_hash_table_free(server->watcher_list);
715 silc_hash_table_free(server->watcher_list_pk);
716 silc_hash_free(server->md5hash);
717 silc_hash_free(server->sha1hash);
719 silc_dlist_uninit(server->listeners);
720 silc_dlist_uninit(server->conns);
721 silc_dlist_uninit(server->expired_clients);
722 silc_skr_free(server->repository);
723 silc_packet_engine_stop(server->packet_engine);
725 silc_free(server->local_list);
726 silc_free(server->global_list);
727 silc_free(server->server_name);
728 silc_free(server->id);
731 silc_hmac_unregister_all();
732 silc_hash_unregister_all();
733 silc_cipher_unregister_all();
734 silc_pkcs_unregister_all();
737 /* Creates a new server listener. */
739 static SilcNetListener
740 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
742 SilcNetListener listener;
745 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
746 server->config->require_reverse_lookup,
748 silc_server_accept_new_connection, server);
750 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
758 /* Adds a secondary listener. */
760 SilcBool silc_server_init_secondary(SilcServer server)
762 SilcServerConfigServerInfoInterface *interface;
763 SilcNetListener listener;
765 for (interface = server->config->server_info->secondary; interface;
766 interface = interface->next) {
767 listener = silc_server_listen(server, interface->server_ip,
771 silc_dlist_add(server->listeners, listener);
777 /* Initializes the entire SILC server. This is called always before running
778 the server. This is called only once at the initialization of the program.
779 This binds the server to its listenning port. After this function returns
780 one should call silc_server_run to start the server. This returns TRUE
781 when everything is ok to run the server. Configuration file must be
782 read and parsed before calling this. */
784 SilcBool silc_server_init(SilcServer server)
787 SilcServerEntry id_entry;
788 SilcNetListener listener;
792 SILC_LOG_DEBUG(("Initializing server"));
794 server->starttime = time(NULL);
796 /* Take config object for us */
797 silc_server_config_ref(&server->config_ref, server->config,
801 /* Set debugging on if configured */
802 if (server->config->debug_string) {
803 silc_log_debug(TRUE);
804 silc_log_set_debug_string(server->config->debug_string);
806 #endif /* SILC_DEBUG */
808 /* Steal public and private key from the config object */
809 server->public_key = server->config->server_info->public_key;
810 server->private_key = server->config->server_info->private_key;
811 server->config->server_info->public_key = NULL;
812 server->config->server_info->private_key = NULL;
814 /* Register all configured ciphers, PKCS and hash functions. */
815 if (!silc_server_config_register_ciphers(server))
816 silc_cipher_register_default();
817 if (!silc_server_config_register_pkcs(server))
818 silc_pkcs_register_default();
819 if (!silc_server_config_register_hashfuncs(server))
820 silc_hash_register_default();
821 if (!silc_server_config_register_hmacs(server))
822 silc_hmac_register_default();
824 /* Initialize random number generator for the server. */
825 server->rng = silc_rng_alloc();
826 silc_rng_init(server->rng);
827 silc_rng_global_init(server->rng);
829 /* Initialize hash functions for server to use */
830 silc_hash_alloc("md5", &server->md5hash);
831 silc_hash_alloc("sha1", &server->sha1hash);
833 /* Initialize the scheduler */
834 server->schedule = silc_schedule_init(server->config->param.connections_max,
836 if (!server->schedule)
839 /* First, register log files configuration for error output */
840 silc_server_config_setlogfiles(server);
842 /* Initialize ID caches */
843 server->local_list->clients =
844 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
846 server->local_list->servers =
847 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
849 server->local_list->channels =
850 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
853 /* These are allocated for normal server as well as these hold some
854 global information that the server has fetched from its router. For
855 router these are used as they are supposed to be used on router. */
856 server->global_list->clients =
857 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
859 server->global_list->servers =
860 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
862 server->global_list->channels =
863 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
866 /* Init watcher lists */
867 server->watcher_list =
868 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
869 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
871 if (!server->watcher_list)
873 server->watcher_list_pk =
874 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
875 silc_hash_public_key_compare, NULL,
877 if (!server->watcher_list_pk)
880 /* Create TCP listener */
881 listener = silc_server_listen(
883 server->config->server_info->primary == NULL ? NULL :
884 server->config->server_info->primary->server_ip,
885 server->config->server_info->primary == NULL ? 0 :
886 server->config->server_info->primary->port);
889 silc_dlist_add(server->listeners, listener);
891 /* Create a Server ID for the server. */
892 port = silc_net_listener_get_port(listener, NULL);
893 ip = silc_net_listener_get_ip(listener, NULL);
894 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
895 server->config->server_info->primary->public_ip :
896 ip[0], port[0], server->rng, &id);
905 server->server_name = server->config->server_info->server_name;
906 server->config->server_info->server_name = NULL;
907 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
908 sizeof(server->id_string), &server->id_string_len);
910 /* Add ourselves to the server list. We don't have a router yet
911 beacuse we haven't established a route yet. It will be done later.
912 For now, NULL is sent as router. This allocates new entry to
915 silc_idlist_add_server(server->local_list, strdup(server->server_name),
917 silc_id_dup(server->id, SILC_ID_SERVER),
920 SILC_LOG_ERROR(("Could not add local server to cache"));
923 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
924 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
925 SILC_CONN_SERVER : SILC_CONN_ROUTER);
926 server->id_entry = id_entry;
928 /* Create secondary TCP listeners */
929 if (silc_server_init_secondary(server) == FALSE)
932 server->listenning = TRUE;
934 /* Create connections to configured routers. */
935 silc_server_create_connections(server);
937 /* If server connections has been configured then we must be router as
938 normal server cannot have server connections, only router connections. */
939 if (server->config->servers) {
940 SilcServerConfigServer *ptr = server->config->servers;
942 server->server_type = SILC_ROUTER;
944 if (ptr->backup_router) {
945 server->server_type = SILC_BACKUP_ROUTER;
946 server->backup_router = TRUE;
947 server->id_entry->server_type = SILC_BACKUP_ROUTER;
954 if (server->server_type != SILC_ROUTER) {
955 server->stat.servers = 1;
956 server->stat.cell_servers = 1;
958 server->stat.routers = 1;
961 /* If we are normal server we'll retrieve network statisticial information
962 once in a while from the router. */
963 if (server->server_type != SILC_ROUTER)
964 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
967 /* Start packet engine */
968 server->packet_engine =
969 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
970 &silc_server_stream_cbs, server);
971 if (!server->packet_engine)
974 /* Register client entry expiration timeout */
975 silc_schedule_task_add_timeout(server->schedule,
976 silc_server_purge_expired_clients, server,
979 /* Initialize HTTP server */
980 silc_server_http_init(server);
982 SILC_LOG_DEBUG(("Server initialized"));
984 /* We are done here, return succesfully */
988 silc_server_config_unref(&server->config_ref);
992 /* Task callback to close a socket connection after rehash */
994 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
996 SilcServer server = app_context;
997 SilcPacketStream sock = context;
998 SilcIDListData idata = silc_packet_get_context(sock);
999 const char *hostname;
1002 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1003 NULL, &hostname, NULL, &port);
1005 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
1006 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
1007 silc_schedule_task_del_by_context(server->schedule, sock);
1008 silc_server_disconnect_remote(server, sock,
1009 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1010 "This connection is removed from "
1012 silc_server_free_sock_user_data(server, sock, NULL);
1015 /* This function basically reads the config file again and switches the config
1016 object pointed by the server object. After that, we have to fix various
1017 things such as the server_name and the listening ports.
1018 Keep in mind that we no longer have the root privileges at this point. */
1020 SilcBool silc_server_rehash(SilcServer server)
1022 SilcServerConfig newconfig;
1024 SILC_LOG_INFO(("Rehashing server"));
1026 /* Reset the logging system */
1027 silc_log_quick(TRUE);
1028 silc_log_flush_all();
1030 /* Start the main rehash phase (read again the config file) */
1031 newconfig = silc_server_config_alloc(server->config_file, server);
1033 SILC_LOG_ERROR(("Rehash FAILED."));
1037 /* Fix the server_name field */
1038 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1039 silc_free(server->server_name);
1041 /* Check server name */
1042 server->server_name =
1043 silc_identifier_check(newconfig->server_info->server_name,
1044 strlen(newconfig->server_info->server_name),
1045 SILC_STRING_LOCALE, 256, NULL);
1046 if (!server->server_name) {
1047 SILC_LOG_ERROR(("Malformed server name string '%s'",
1048 server->config->server_info->server_name));
1052 /* Update the idcache list with a fresh pointer */
1053 silc_free(server->id_entry->server_name);
1054 server->id_entry->server_name = strdup(server->server_name);
1055 silc_idcache_update_by_context(server->local_list->servers,
1056 server->id_entry, NULL,
1057 strdup(server->id_entry->server_name),
1062 silc_server_config_setlogfiles(server);
1064 /* Change new key pair if necessary */
1065 if (newconfig->server_info->public_key &&
1066 !silc_pkcs_public_key_compare(server->public_key,
1067 newconfig->server_info->public_key)) {
1068 silc_pkcs_public_key_free(server->public_key);
1069 silc_pkcs_private_key_free(server->private_key);
1070 server->public_key = newconfig->server_info->public_key;
1071 server->private_key = newconfig->server_info->private_key;
1072 newconfig->server_info->public_key = NULL;
1073 newconfig->server_info->private_key = NULL;
1076 /* Check for unconfigured server and router connections and close
1077 connections that were unconfigured. */
1079 if (server->config->routers) {
1080 SilcServerConfigRouter *ptr;
1081 SilcServerConfigRouter *newptr;
1084 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1087 /* Check whether new config has this one too */
1088 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1089 if (silc_string_compare(newptr->host, ptr->host) &&
1090 newptr->port == ptr->port &&
1091 newptr->initiator == ptr->initiator) {
1097 if (!found && ptr->host) {
1098 /* Remove this connection */
1099 SilcPacketStream sock;
1100 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1101 ptr->host, ptr->port);
1103 silc_schedule_task_add_timeout(server->schedule,
1104 silc_server_rehash_close_connection,
1110 if (server->config->servers) {
1111 SilcServerConfigServer *ptr;
1112 SilcServerConfigServer *newptr;
1115 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1118 /* Check whether new config has this one too */
1119 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1120 if (silc_string_compare(newptr->host, ptr->host)) {
1126 if (!found && ptr->host) {
1127 /* Remove this connection */
1128 SilcPacketStream sock;
1129 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1132 silc_schedule_task_add_timeout(server->schedule,
1133 silc_server_rehash_close_connection,
1139 if (server->config->clients) {
1140 SilcServerConfigClient *ptr;
1141 SilcServerConfigClient *newptr;
1144 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1147 /* Check whether new config has this one too */
1148 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1149 if (silc_string_compare(newptr->host, ptr->host)) {
1155 if (!found && ptr->host) {
1156 /* Remove this connection */
1157 SilcPacketStream sock;
1158 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1161 silc_schedule_task_add_timeout(server->schedule,
1162 silc_server_rehash_close_connection,
1168 /* Create connections after rehash */
1169 silc_server_create_connections(server);
1171 /* Check whether our router status has changed */
1172 if (newconfig->servers) {
1173 SilcServerConfigServer *ptr = newconfig->servers;
1175 server->server_type = SILC_ROUTER;
1177 if (ptr->backup_router) {
1178 server->server_type = SILC_BACKUP_ROUTER;
1179 server->backup_router = TRUE;
1180 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1187 /* Our old config is gone now. We'll unreference our reference made in
1188 silc_server_init and then destroy it since we are destroying it
1189 underneath the application (layer which called silc_server_init). */
1190 silc_server_config_unref(&server->config_ref);
1191 silc_server_config_destroy(server->config);
1193 /* Take new config context */
1194 server->config = newconfig;
1195 silc_server_config_ref(&server->config_ref, server->config, server->config);
1198 /* Set debugging on if configured */
1199 if (server->config->debug_string) {
1200 silc_log_debug(TRUE);
1201 silc_log_set_debug_string(server->config->debug_string);
1203 #endif /* SILC_DEBUG */
1205 SILC_LOG_DEBUG(("Server rehashed"));
1210 /* The heart of the server. This runs the scheduler thus runs the server.
1211 When this returns the server has been stopped and the program will
1214 void silc_server_run(SilcServer server)
1216 SILC_LOG_INFO(("SILC Server started"));
1218 /* Start the scheduler, the heart of the SILC server. When this returns
1219 the program will be terminated. */
1220 silc_schedule(server->schedule);
1223 /* Stops the SILC server. This function is used to shutdown the server.
1224 This is usually called after the scheduler has returned. After stopping
1225 the server one should call silc_server_free. */
1227 void silc_server_stop(SilcServer server)
1230 SilcPacketStream ps;
1231 SilcNetListener listener;
1233 SILC_LOG_INFO(("SILC Server shutting down"));
1235 server->server_shutdown = TRUE;
1237 /* Close all connections */
1238 if (server->packet_engine) {
1239 list = silc_packet_engine_get_streams(server->packet_engine);
1241 silc_dlist_start(list);
1242 while ((ps = silc_dlist_get(list))) {
1243 SilcIDListData idata = silc_packet_get_context(ps);
1245 if (!silc_packet_stream_is_valid(ps))
1249 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1251 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1252 "Server is shutting down");
1253 silc_server_free_sock_user_data(server, ps,
1254 "Server is shutting down");
1256 silc_packet_engine_free_streams_list(list);
1259 /* We are not connected to network anymore */
1260 server->standalone = TRUE;
1262 silc_dlist_start(server->listeners);
1263 while ((listener = silc_dlist_get(server->listeners)))
1264 silc_net_close_listener(listener);
1266 silc_server_http_uninit(server);
1268 /* Cancel any possible retry timeouts */
1269 silc_schedule_task_del_by_callback(server->schedule,
1270 silc_server_connect_router);
1271 silc_schedule_task_del_by_callback(server->schedule,
1272 silc_server_connect_to_router_retry);
1273 silc_schedule_task_del_by_callback(server->schedule,
1274 silc_server_connect_to_router);
1276 silc_schedule_stop(server->schedule);
1278 SILC_LOG_DEBUG(("Server stopped"));
1281 /* Purge expired client entries from the server */
1283 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1285 SilcServer server = context;
1286 SilcClientEntry client;
1288 SilcUInt64 curtime = silc_time();
1290 SILC_LOG_DEBUG(("Expire timeout"));
1292 silc_dlist_start(server->expired_clients);
1293 while ((client = silc_dlist_get(server->expired_clients))) {
1294 /* For unregistered clients the created timestamp is actually
1295 unregistered timestamp. Make sure client remains in history
1296 at least 500 seconds. */
1297 if (client->data.created && curtime - client->data.created < 500)
1300 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1301 server->local_list : server->global_list);
1303 silc_idlist_del_data(client);
1304 silc_idlist_del_client(id_list, client);
1305 silc_dlist_del(server->expired_clients, client);
1308 silc_schedule_task_add_timeout(server->schedule,
1309 silc_server_purge_expired_clients, server,
1314 /******************************* Connecting *********************************/
1316 /* Free connection context */
1318 void silc_server_connection_free(SilcServerConnection sconn)
1322 SILC_LOG_DEBUG(("Free connection %p", sconn));
1323 silc_dlist_del(sconn->server->conns, sconn);
1324 silc_server_config_unref(&sconn->conn);
1325 silc_free(sconn->remote_host);
1326 silc_free(sconn->backup_replace_ip);
1330 /* Creates connection to a remote router. */
1332 void silc_server_create_connection(SilcServer server,
1335 const char *remote_host, SilcUInt32 port,
1336 SilcServerConnectCallback callback,
1339 SilcServerConnection sconn;
1341 /* Allocate connection object for hold connection specific stuff. */
1342 sconn = silc_calloc(1, sizeof(*sconn));
1345 sconn->remote_host = strdup(remote_host);
1346 sconn->remote_port = port;
1347 sconn->no_reconnect = reconnect == FALSE;
1348 sconn->callback = callback;
1349 sconn->callback_context = context;
1350 sconn->no_conf = dynamic;
1351 sconn->server = server;
1353 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1354 remote_host, port));
1356 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1360 /* Connection authentication completion callback */
1363 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1366 SilcServerConnection sconn = context;
1367 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1368 SilcServer server = entry->server;
1369 SilcServerConfigServer *conn;
1370 SilcServerConfigConnParams *param;
1371 SilcIDListData idata;
1372 SilcServerEntry id_entry = NULL;
1373 unsigned char id[32];
1378 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1383 if (success == FALSE) {
1384 /* Authentication failed */
1386 /* Try reconnecting if configuration wants it */
1387 if (!sconn->no_reconnect) {
1388 silc_schedule_task_add_timeout(server->schedule,
1389 silc_server_connect_to_router_retry,
1391 silc_dlist_del(server->conns, sconn);
1395 if (sconn->callback)
1396 (*sconn->callback)(server, NULL, sconn->callback_context);
1397 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1398 silc_server_disconnect_remote(server, sconn->sock,
1399 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1403 /* XXX For now remote is router always */
1404 entry->data.conn_type = SILC_CONN_ROUTER;
1406 SILC_LOG_INFO(("Connected to %s %s",
1407 SILC_CONNTYPE_STRING(entry->data.conn_type),
1408 sconn->remote_host));
1410 /* Create the actual entry for remote entity */
1411 switch (entry->data.conn_type) {
1412 case SILC_CONN_SERVER:
1413 SILC_LOG_DEBUG(("Remote is SILC server"));
1415 /* Add new server. The server must register itself to us before it
1416 becomes registered to SILC network. */
1417 id_entry = silc_idlist_add_server(server->local_list,
1418 strdup(sconn->remote_host),
1419 SILC_SERVER, NULL, NULL, sconn->sock);
1421 if (sconn->callback)
1422 (*sconn->callback)(server, NULL, sconn->callback_context);
1423 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1424 silc_server_disconnect_remote(server, sconn->sock,
1425 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1430 server->stat.my_servers++;
1431 if (server->server_type == SILC_ROUTER)
1432 server->stat.servers++;
1433 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1435 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1438 case SILC_CONN_ROUTER:
1439 SILC_LOG_DEBUG(("Remote is SILC router"));
1441 /* Register to network */
1442 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1443 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1444 SILC_STR_UI_SHORT(id_len),
1445 SILC_STR_DATA(id, id_len),
1446 SILC_STR_UI_SHORT(strlen(server->server_name)),
1447 SILC_STR_DATA(server->server_name,
1448 strlen(server->server_name)),
1450 if (sconn->callback)
1451 (*sconn->callback)(server, NULL, sconn->callback_context);
1452 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1453 silc_server_disconnect_remote(server, sconn->sock,
1454 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1459 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1461 /* Check that we do not have this ID already */
1462 id_entry = silc_idlist_find_server_by_id(server->local_list,
1463 &remote_id.u.server_id,
1466 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1468 id_entry = silc_idlist_find_server_by_id(server->global_list,
1469 &remote_id.u.server_id,
1472 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1476 SILC_LOG_DEBUG(("New server id(%s)",
1477 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1479 /* Add the connected router to global server list. Router is sent
1480 as NULL since it's local to us. */
1481 id_entry = silc_idlist_add_server(server->global_list,
1482 strdup(sconn->remote_host),
1484 silc_id_dup(&remote_id.u.server_id,
1488 /* Try reconnecting if configuration wants it */
1489 if (!sconn->no_reconnect) {
1490 silc_schedule_task_add_timeout(server->schedule,
1491 silc_server_connect_to_router_retry,
1493 silc_dlist_del(server->conns, sconn);
1497 if (sconn->callback)
1498 (*sconn->callback)(server, NULL, sconn->callback_context);
1499 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1500 silc_server_disconnect_remote(server, sconn->sock,
1501 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1506 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1507 idata = (SilcIDListData)id_entry;
1508 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1509 SILC_IDLIST_STATUS_LOCAL);
1510 idata->sconn = sconn;
1511 idata->sconn->callback = NULL;
1514 server->stat.my_routers++;
1515 if (server->server_type == SILC_ROUTER)
1516 server->stat.routers++;
1517 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1519 if (!sconn->backup) {
1520 /* Mark this router our primary router if we're still standalone */
1521 if (server->standalone) {
1522 SILC_LOG_DEBUG(("This connection is our primary router"));
1523 server->id_entry->router = id_entry;
1524 server->router = id_entry;
1525 server->router->server_type = SILC_ROUTER;
1526 server->standalone = FALSE;
1527 server->backup_primary = FALSE;
1529 /* Announce data if we are not backup router (unless not as primary
1530 currently). Backup router announces later at the end of
1531 resuming protocol. */
1532 if (server->backup_router && server->server_type == SILC_ROUTER) {
1533 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1535 /* If we are router then announce our possible servers. Backup
1536 router announces also global servers. */
1537 if (server->server_type == SILC_ROUTER)
1538 silc_server_announce_servers(server,
1539 server->backup_router ? TRUE : FALSE,
1540 0, SILC_PRIMARY_ROUTE(server));
1542 /* Announce our clients and channels to the router */
1543 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1544 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1547 /* If we are backup router then this primary router is whom we are
1549 if (server->server_type == SILC_BACKUP_ROUTER) {
1550 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1552 NULL, NULL, &ip, NULL);
1553 silc_server_backup_add(server, server->id_entry, ip,
1554 sconn->remote_port, TRUE);
1559 /* We already have primary router. Disconnect this connection */
1560 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1561 silc_idlist_del_server(server->global_list, id_entry);
1562 if (sconn->callback)
1563 (*sconn->callback)(server, NULL, sconn->callback_context);
1564 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1565 silc_server_disconnect_remote(server, sconn->sock,
1566 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1571 /* Add this server to be our backup router */
1572 id_entry->server_type = SILC_BACKUP_ROUTER;
1573 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1574 sconn->backup_replace_port, FALSE);
1580 if (sconn->callback)
1581 (*sconn->callback)(server, NULL, sconn->callback_context);
1582 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1583 silc_server_disconnect_remote(server, sconn->sock,
1584 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1588 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1590 conn = sconn->conn.ref_ptr;
1591 param = &server->config->param;
1592 if (conn && conn->param)
1593 param = conn->param;
1595 /* Register rekey timeout */
1596 sconn->rekey_timeout = param->key_exchange_rekey;
1597 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1598 sconn->sock, sconn->rekey_timeout, 0);
1600 /* Set the entry as packet stream context */
1601 silc_packet_set_context(sconn->sock, id_entry);
1603 /* Call the completion callback to indicate that we've connected to
1605 if (sconn && sconn->callback)
1606 (*sconn->callback)(server, id_entry, sconn->callback_context);
1608 if (sconn == server->router_conn)
1609 server->router_conn = NULL;
1614 /* SKE completion callback */
1616 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1617 SilcSKESecurityProperties prop,
1618 SilcSKEKeyMaterial keymat,
1619 SilcSKERekeyMaterial rekey,
1622 SilcPacketStream sock = context;
1623 SilcUnknownEntry entry = silc_packet_get_context(sock);
1624 SilcServerConnection sconn;
1626 SilcServerConfigRouter *conn;
1627 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1628 void *auth_data = NULL;
1629 SilcUInt32 auth_data_len = 0;
1630 SilcConnAuth connauth;
1631 SilcCipher send_key, receive_key;
1632 SilcHmac hmac_send, hmac_receive;
1634 server = entry->server;
1635 sconn = entry->data.sconn;
1636 conn = sconn->conn.ref_ptr;
1639 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1641 if (status != SILC_SKE_STATUS_OK) {
1643 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1644 silc_ske_map_status(status), entry->hostname, entry->ip));
1647 /* Try reconnecting if configuration wants it */
1648 if (!sconn->no_reconnect) {
1649 silc_schedule_task_add_timeout(server->schedule,
1650 silc_server_connect_to_router_retry,
1652 silc_dlist_del(server->conns, sconn);
1656 if (sconn->callback)
1657 (*sconn->callback)(server, NULL, sconn->callback_context);
1658 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1659 silc_server_disconnect_remote(server, sconn->sock,
1660 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1664 SILC_LOG_DEBUG(("Setting keys into use"));
1666 /* Set the keys into use. The data will be encrypted after this. */
1667 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1668 &hmac_send, &hmac_receive, NULL)) {
1671 /* Try reconnecting if configuration wants it */
1672 if (!sconn->no_reconnect) {
1673 silc_schedule_task_add_timeout(server->schedule,
1674 silc_server_connect_to_router_retry,
1676 silc_dlist_del(server->conns, sconn);
1680 /* Error setting keys */
1681 if (sconn->callback)
1682 (*sconn->callback)(server, NULL, sconn->callback_context);
1683 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1684 silc_server_disconnect_remote(server, sconn->sock,
1685 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1688 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1689 hmac_receive, FALSE);
1691 SILC_LOG_DEBUG(("Starting connection authentication"));
1693 connauth = silc_connauth_alloc(server->schedule, ske,
1694 server->config->conn_auth_timeout);
1698 /* Try reconnecting if configuration wants it */
1699 if (!sconn->no_reconnect) {
1700 silc_schedule_task_add_timeout(server->schedule,
1701 silc_server_connect_to_router_retry,
1703 silc_dlist_del(server->conns, sconn);
1707 /** Error allocating auth protocol */
1708 if (sconn->callback)
1709 (*sconn->callback)(server, NULL, sconn->callback_context);
1710 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1711 silc_server_disconnect_remote(server, sconn->sock,
1712 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1716 /* Get authentication method */
1718 if (conn->passphrase) {
1719 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1720 auth_meth = SILC_AUTH_PUBLIC_KEY;
1721 auth_data = server->private_key;
1723 auth_meth = SILC_AUTH_PASSWORD;
1724 auth_data = conn->passphrase;
1725 auth_data_len = conn->passphrase_len;
1728 auth_meth = SILC_AUTH_PUBLIC_KEY;
1729 auth_data = server->private_key;
1733 entry->data.rekey = rekey;
1735 /* Start connection authentication */
1737 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1738 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1739 auth_data, auth_data_len,
1740 silc_server_ke_auth_compl, sconn);
1743 /* Function that is called when the network connection to a router has
1744 been established. This will continue with the key exchange protocol
1745 with the remote router. */
1747 void silc_server_start_key_exchange(SilcServerConnection sconn)
1749 SilcServer server = sconn->server;
1750 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1751 SilcUnknownEntry entry;
1752 SilcSKEParamsStruct params;
1755 /* Cancel any possible retry timeouts */
1756 silc_schedule_task_del_by_context(server->schedule, sconn);
1758 /* Create packet stream */
1759 sconn->sock = silc_packet_stream_create(server->packet_engine,
1760 server->schedule, sconn->stream);
1762 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1763 silc_stream_destroy(sconn->stream);
1765 /* Try reconnecting if configuration wants it */
1766 if (!sconn->no_reconnect) {
1767 silc_schedule_task_add_timeout(server->schedule,
1768 silc_server_connect_to_router_retry,
1770 silc_dlist_del(server->conns, sconn);
1774 if (sconn->callback)
1775 (*sconn->callback)(server, NULL, sconn->callback_context);
1776 silc_server_connection_free(sconn);
1779 server->stat.conn_num++;
1781 /* Set source ID to packet stream */
1782 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1784 silc_packet_stream_destroy(sconn->sock);
1786 /* Try reconnecting if configuration wants it */
1787 if (!sconn->no_reconnect) {
1788 silc_schedule_task_add_timeout(server->schedule,
1789 silc_server_connect_to_router_retry,
1791 silc_dlist_del(server->conns, sconn);
1795 if (sconn->callback)
1796 (*sconn->callback)(server, NULL, sconn->callback_context);
1797 silc_server_connection_free(sconn);
1801 /* Create entry for remote entity */
1802 entry = silc_calloc(1, sizeof(*entry));
1804 silc_packet_stream_destroy(sconn->sock);
1806 /* Try reconnecting if configuration wants it */
1807 if (!sconn->no_reconnect) {
1808 silc_schedule_task_add_timeout(server->schedule,
1809 silc_server_connect_to_router_retry,
1811 silc_dlist_del(server->conns, sconn);
1815 if (sconn->callback)
1816 (*sconn->callback)(server, NULL, sconn->callback_context);
1817 silc_server_connection_free(sconn);
1820 entry->server = server;
1821 entry->data.sconn = sconn;
1822 entry->data.conn_type = SILC_CONN_UNKNOWN;
1823 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1824 silc_packet_set_context(sconn->sock, entry);
1826 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1828 /* Set Key Exchange flags from configuration, but fall back to global
1830 memset(¶ms, 0, sizeof(params));
1831 SILC_GET_SKE_FLAGS(conn, params.flags);
1832 if (server->config->param.key_exchange_pfs)
1833 params.flags |= SILC_SKE_SP_FLAG_PFS;
1835 /* Start SILC Key Exchange protocol */
1836 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1837 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1838 server->public_key, server->private_key, sconn);
1841 silc_packet_stream_destroy(sconn->sock);
1843 /* Try reconnecting if configuration wants it */
1844 if (!sconn->no_reconnect) {
1845 silc_schedule_task_add_timeout(server->schedule,
1846 silc_server_connect_to_router_retry,
1848 silc_dlist_del(server->conns, sconn);
1852 if (sconn->callback)
1853 (*sconn->callback)(server, NULL, sconn->callback_context);
1854 silc_server_connection_free(sconn);
1857 silc_ske_set_callbacks(ske, silc_server_verify_key,
1858 silc_server_ke_completed, sconn->sock);
1860 /* Start key exchange protocol */
1861 params.version = silc_version_string;
1862 params.timeout_secs = server->config->key_exchange_timeout;
1863 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1866 /* Timeout callback that will be called to retry connecting to remote
1867 router. This is used by both normal and router server. This will wait
1868 before retrying the connecting. The timeout is generated by exponential
1869 backoff algorithm. */
1871 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1873 SilcServerConnection sconn = context;
1874 SilcServer server = sconn->server;
1875 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1876 SilcServerConfigConnParams *param =
1877 (conn->param ? conn->param : &server->config->param);
1879 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1880 sconn->remote_port));
1882 /* Calculate next timeout */
1883 if (sconn->retry_count >= 1) {
1884 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1885 if (sconn->retry_timeout > param->reconnect_interval_max)
1886 sconn->retry_timeout = param->reconnect_interval_max;
1888 sconn->retry_timeout = param->reconnect_interval;
1890 sconn->retry_count++;
1891 sconn->retry_timeout = sconn->retry_timeout +
1892 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1894 /* If we've reached max retry count, give up. */
1895 if ((sconn->retry_count > param->reconnect_count) &&
1896 sconn->no_reconnect) {
1897 SILC_LOG_ERROR(("Could not connect, giving up"));
1899 if (sconn->callback)
1900 (*sconn->callback)(server, NULL, sconn->callback_context);
1901 silc_server_connection_free(sconn);
1905 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1907 /* We will lookup a fresh pointer later */
1908 silc_server_config_unref(&sconn->conn);
1910 /* Wait before retrying */
1911 silc_schedule_task_del_by_context(server->schedule, sconn);
1912 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1913 sconn, sconn->retry_timeout, 0);
1916 /* Callback for async connection to remote router */
1918 static void silc_server_connection_established(SilcNetStatus status,
1922 SilcServerConnection sconn = context;
1923 SilcServer server = sconn->server;
1925 silc_schedule_task_del_by_context(server->schedule, sconn);
1930 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1931 sconn->remote_host, sconn->remote_port));
1933 /* Continue with key exchange protocol */
1934 sconn->stream = stream;
1935 silc_server_start_key_exchange(sconn);
1938 case SILC_NET_UNKNOWN_IP:
1939 case SILC_NET_UNKNOWN_HOST:
1940 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1941 sconn->remote_host, sconn->remote_port,
1942 silc_net_get_error_string(status)));
1943 if (!sconn->no_reconnect) {
1944 silc_schedule_task_add_timeout(sconn->server->schedule,
1945 silc_server_connect_to_router_retry,
1947 silc_dlist_del(server->conns, sconn);
1949 if (sconn->callback)
1950 (*sconn->callback)(server, NULL, sconn->callback_context);
1951 silc_server_connection_free(sconn);
1956 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1957 sconn->remote_host, sconn->remote_port,
1958 silc_net_get_error_string(status)));
1959 if (!sconn->no_reconnect) {
1960 silc_schedule_task_add_timeout(sconn->server->schedule,
1961 silc_server_connect_to_router_retry,
1963 silc_dlist_del(server->conns, sconn);
1965 if (sconn->callback)
1966 (*sconn->callback)(server, NULL, sconn->callback_context);
1967 silc_server_connection_free(sconn);
1973 /* Generic routine to use connect to a router. */
1975 SILC_TASK_CALLBACK(silc_server_connect_router)
1977 SilcServerConnection sconn = context;
1978 SilcServer server = sconn->server;
1979 SilcServerConfigRouter *rconn;
1981 silc_schedule_task_del_by_context(server->schedule, sconn);
1983 /* Don't connect if we are shutting down. */
1984 if (server->server_shutdown) {
1985 if (sconn->callback)
1986 (*sconn->callback)(server, NULL, sconn->callback_context);
1987 silc_server_connection_free(sconn);
1991 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1992 (sconn->backup ? "backup router" : "router"),
1993 sconn->remote_host, sconn->remote_port));
1995 if (!sconn->no_conf) {
1996 /* Find connection configuration */
1997 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1998 sconn->remote_port);
2000 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
2001 (sconn->backup ? "backup router" : "router"),
2002 sconn->remote_host, sconn->remote_port));
2003 if (sconn->callback)
2004 (*sconn->callback)(server, NULL, sconn->callback_context);
2005 silc_server_connection_free(sconn);
2008 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
2011 /* Connect to remote host */
2013 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
2014 server->config->server_info->primary->server_ip),
2015 sconn->remote_host, sconn->remote_port,
2016 server->schedule, silc_server_connection_established,
2019 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2020 sconn->remote_host, sconn->remote_port));
2021 if (sconn->callback)
2022 (*sconn->callback)(server, NULL, sconn->callback_context);
2023 silc_server_connection_free(sconn);
2027 /* Add to connection list */
2028 silc_dlist_add(server->conns, sconn);
2031 /* This function connects to our primary router or if we are a router this
2032 establishes all our primary routes. This is called at the start of the
2033 server to do authentication and key exchange with our router - called
2036 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2038 SilcServer server = context;
2039 SilcServerConnection sconn;
2040 SilcServerConfigRouter *ptr;
2041 SilcServerConfigConnParams *param;
2043 /* Don't connect if we are shutting down. */
2044 if (server->server_shutdown)
2047 SILC_LOG_DEBUG(("We are %s",
2048 (server->server_type == SILC_SERVER ?
2049 "normal server" : server->server_type == SILC_ROUTER ?
2050 "router" : "backup router/normal server")));
2052 if (!server->config->routers) {
2053 /* There wasn't a configured router, we will continue but we don't
2054 have a connection to outside world. We will be standalone server. */
2055 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2056 server->standalone = TRUE;
2060 /* Cancel any possible retry timeouts */
2061 silc_schedule_task_del_by_callback(server->schedule,
2062 silc_server_connect_router);
2063 silc_schedule_task_del_by_callback(server->schedule,
2064 silc_server_connect_to_router_retry);
2066 /* Create the connections to all our routes */
2067 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2069 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2070 ptr->backup_router ? "Backup router" : "Router",
2071 ptr->initiator ? "Initiator" : "Responder",
2072 ptr->host, ptr->port));
2074 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2075 ptr->initiator == FALSE && !server->backup_router &&
2076 !silc_server_config_get_backup_router(server))
2077 server->wait_backup = TRUE;
2079 if (!ptr->initiator)
2081 if (ptr->dynamic_connection)
2084 /* Check whether we are connecting or connected to this host already */
2085 if (silc_server_num_sockets_by_remote(server,
2086 silc_net_is_ip(ptr->host) ?
2088 silc_net_is_ip(ptr->host) ?
2089 NULL : ptr->host, ptr->port,
2090 SILC_CONN_ROUTER)) {
2091 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2092 ptr->host, ptr->port));
2094 /* If we don't have primary router and this connection is our
2095 primary router we are in desync. Reconnect to the primary. */
2096 if (server->standalone && !server->router) {
2098 SilcPacketStream sock;
2099 SilcServerConfigRouter *primary =
2100 silc_server_config_get_primary_router(server);
2103 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2104 ptr->host, ptr->port);
2107 server->backup_noswitch = TRUE;
2108 silc_server_free_sock_user_data(server, sock, NULL);
2109 silc_server_disconnect_remote(server, sock, 0, NULL);
2110 server->backup_noswitch = FALSE;
2111 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2117 param = (ptr->param ? ptr->param : &server->config->param);
2119 /* Allocate connection object for hold connection specific stuff. */
2120 sconn = silc_calloc(1, sizeof(*sconn));
2123 sconn->server = server;
2124 sconn->remote_host = strdup(ptr->host);
2125 sconn->remote_port = ptr->port;
2126 sconn->backup = ptr->backup_router;
2127 if (sconn->backup) {
2128 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2129 sconn->backup_replace_port = ptr->backup_replace_port;
2131 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2133 SILC_LOG_DEBUG(("Created connection %p", sconn));
2135 if (!server->router_conn && !sconn->backup)
2136 server->router_conn = sconn;
2139 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2145 /************************ Accepting new connection **************************/
2147 /* After this is called, server don't wait for backup router anymore.
2148 This gets called automatically even after we have backup router
2149 connection established. */
2151 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2153 SilcServer server = context;
2154 server->wait_backup = FALSE;
2157 /* Authentication data callback */
2160 silc_server_accept_get_auth(SilcConnAuth connauth,
2161 SilcConnectionType conn_type,
2162 unsigned char **passphrase,
2163 SilcUInt32 *passphrase_len,
2164 SilcSKR *repository,
2167 SilcPacketStream sock = context;
2168 SilcUnknownEntry entry = silc_packet_get_context(sock);
2169 SilcServer server = entry->server;
2171 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2173 /* Remote end is client */
2174 if (conn_type == SILC_CONN_CLIENT) {
2175 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2179 *passphrase = cconfig->passphrase;
2180 *passphrase_len = cconfig->passphrase_len;
2181 if (cconfig->publickeys)
2182 *repository = server->repository;
2184 if (cconfig->publickeys) {
2185 if (server->config->prefer_passphrase_auth) {
2189 *passphrase_len = 0;
2193 entry->conn_type = conn_type;
2197 /* Remote end is server */
2198 if (conn_type == SILC_CONN_SERVER) {
2199 SilcServerConfigServer *sconfig;
2201 /* If we are normal server, don't accept the connection */
2202 if (server->server_type == SILC_SERVER)
2205 sconfig = entry->sconfig.ref_ptr;
2209 *passphrase = sconfig->passphrase;
2210 *passphrase_len = sconfig->passphrase_len;
2211 if (sconfig->publickeys)
2212 *repository = server->repository;
2214 if (sconfig->publickeys) {
2215 if (server->config->prefer_passphrase_auth) {
2219 *passphrase_len = 0;
2223 entry->conn_type = conn_type;
2227 /* Remote end is router */
2228 if (conn_type == SILC_CONN_ROUTER) {
2229 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2233 *passphrase = rconfig->passphrase;
2234 *passphrase_len = rconfig->passphrase_len;
2235 if (rconfig->publickeys)
2236 *repository = server->repository;
2238 if (rconfig->publickeys) {
2239 if (server->config->prefer_passphrase_auth) {
2243 *passphrase_len = 0;
2247 entry->conn_type = conn_type;
2254 /* Authentication completion callback. */
2257 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2260 SilcPacketStream sock = context;
2261 SilcUnknownEntry entry = silc_packet_get_context(sock);
2262 SilcIDListData idata = (SilcIDListData)entry;
2263 SilcServer server = entry->server;
2264 SilcServerConfigConnParams *param = &server->config->param;
2265 SilcServerConnection sconn;
2267 const char *hostname, *ip;
2271 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2272 NULL, &hostname, &ip, &port);
2274 if (success == FALSE) {
2275 /* Authentication failed */
2276 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2277 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2278 server->stat.auth_failures++;
2279 silc_server_disconnect_remote(server, sock,
2280 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2281 silc_server_config_unref(&entry->cconfig);
2282 silc_server_config_unref(&entry->sconfig);
2283 silc_server_config_unref(&entry->rconfig);
2284 silc_server_free_sock_user_data(server, sock, NULL);
2288 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2290 switch (entry->conn_type) {
2291 case SILC_CONN_CLIENT:
2293 SilcClientEntry client;
2294 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2296 /* Verify whether this connection is after all allowed to connect */
2297 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2298 &server->config->param,
2300 silc_connauth_get_ske(connauth))) {
2301 server->stat.auth_failures++;
2305 /* If we are primary router and we have backup router configured
2306 but it has not connected to use yet, do not accept any other
2308 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2309 !server->backup_router) {
2310 SilcServerConfigRouter *router;
2311 router = silc_server_config_get_backup_router(server);
2312 if (router && strcmp(server->config->server_info->primary->server_ip,
2314 silc_server_find_socket_by_host(server,
2316 router->backup_replace_ip, 0)) {
2317 SILC_LOG_INFO(("Will not accept connections because we do "
2318 "not have backup router connection established"));
2319 silc_server_disconnect_remote(server, sock,
2320 SILC_STATUS_ERR_PERM_DENIED,
2321 "We do not have connection to backup "
2322 "router established, try later");
2323 silc_server_config_unref(&entry->cconfig);
2324 silc_server_config_unref(&entry->sconfig);
2325 silc_server_config_unref(&entry->rconfig);
2326 silc_server_free_sock_user_data(server, sock, NULL);
2327 server->stat.auth_failures++;
2329 /* From here on, wait 20 seconds for the backup router to appear. */
2330 silc_schedule_task_add_timeout(server->schedule,
2331 silc_server_backup_router_wait,
2332 (void *)server, 20, 0);
2337 SILC_LOG_DEBUG(("Remote host is client"));
2338 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2341 /* Add the client to the client ID cache. The nickname and Client ID
2342 and other information is created after we have received NEW_CLIENT
2343 packet from client. */
2344 client = silc_idlist_add_client(server->local_list,
2345 NULL, NULL, NULL, NULL, NULL, sock);
2347 SILC_LOG_ERROR(("Could not add new client to cache"));
2348 server->stat.auth_failures++;
2349 silc_server_disconnect_remote(server, sock,
2350 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2351 silc_server_config_unref(&entry->cconfig);
2352 silc_server_config_unref(&entry->sconfig);
2353 silc_server_config_unref(&entry->rconfig);
2354 silc_server_free_sock_user_data(server, sock, NULL);
2357 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2358 entry->data.conn_type = SILC_CONN_CLIENT;
2361 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
2362 server->stat.clients + 1));
2363 server->stat.my_clients++;
2364 server->stat.clients++;
2365 server->stat.cell_clients++;
2367 /* Get connection parameters */
2369 param = conn->param;
2371 if (!param->keepalive_secs)
2372 param->keepalive_secs = server->config->param.keepalive_secs;
2374 if (!param->qos && server->config->param.qos) {
2375 param->qos = server->config->param.qos;
2376 param->qos_rate_limit = server->config->param.qos_rate_limit;
2377 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2378 param->qos_limit_sec = server->config->param.qos_limit_sec;
2379 param->qos_limit_usec = server->config->param.qos_limit_usec;
2382 /* Check if to be anonymous connection */
2383 if (param->anonymous)
2384 client->mode |= SILC_UMODE_ANONYMOUS;
2387 /* Add public key to repository */
2388 SILC_LOG_DEBUG(("Add client public key to repository"));
2389 if (!silc_server_get_public_key_by_client(server, client, NULL))
2390 silc_skr_add_public_key_simple(server->repository,
2391 entry->data.public_key,
2392 SILC_SKR_USAGE_IDENTIFICATION, client,
2395 id_entry = (void *)client;
2399 case SILC_CONN_SERVER:
2400 case SILC_CONN_ROUTER:
2402 SilcServerEntry new_server;
2403 SilcBool initiator = FALSE;
2404 SilcBool backup_local = FALSE;
2405 SilcBool backup_router = FALSE;
2406 char *backup_replace_ip = NULL;
2407 SilcUInt16 backup_replace_port = 0;
2408 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2409 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2411 /* If we are backup router and this is incoming server connection
2412 and we do not have connection to primary router, do not allow
2414 if (server->server_type == SILC_BACKUP_ROUTER &&
2415 entry->conn_type == SILC_CONN_SERVER &&
2416 !SILC_PRIMARY_ROUTE(server)) {
2417 SILC_LOG_INFO(("Will not accept server connection because we do "
2418 "not have primary router connection established"));
2419 silc_server_disconnect_remote(server, sock,
2420 SILC_STATUS_ERR_PERM_DENIED,
2421 "We do not have connection to primary "
2422 "router established, try later");
2423 silc_server_config_unref(&entry->cconfig);
2424 silc_server_config_unref(&entry->sconfig);
2425 silc_server_config_unref(&entry->rconfig);
2426 silc_server_free_sock_user_data(server, sock, NULL);
2427 server->stat.auth_failures++;
2431 if (entry->conn_type == SILC_CONN_ROUTER) {
2432 /* Verify whether this connection is after all allowed to connect */
2433 if (!silc_server_connection_allowed(server, sock,
2435 &server->config->param,
2436 rconn ? rconn->param : NULL,
2437 silc_connauth_get_ske(connauth))) {
2438 silc_server_config_unref(&entry->cconfig);
2439 silc_server_config_unref(&entry->sconfig);
2440 silc_server_config_unref(&entry->rconfig);
2441 server->stat.auth_failures++;
2447 param = rconn->param;
2449 if (!param->keepalive_secs)
2450 param->keepalive_secs = server->config->param.keepalive_secs;
2452 if (!param->qos && server->config->param.qos) {
2453 param->qos = server->config->param.qos;
2454 param->qos_rate_limit = server->config->param.qos_rate_limit;
2455 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2456 param->qos_limit_sec = server->config->param.qos_limit_sec;
2457 param->qos_limit_usec = server->config->param.qos_limit_usec;
2461 initiator = rconn->initiator;
2462 backup_local = rconn->backup_local;
2463 backup_router = rconn->backup_router;
2464 backup_replace_ip = rconn->backup_replace_ip;
2465 backup_replace_port = rconn->backup_replace_port;
2469 if (entry->conn_type == SILC_CONN_SERVER) {
2470 /* Verify whether this connection is after all allowed to connect */
2471 if (!silc_server_connection_allowed(server, sock,
2473 &server->config->param,
2474 srvconn ? srvconn->param : NULL,
2475 silc_connauth_get_ske(connauth))) {
2476 server->stat.auth_failures++;
2480 if (srvconn->param) {
2481 param = srvconn->param;
2483 if (!param->keepalive_secs)
2484 param->keepalive_secs = server->config->param.keepalive_secs;
2486 if (!param->qos && server->config->param.qos) {
2487 param->qos = server->config->param.qos;
2488 param->qos_rate_limit = server->config->param.qos_rate_limit;
2489 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2490 param->qos_limit_sec = server->config->param.qos_limit_sec;
2491 param->qos_limit_usec = server->config->param.qos_limit_usec;
2495 backup_router = srvconn->backup_router;
2499 /* If we are primary router and we have backup router configured
2500 but it has not connected to use yet, do not accept any other
2502 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2503 !server->backup_router && !backup_router) {
2504 SilcServerConfigRouter *router;
2505 router = silc_server_config_get_backup_router(server);
2506 if (router && strcmp(server->config->server_info->primary->server_ip,
2508 silc_server_find_socket_by_host(server,
2510 router->backup_replace_ip, 0)) {
2511 SILC_LOG_INFO(("Will not accept connections because we do "
2512 "not have backup router connection established"));
2513 silc_server_disconnect_remote(server, sock,
2514 SILC_STATUS_ERR_PERM_DENIED,
2515 "We do not have connection to backup "
2516 "router established, try later");
2517 silc_server_config_unref(&entry->cconfig);
2518 silc_server_config_unref(&entry->sconfig);
2519 silc_server_config_unref(&entry->rconfig);
2520 silc_server_free_sock_user_data(server, sock, NULL);
2521 server->stat.auth_failures++;
2523 /* From here on, wait 20 seconds for the backup router to appear. */
2524 silc_schedule_task_add_timeout(server->schedule,
2525 silc_server_backup_router_wait,
2526 (void *)server, 20, 0);
2531 SILC_LOG_DEBUG(("Remote host is %s",
2532 entry->conn_type == SILC_CONN_SERVER ?
2533 "server" : (backup_router ?
2534 "backup router" : "router")));
2535 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2536 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2537 "server" : (backup_router ?
2538 "backup router" : "router")));
2540 /* Add the server into server cache. The server name and Server ID
2541 is updated after we have received NEW_SERVER packet from the
2542 server. We mark ourselves as router for this server if we really
2545 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2546 server->local_list : (backup_router ?
2547 server->local_list :
2548 server->global_list)),
2550 (entry->conn_type == SILC_CONN_SERVER ?
2551 SILC_SERVER : SILC_ROUTER),
2553 (entry->conn_type == SILC_CONN_SERVER ?
2554 server->id_entry : (backup_router ?
2555 server->id_entry : NULL)),
2558 SILC_LOG_ERROR(("Could not add new server to cache"));
2559 silc_server_disconnect_remote(server, sock,
2560 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2561 silc_server_config_unref(&entry->cconfig);
2562 silc_server_config_unref(&entry->sconfig);
2563 silc_server_config_unref(&entry->rconfig);
2564 silc_server_free_sock_user_data(server, sock, NULL);
2565 server->stat.auth_failures++;
2568 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2569 entry->data.conn_type = entry->conn_type;
2571 id_entry = (void *)new_server;
2573 /* If the incoming connection is router and marked as backup router
2574 then add it to be one of our backups */
2575 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2576 /* Change it back to SERVER type since that's what it really is. */
2578 entry->data.conn_type = SILC_CONN_SERVER;
2579 new_server->server_type = SILC_BACKUP_ROUTER;
2581 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2582 ("Backup router %s is now online",
2585 /* Remove the backup waiting with timeout */
2586 silc_schedule_task_add_timeout(server->schedule,
2587 silc_server_backup_router_wait,
2588 (void *)server, 10, 0);
2592 if (entry->data.conn_type == SILC_CONN_SERVER) {
2593 server->stat.my_servers++;
2594 server->stat.servers++;
2595 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2597 server->stat.my_routers++;
2598 server->stat.routers++;
2599 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2602 /* Check whether this connection is to be our primary router connection
2603 if we do not already have the primary route. */
2604 if (!backup_router &&
2605 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2606 if (silc_server_config_is_primary_route(server) && !initiator)
2609 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2610 server->standalone = FALSE;
2611 if (!server->id_entry->router) {
2612 server->id_entry->router = id_entry;
2613 server->router = id_entry;
2625 /* Add connection to server->conns so that we know we have connection
2627 sconn = silc_calloc(1, sizeof(*sconn));
2630 sconn->server = server;
2632 sconn->remote_host = strdup(hostname);
2633 sconn->remote_port = port;
2634 silc_dlist_add(server->conns, sconn);
2635 idata->sconn = sconn;
2636 idata->sconn->callback = NULL;
2637 idata->last_receive = time(NULL);
2639 /* Add the common data structure to the ID entry. */
2640 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2641 silc_packet_set_context(sock, id_entry);
2643 /* Connection has been fully established now. Everything is ok. */
2644 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2646 /* Perform Quality of Service */
2648 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2649 param->qos_rate_limit, param->qos_bytes_limit,
2650 param->qos_limit_sec, param->qos_limit_usec);
2652 silc_server_config_unref(&entry->cconfig);
2653 silc_server_config_unref(&entry->sconfig);
2654 silc_server_config_unref(&entry->rconfig);
2658 silc_ske_free(silc_connauth_get_ske(connauth));
2659 silc_connauth_free(connauth);
2662 /* SKE completion callback. We set the new keys into use here. */
2665 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2666 SilcSKESecurityProperties prop,
2667 SilcSKEKeyMaterial keymat,
2668 SilcSKERekeyMaterial rekey,
2671 SilcPacketStream sock = context;
2672 SilcUnknownEntry entry = silc_packet_get_context(sock);
2673 SilcIDListData idata = (SilcIDListData)entry;
2674 SilcServer server = entry->server;
2675 SilcConnAuth connauth;
2676 SilcCipher send_key, receive_key;
2677 SilcHmac hmac_send, hmac_receive;
2684 if (status != SILC_SKE_STATUS_OK) {
2686 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2687 silc_ske_map_status(status), entry->hostname, entry->ip));
2689 silc_server_disconnect_remote(server, sock,
2690 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2691 silc_server_config_unref(&entry->cconfig);
2692 silc_server_config_unref(&entry->sconfig);
2693 silc_server_config_unref(&entry->rconfig);
2694 silc_server_free_sock_user_data(server, sock, NULL);
2698 SILC_LOG_DEBUG(("Setting keys into use"));
2700 /* Set the keys into use. The data will be encrypted after this. */
2701 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2702 &hmac_send, &hmac_receive, &hash)) {
2703 /* Error setting keys */
2705 silc_server_disconnect_remote(server, sock,
2706 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2707 silc_server_free_sock_user_data(server, sock, NULL);
2710 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2711 hmac_receive, FALSE);
2713 idata->rekey = rekey;
2714 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2715 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2717 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2722 SILC_LOG_DEBUG(("Starting connection authentication"));
2723 server->stat.auth_attempts++;
2725 connauth = silc_connauth_alloc(server->schedule, ske,
2726 server->config->conn_auth_timeout);
2728 /** Error allocating auth protocol */
2730 silc_server_disconnect_remote(server, sock,
2731 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2732 silc_server_config_unref(&entry->cconfig);
2733 silc_server_config_unref(&entry->sconfig);
2734 silc_server_config_unref(&entry->rconfig);
2735 silc_server_free_sock_user_data(server, sock, NULL);
2739 /* Start connection authentication */
2741 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2742 silc_server_accept_auth_compl, sock);
2745 /* Accept new TCP connection */
2747 static void silc_server_accept_new_connection(SilcNetStatus status,
2751 SilcServer server = context;
2752 SilcPacketStream packet_stream;
2753 SilcServerConfigClient *cconfig = NULL;
2754 SilcServerConfigServer *sconfig = NULL;
2755 SilcServerConfigRouter *rconfig = NULL;
2756 SilcServerConfigDeny *deny;
2757 SilcUnknownEntry entry;
2759 SilcSKEParamsStruct params;
2760 char *hostname, *ip;
2763 SILC_LOG_DEBUG(("Accepting new connection"));
2765 /* Check for maximum allowed connections */
2766 server->stat.conn_attempts++;
2767 if (silc_dlist_count(server->conns) >
2768 server->config->param.connections_max) {
2769 SILC_LOG_ERROR(("Refusing connection, server is full"));
2770 server->stat.conn_failures++;
2771 silc_stream_destroy(stream);
2775 /* Get hostname, IP and port */
2776 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2777 (const char **)&ip, &port)) {
2778 /* Bad socket stream */
2779 server->stat.conn_failures++;
2780 silc_stream_destroy(stream);
2784 /* Create packet stream */
2785 packet_stream = silc_packet_stream_create(server->packet_engine,
2786 server->schedule, stream);
2787 if (!packet_stream) {
2788 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2789 server->stat.conn_failures++;
2790 silc_stream_destroy(stream);
2793 server->stat.conn_num++;
2795 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2797 /* Set source ID to packet stream */
2798 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2801 server->stat.conn_failures++;
2802 silc_packet_stream_destroy(packet_stream);
2806 /* Check whether this connection is denied to connect to us. */
2807 deny = silc_server_config_find_denied(server, ip);
2809 deny = silc_server_config_find_denied(server, hostname);
2811 /* The connection is denied */
2812 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2813 silc_server_disconnect_remote(server, packet_stream,
2814 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2816 silc_server_free_sock_user_data(server, packet_stream, NULL);
2820 /* Check whether we have configured this sort of connection at all. We
2821 have to check all configurations since we don't know what type of
2822 connection this is. */
2823 if (!(cconfig = silc_server_config_find_client(server, ip)))
2824 cconfig = silc_server_config_find_client(server, hostname);
2825 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2826 sconfig = silc_server_config_find_server_conn(server, hostname);
2827 if (server->server_type == SILC_ROUTER)
2828 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2829 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2830 if (!cconfig && !sconfig && !rconfig) {
2831 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2832 server->stat.conn_failures++;
2833 silc_server_disconnect_remote(server, packet_stream,
2834 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2835 silc_server_free_sock_user_data(server, packet_stream, NULL);
2839 /* The connection is allowed */
2840 entry = silc_calloc(1, sizeof(*entry));
2842 server->stat.conn_failures++;
2843 silc_server_disconnect_remote(server, packet_stream,
2844 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2845 silc_server_free_sock_user_data(server, packet_stream, NULL);
2848 entry->hostname = hostname;
2851 entry->server = server;
2852 entry->data.conn_type = SILC_CONN_UNKNOWN;
2853 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2854 silc_packet_set_context(packet_stream, entry);
2856 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2858 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2859 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2860 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2862 /* Take flags for key exchange. Since we do not know what type of connection
2863 this is, we go through all found configurations and use the global ones
2864 as well. This will result always into strictest key exchange flags. */
2865 memset(¶ms, 0, sizeof(params));
2866 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2867 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2868 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2869 if (server->config->param.key_exchange_pfs)
2870 params.flags |= SILC_SKE_SP_FLAG_PFS;
2872 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2873 server->stat.conn_attempts++;
2875 /* Start SILC Key Exchange protocol */
2876 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2877 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2878 server->public_key, server->private_key,
2881 server->stat.conn_failures++;
2882 silc_server_disconnect_remote(server, packet_stream,
2883 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2884 silc_server_free_sock_user_data(server, packet_stream, NULL);
2887 silc_ske_set_callbacks(ske, silc_server_verify_key,
2888 silc_server_accept_completed, packet_stream);
2890 /* Start key exchange protocol */
2891 params.version = silc_version_string;
2892 params.timeout_secs = server->config->key_exchange_timeout;
2893 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2897 /********************************** Rekey ***********************************/
2899 /* Initiator rekey completion callback */
2901 static void silc_server_rekey_completion(SilcSKE ske,
2902 SilcSKEStatus status,
2903 const SilcSKESecurityProperties prop,
2904 const SilcSKEKeyMaterial keymat,
2905 SilcSKERekeyMaterial rekey,
2908 SilcPacketStream sock = context;
2909 SilcIDListData idata = silc_packet_get_context(sock);
2910 SilcServer server = idata->sconn->server;
2912 idata->sconn->op = NULL;
2913 if (status != SILC_SKE_STATUS_OK) {
2914 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2915 idata->sconn->remote_host));
2919 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2920 idata->sconn->remote_host, idata->sconn->remote_port,
2921 SILC_CONNTYPE_STRING(idata->conn_type)));
2923 /* Save rekey data for next rekey */
2924 idata->rekey = rekey;
2926 /* Register new rekey timeout */
2927 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2928 sock, idata->sconn->rekey_timeout, 0);
2931 /* Helper to stop future rekeys on a link. */
2932 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2934 if (!client->connection)
2937 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2939 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2940 client->connection);
2943 /* Rekey callback. Start rekey as initiator */
2945 SILC_TASK_CALLBACK(silc_server_do_rekey)
2947 SilcServer server = app_context;
2948 SilcPacketStream sock = context;
2949 SilcIDListData idata = silc_packet_get_context(sock);
2952 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2954 /* Do not execute rekey with disabled connections */
2955 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2958 /* If another protocol is active do not start rekey */
2959 if (idata->sconn->op) {
2960 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2961 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2966 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2967 idata->sconn->remote_host, idata->sconn->remote_port,
2968 SILC_CONNTYPE_STRING(idata->conn_type)));
2971 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2972 server->public_key, NULL, sock);
2976 /* Set SKE callbacks */
2977 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2980 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2983 /* Responder rekey completion callback */
2986 silc_server_rekey_resp_completion(SilcSKE ske,
2987 SilcSKEStatus status,
2988 const SilcSKESecurityProperties prop,
2989 const SilcSKEKeyMaterial keymat,
2990 SilcSKERekeyMaterial rekey,
2993 SilcPacketStream sock = context;
2994 SilcIDListData idata = silc_packet_get_context(sock);
2996 idata->sconn->op = NULL;
2997 if (status != SILC_SKE_STATUS_OK) {
2998 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2999 idata->sconn->remote_host));
3003 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
3004 idata->sconn->remote_host, idata->sconn->remote_port,
3005 SILC_CONNTYPE_STRING(idata->conn_type)));
3007 /* Save rekey data for next rekey */
3008 idata->rekey = rekey;
3011 /* Start rekey as responder */
3013 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
3016 SilcIDListData idata = silc_packet_get_context(sock);
3019 if (!idata->rekey) {
3020 silc_packet_free(packet);
3023 if (idata->conn_type == SILC_CONN_UNKNOWN) {
3024 silc_packet_free(packet);
3028 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3029 idata->sconn->remote_host, idata->sconn->remote_port,
3030 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3033 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3034 server->public_key, NULL, sock);
3036 silc_packet_free(packet);
3040 /* Set SKE callbacks */
3041 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3044 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3049 /****************************** Disconnection *******************************/
3051 /* Destroys packet stream. */
3053 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3055 silc_packet_stream_unref(context);
3058 /* Closes connection to socket connection */
3060 void silc_server_close_connection(SilcServer server,
3061 SilcPacketStream sock)
3063 SilcIDListData idata = silc_packet_get_context(sock);
3065 const char *hostname;
3068 if (!silc_packet_stream_is_valid(sock))
3071 memset(tmp, 0, sizeof(tmp));
3072 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3073 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3074 NULL, &hostname, NULL, &port);
3075 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3076 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3077 tmp[0] ? tmp : ""));
3079 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3081 if (idata && idata->sconn) {
3082 silc_server_connection_free(idata->sconn);
3083 idata->sconn = NULL;
3086 /* Take a reference and then destroy the stream. The last reference
3087 is released later in a timeout callback. */
3088 silc_packet_stream_ref(sock);
3089 silc_packet_stream_destroy(sock);
3091 /* Close connection with timeout */
3092 server->stat.conn_num--;
3093 silc_schedule_task_del_by_all(server->schedule, 0,
3094 silc_server_close_connection_final, sock);
3095 silc_schedule_task_add_timeout(server->schedule,
3096 silc_server_close_connection_final,
3100 /* Sends disconnect message to remote connection and disconnects the
3103 void silc_server_disconnect_remote(SilcServer server,
3104 SilcPacketStream sock,
3105 SilcStatus status, ...)
3107 unsigned char buf[512];
3114 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p, status %d", sock,
3117 va_start(ap, status);
3118 cp = va_arg(ap, char *);
3120 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3123 /* Send SILC_PACKET_DISCONNECT */
3124 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3125 SILC_STR_UI_CHAR(status),
3126 SILC_STR_UI8_STRING(cp ? buf : NULL),
3129 /* Close connection */
3130 silc_server_close_connection(server, sock);
3133 /* Frees client data and notifies about client's signoff. */
3135 void silc_server_free_client_data(SilcServer server,
3136 SilcPacketStream sock,
3137 SilcClientEntry client,
3139 const char *signoff)
3141 SILC_LOG_DEBUG(("Freeing client %p data", client));
3144 /* Check if anyone is watching this nickname */
3145 if (server->server_type == SILC_ROUTER)
3146 silc_server_check_watcher_list(server, client, NULL,
3147 SILC_NOTIFY_TYPE_SIGNOFF);
3149 /* Send SIGNOFF notify to routers. */
3151 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3152 SILC_BROADCAST(server), client->id,
3156 /* Remove client from all channels */
3158 silc_server_remove_from_channels(server, NULL, client,
3159 TRUE, (char *)signoff, TRUE, FALSE);
3161 silc_server_remove_from_channels(server, NULL, client,
3162 FALSE, NULL, FALSE, FALSE);
3164 /* Remove this client from watcher list if it is */
3165 silc_server_del_from_watcher_list(server, client);
3167 /* Remove client's public key from repository, this will free it too. */
3168 if (client->data.public_key) {
3169 silc_skr_del_public_key(server->repository, client->data.public_key,
3171 client->data.public_key = NULL;
3174 /* Update statistics */
3176 /* Local detached clients aren't counted. */
3177 if (!client->local_detached)
3178 server->stat.my_clients--;
3179 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3180 server->stat.clients - 1));
3181 SILC_VERIFY(server->stat.clients > 0);
3182 server->stat.clients--;
3183 if (server->stat.cell_clients)
3184 server->stat.cell_clients--;
3185 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3186 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3187 silc_schedule_task_del_by_context(server->schedule, client);
3189 if (client->data.sconn) {
3190 silc_server_connection_free(client->data.sconn);
3191 client->data.sconn = NULL;
3194 /* We will not delete the client entry right away. We will take it
3195 into history (for WHOWAS command) for 5 minutes, unless we're
3196 shutting down server. */
3197 if (!server->server_shutdown) {
3198 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3200 client->router = NULL;
3201 client->connection = NULL;
3202 client->data.created = silc_time();
3203 silc_dlist_del(server->expired_clients, client);
3204 silc_dlist_add(server->expired_clients, client);
3206 /* Delete directly since we're shutting down server */
3207 SILC_LOG_DEBUG(("Delete client directly"));
3208 silc_idlist_del_data(client);
3209 silc_idlist_del_client(server->local_list, client);
3213 /* Frees user_data pointer from socket connection object. This also sends
3214 appropriate notify packets to the network to inform about leaving
3217 void silc_server_free_sock_user_data(SilcServer server,
3218 SilcPacketStream sock,
3219 const char *signoff_message)
3221 SilcIDListData idata;
3228 SILC_LOG_DEBUG(("Start, sock %p", sock));
3230 idata = silc_packet_get_context(sock);
3234 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3237 /* Cancel active protocols */
3239 if (idata->sconn && idata->sconn->op) {
3240 SILC_LOG_DEBUG(("Abort active protocol"));
3241 silc_async_abort(idata->sconn->op, NULL, NULL);
3242 idata->sconn->op = NULL;
3244 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3245 ((SilcUnknownEntry)idata)->op) {
3246 SILC_LOG_DEBUG(("Abort active protocol"));
3247 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3248 ((SilcUnknownEntry)idata)->op = NULL;
3252 switch (idata->conn_type) {
3253 case SILC_CONN_CLIENT:
3255 SilcClientEntry client_entry = (SilcClientEntry)idata;
3256 silc_server_free_client_data(server, sock, client_entry, TRUE,
3258 silc_packet_set_context(sock, NULL);
3262 case SILC_CONN_SERVER:
3263 case SILC_CONN_ROUTER:
3265 SilcServerEntry user_data = (SilcServerEntry)idata;
3266 SilcServerEntry backup_router = NULL;
3268 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3271 backup_router = silc_server_backup_get(server, user_data->id);
3273 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3274 backup_router == server->id_entry &&
3275 idata->conn_type != SILC_CONN_ROUTER)
3276 backup_router = NULL;
3278 if (server->server_shutdown || server->backup_noswitch)
3279 backup_router = NULL;
3281 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3282 NULL, NULL, &ip, &port);
3284 /* If this was our primary router connection then we're lost to
3285 the outside world. */
3286 if (server->router == user_data) {
3287 /* Check whether we have a backup router connection */
3288 if (!backup_router || backup_router == user_data) {
3289 if (!server->no_reconnect)
3290 silc_server_create_connections(server);
3291 server->id_entry->router = NULL;
3292 server->router = NULL;
3293 server->standalone = TRUE;
3294 server->backup_primary = FALSE;
3295 backup_router = NULL;
3297 if (server->id_entry != backup_router) {
3298 SILC_LOG_INFO(("New primary router is backup router %s",
3299 backup_router->server_name));
3300 server->id_entry->router = backup_router;
3301 server->router = backup_router;
3302 server->router_connect = time(0);
3303 server->backup_primary = TRUE;
3304 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3306 /* Send START_USE to backup router to indicate we have switched */
3307 silc_server_backup_send_start_use(server,
3308 backup_router->connection,
3311 SILC_LOG_INFO(("We are now new primary router in this cell"));
3312 server->id_entry->router = NULL;
3313 server->router = NULL;
3314 server->standalone = TRUE;
3317 /* We stop here to take a breath */
3320 if (server->backup_router) {
3321 server->server_type = SILC_ROUTER;
3323 /* We'll need to constantly try to reconnect to the primary
3324 router so that we'll see when it comes back online. */
3325 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3326 silc_server_backup_connected,
3330 /* Mark this connection as replaced */
3331 silc_server_backup_replaced_add(server, user_data->id,
3334 } else if (backup_router) {
3335 SILC_LOG_INFO(("Enabling the use of backup router %s",
3336 backup_router->server_name));
3338 /* Mark this connection as replaced */
3339 silc_server_backup_replaced_add(server, user_data->id,
3341 } else if (server->server_type == SILC_SERVER &&
3342 idata->conn_type == SILC_CONN_ROUTER) {
3343 /* Reconnect to the router (backup) */
3344 if (!server->no_reconnect)
3345 silc_server_create_connections(server);
3348 if (user_data->server_name)
3349 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3350 ("Server %s signoff", user_data->server_name));
3352 if (!backup_router) {
3353 /* Remove all servers that are originated from this server, and
3354 remove the clients of those servers too. */
3355 silc_server_remove_servers_by_server(server, user_data, TRUE);
3358 /* Remove the clients that this server owns as they will become
3359 invalid now too. For backup router the server is actually
3360 coming from the primary router, so mark that as the owner
3362 if (server->server_type == SILC_BACKUP_ROUTER &&
3363 sock->type == SILC_CONN_SERVER)
3364 silc_server_remove_clients_by_server(server, server->router,
3368 silc_server_remove_clients_by_server(server, user_data,
3371 /* Remove channels owned by this server */
3372 if (server->server_type == SILC_SERVER)
3373 silc_server_remove_channels_by_server(server, user_data);
3375 /* Enable local server connections that may be disabled */
3376 silc_server_local_servers_toggle_enabled(server, TRUE);
3378 /* Update the client entries of this server to the new backup
3379 router. If we are the backup router we also resolve the real
3380 servers for the clients. After updating is over this also
3381 removes the clients that this server explicitly owns. */
3382 silc_server_update_clients_by_server(server, user_data,
3383 backup_router, TRUE);
3385 /* If we are router and just lost our primary router (now standlaone)
3386 we remove everything that was behind it, since we don't know
3388 if (server->server_type == SILC_ROUTER && server->standalone)
3389 /* Remove all servers that are originated from this server, and
3390 remove the clients of those servers too. */
3391 silc_server_remove_servers_by_server(server, user_data, TRUE);
3393 /* Finally remove the clients that are explicitly owned by this
3394 server. They go down with the server. */
3395 silc_server_remove_clients_by_server(server, user_data,
3398 /* Update our server cache to use the new backup router too. */
3399 silc_server_update_servers_by_server(server, user_data, backup_router);
3400 if (server->server_type == SILC_SERVER)
3401 silc_server_update_channels_by_server(server, user_data,
3404 /* Send notify about primary router going down to local operators */
3405 if (server->backup_router)
3406 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3407 SILC_NOTIFY_TYPE_NONE,
3408 ("%s switched to backup router %s "
3409 "(we are primary router now)",
3410 server->server_name, server->server_name));
3411 else if (server->router)
3412 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3413 SILC_NOTIFY_TYPE_NONE,
3414 ("%s switched to backup router %s",
3415 server->server_name,
3416 server->router->server_name));
3418 server->backup_noswitch = FALSE;
3421 silc_server_connection_free(idata->sconn);
3422 idata->sconn = NULL;
3426 if (idata->conn_type == SILC_CONN_SERVER) {
3427 server->stat.my_servers--;
3428 server->stat.servers--;
3429 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3430 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3431 server->stat.my_routers--;
3432 server->stat.routers--;
3433 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3435 if (server->server_type == SILC_ROUTER)
3436 server->stat.cell_servers--;
3438 /* Free the server entry */
3439 silc_server_backup_del(server, user_data);
3440 silc_server_backup_replaced_del(server, user_data);
3441 silc_idlist_del_data(user_data);
3442 if (!silc_idlist_del_server(server->local_list, user_data))
3443 silc_idlist_del_server(server->global_list, user_data);
3445 if (backup_router && backup_router != server->id_entry) {
3446 /* Announce all of our stuff that was created about 5 minutes ago.
3447 The backup router knows all the other stuff already. */
3448 if (server->server_type == SILC_ROUTER)
3449 silc_server_announce_servers(server, FALSE, time(0) - 300,
3450 backup_router->connection);
3452 /* Announce our clients and channels to the router */
3453 silc_server_announce_clients(server, time(0) - 300,
3454 backup_router->connection);
3455 silc_server_announce_channels(server, time(0) - 300,
3456 backup_router->connection);
3459 silc_packet_set_context(sock, NULL);
3465 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3467 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3470 if (server->router_conn == idata->sconn) {
3471 if (!server->no_reconnect)
3472 silc_server_create_connections(server);
3473 server->router_conn = NULL;
3476 silc_server_connection_free(idata->sconn);
3477 idata->sconn = NULL;
3479 silc_idlist_del_data(idata);
3481 silc_packet_set_context(sock, NULL);
3487 /* Removes client from all channels it has joined. This is used when client
3488 connection is disconnected. If the client on a channel is last, the
3489 channel is removed as well. This sends the SIGNOFF notify types. */
3491 void silc_server_remove_from_channels(SilcServer server,
3492 SilcPacketStream sock,
3493 SilcClientEntry client,
3495 const char *signoff_message,
3499 SilcChannelEntry channel;
3500 SilcChannelClientEntry chl;
3501 SilcHashTableList htl;
3502 SilcBuffer clidp = NULL;
3507 if (notify && !client->id)
3510 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3511 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3514 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3519 /* Remove the client from all channels. The client is removed from
3520 the channels' user list. */
3521 silc_hash_table_list(client->channels, &htl);
3522 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3523 channel = chl->channel;
3525 /* Remove channel if this is last client leaving the channel, unless
3526 the channel is permanent. */
3527 if (server->server_type != SILC_SERVER &&
3528 silc_hash_table_count(channel->user_list) < 2) {
3529 silc_server_channel_delete(server, channel);
3533 silc_hash_table_del(client->channels, channel);
3534 silc_hash_table_del(channel->user_list, client);
3535 channel->user_count--;
3537 /* If there is no global users on the channel anymore mark the channel
3538 as local channel. Do not check if the removed client is local client. */
3539 if (server->server_type == SILC_SERVER && channel->global_users &&
3540 chl->client->router && !silc_server_channel_has_global(channel))
3541 channel->global_users = FALSE;
3543 memset(chl, 'A', sizeof(*chl));
3546 /* Update statistics */
3547 if (SILC_IS_LOCAL(client))
3548 server->stat.my_chanclients--;
3549 if (server->server_type == SILC_ROUTER) {
3550 server->stat.cell_chanclients--;
3551 server->stat.chanclients--;
3554 /* If there is not at least one local user on the channel then we don't
3555 need the channel entry anymore, we can remove it safely, unless the
3556 channel is permanent channel */
3557 if (server->server_type == SILC_SERVER &&
3558 !silc_server_channel_has_local(channel)) {
3559 /* Notify about leaving client if this channel has global users. */
3560 if (notify && channel->global_users)
3561 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3562 SILC_NOTIFY_TYPE_SIGNOFF,
3563 signoff_message ? 2 : 1,
3564 clidp->data, silc_buffer_len(clidp),
3565 signoff_message, signoff_message ?
3566 strlen(signoff_message) : 0);
3568 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3569 silc_server_channel_delete(server, channel);
3573 /* Send notify to channel about client leaving SILC and channel too */
3575 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3576 SILC_NOTIFY_TYPE_SIGNOFF,
3577 signoff_message ? 2 : 1,
3578 clidp->data, silc_buffer_len(clidp),
3579 signoff_message, signoff_message ?
3580 strlen(signoff_message) : 0);
3582 if (killed && clidp) {
3583 /* Remove the client from channel's invite list */
3584 if (channel->invite_list &&
3585 silc_hash_table_count(channel->invite_list)) {
3587 SilcArgumentPayload iargs;
3588 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3589 silc_buffer_len(clidp), 3);
3590 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3591 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3592 silc_buffer_free(ab);
3593 silc_argument_payload_free(iargs);
3597 /* Don't create keys if we are shutting down */
3598 if (server->server_shutdown)
3601 /* Re-generate channel key if needed */
3602 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3603 if (!silc_server_create_channel_key(server, channel, 0))
3606 /* Send the channel key to the channel. The key of course is not sent
3607 to the client who was removed from the channel. */
3608 silc_server_send_channel_key(server, client->connection, channel,
3609 server->server_type == SILC_ROUTER ?
3610 FALSE : !server->standalone);
3614 silc_hash_table_list_reset(&htl);
3616 silc_buffer_free(clidp);
3619 /* Removes client from one channel. This is used for example when client
3620 calls LEAVE command to remove itself from the channel. Returns TRUE
3621 if channel still exists and FALSE if the channel is removed when
3622 last client leaves the channel. If `notify' is FALSE notify messages
3625 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3626 SilcPacketStream sock,
3627 SilcChannelEntry channel,
3628 SilcClientEntry client,
3631 SilcChannelClientEntry chl;
3634 SILC_LOG_DEBUG(("Removing %s from channel %s",
3635 silc_id_render(client->id, SILC_ID_CLIENT),
3636 channel->channel_name));
3638 /* Get the entry to the channel, if this client is not on the channel
3640 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3643 /* Remove channel if this is last client leaving the channel, unless
3644 the channel is permanent. */
3645 if (server->server_type != SILC_SERVER &&
3646 silc_hash_table_count(channel->user_list) < 2) {
3647 silc_server_channel_delete(server, channel);
3651 silc_hash_table_del(client->channels, channel);
3652 silc_hash_table_del(channel->user_list, client);
3653 channel->user_count--;
3655 /* If there is no global users on the channel anymore mark the channel
3656 as local channel. Do not check if the client is local client. */
3657 if (server->server_type == SILC_SERVER && channel->global_users &&
3658 chl->client->router && !silc_server_channel_has_global(channel))
3659 channel->global_users = FALSE;
3661 memset(chl, 'O', sizeof(*chl));
3664 /* Update statistics */
3665 if (SILC_IS_LOCAL(client))
3666 server->stat.my_chanclients--;
3667 if (server->server_type == SILC_ROUTER) {
3668 server->stat.cell_chanclients--;
3669 server->stat.chanclients--;
3672 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3676 /* If there is not at least one local user on the channel then we don't
3677 need the channel entry anymore, we can remove it safely, unless the
3678 channel is permanent channel */
3679 if (server->server_type == SILC_SERVER &&
3680 !silc_server_channel_has_local(channel)) {
3681 /* Notify about leaving client if this channel has global users. */
3682 if (notify && channel->global_users)
3683 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3684 SILC_NOTIFY_TYPE_LEAVE, 1,
3685 clidp->data, silc_buffer_len(clidp));
3687 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3688 silc_server_channel_delete(server, channel);
3689 silc_buffer_free(clidp);
3693 /* Send notify to channel about client leaving the channel */
3695 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3696 SILC_NOTIFY_TYPE_LEAVE, 1,
3697 clidp->data, silc_buffer_len(clidp));
3699 silc_buffer_free(clidp);
3703 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3704 function may be used only by router. In real SILC network all channels
3705 are created by routers thus this function is never used by normal
3708 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3709 SilcServerID *router_id,
3715 SilcChannelID *channel_id;
3716 SilcChannelEntry entry;
3717 SilcCipher send_key, receive_key;
3720 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3723 cipher = SILC_DEFAULT_CIPHER;
3725 hmac = SILC_DEFAULT_HMAC;
3727 /* Allocate cipher */
3728 if (!silc_cipher_alloc(cipher, &send_key))
3730 if (!silc_cipher_alloc(cipher, &receive_key)) {
3731 silc_cipher_free(send_key);
3736 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3737 silc_cipher_free(send_key);
3738 silc_cipher_free(receive_key);
3742 channel_name = strdup(channel_name);
3744 /* Create the channel ID */
3745 if (!silc_id_create_channel_id(server, router_id, server->rng,
3747 silc_free(channel_name);
3748 silc_cipher_free(send_key);
3749 silc_cipher_free(receive_key);
3750 silc_hmac_free(newhmac);
3754 /* Create the channel */
3755 entry = silc_idlist_add_channel(server->local_list, channel_name,
3756 SILC_CHANNEL_MODE_NONE, channel_id,
3757 NULL, send_key, receive_key, newhmac);
3759 silc_free(channel_name);
3760 silc_cipher_free(send_key);
3761 silc_cipher_free(receive_key);
3762 silc_hmac_free(newhmac);
3763 silc_free(channel_id);
3767 entry->cipher = strdup(cipher);
3768 entry->hmac_name = strdup(hmac);
3770 /* Now create the actual key material */
3771 if (!silc_server_create_channel_key(server, entry,
3772 silc_cipher_get_key_len(send_key) / 8)) {
3773 silc_idlist_del_channel(server->local_list, entry);
3777 /* Notify other routers about the new channel. We send the packet
3778 to our primary route. */
3780 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3781 channel_name, entry->id,
3782 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3785 /* Distribute to backup routers */
3786 if (broadcast && server->server_type == SILC_ROUTER) {
3788 unsigned char cid[32];
3789 SilcUInt32 name_len = strlen(channel_name);
3792 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3793 packet = silc_channel_payload_encode(channel_name, name_len,
3794 cid, id_len, entry->mode);
3795 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3796 packet->data, silc_buffer_len(packet), FALSE,
3798 silc_buffer_free(packet);
3801 server->stat.my_channels++;
3802 if (server->server_type == SILC_ROUTER) {
3803 server->stat.channels++;
3804 server->stat.cell_channels++;
3805 entry->users_resolved = TRUE;
3811 /* Same as above but creates the channel with Channel ID `channel_id. */
3814 silc_server_create_new_channel_with_id(SilcServer server,
3818 SilcChannelID *channel_id,
3821 SilcChannelEntry entry;
3822 SilcCipher send_key, receive_key;
3825 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3828 cipher = SILC_DEFAULT_CIPHER;
3830 hmac = SILC_DEFAULT_HMAC;
3832 /* Allocate cipher */
3833 if (!silc_cipher_alloc(cipher, &send_key))
3835 if (!silc_cipher_alloc(cipher, &receive_key)) {
3836 silc_cipher_free(send_key);
3841 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3842 silc_cipher_free(send_key);
3843 silc_cipher_free(receive_key);
3847 channel_name = strdup(channel_name);
3849 /* Create the channel */
3850 entry = silc_idlist_add_channel(server->local_list, channel_name,
3851 SILC_CHANNEL_MODE_NONE, channel_id,
3852 NULL, send_key, receive_key, newhmac);
3854 silc_cipher_free(send_key);
3855 silc_cipher_free(receive_key);
3856 silc_hmac_free(newhmac);
3857 silc_free(channel_name);
3861 /* Now create the actual key material */
3862 if (!silc_server_create_channel_key(server, entry,
3863 silc_cipher_get_key_len(send_key) / 8)) {
3864 silc_idlist_del_channel(server->local_list, entry);
3868 /* Notify other routers about the new channel. We send the packet
3869 to our primary route. */
3871 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3872 channel_name, entry->id,
3873 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3876 /* Distribute to backup routers */
3877 if (broadcast && server->server_type == SILC_ROUTER) {
3879 unsigned char cid[32];
3880 SilcUInt32 name_len = strlen(channel_name);
3883 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3884 packet = silc_channel_payload_encode(channel_name, name_len,
3885 cid, id_len, entry->mode);
3886 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3887 packet->data, silc_buffer_len(packet), FALSE,
3889 silc_buffer_free(packet);
3892 server->stat.my_channels++;
3893 if (server->server_type == SILC_ROUTER) {
3894 server->stat.channels++;
3895 server->stat.cell_channels++;
3896 entry->users_resolved = TRUE;
3902 /* Channel's key re-key timeout callback. */
3904 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3906 SilcServer server = app_context;
3907 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3911 /* Return now if we are shutting down */
3912 if (server->server_shutdown)
3915 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3918 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3921 /* Generates new channel key. This is used to create the initial channel key
3922 but also to re-generate new key for channel. If `key_len' is provided
3923 it is the bytes of the key length. */
3925 SilcBool silc_server_create_channel_key(SilcServer server,
3926 SilcChannelEntry channel,
3930 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3933 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3934 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3938 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3940 if (!channel->send_key)
3941 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3942 channel->send_key = NULL;
3945 if (!channel->receive_key)
3946 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3947 silc_cipher_free(channel->send_key);
3948 channel->send_key = channel->receive_key = NULL;
3954 else if (channel->key_len)
3955 len = channel->key_len / 8;
3957 len = silc_cipher_get_key_len(channel->send_key) / 8;
3959 /* Create channel key */
3960 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3963 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3964 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3966 /* Remove old key if exists */
3968 memset(channel->key, 0, channel->key_len / 8);
3969 silc_free(channel->key);
3973 channel->key_len = len * 8;
3974 channel->key = silc_memdup(channel_key, len);
3975 memset(channel_key, 0, sizeof(channel_key));
3977 /* Generate HMAC key from the channel key data and set it */
3979 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3980 memset(channel->key, 0, channel->key_len / 8);
3981 silc_free(channel->key);
3982 silc_cipher_free(channel->send_key);
3983 silc_cipher_free(channel->receive_key);
3984 channel->send_key = channel->receive_key = NULL;
3987 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3988 silc_hmac_set_key(channel->hmac, hash,
3989 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3990 memset(hash, 0, sizeof(hash));
3992 if (server->server_type == SILC_ROUTER) {
3993 if (!channel->rekey)
3994 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3995 channel->rekey->channel = channel;
3996 channel->rekey->key_len = key_len;
3997 if (channel->rekey->task)
3998 silc_schedule_task_del(server->schedule, channel->rekey->task);
4000 channel->rekey->task =
4001 silc_schedule_task_add_timeout(server->schedule,
4002 silc_server_channel_key_rekey,
4003 (void *)channel->rekey,
4004 server->config->channel_rekey_secs, 0);
4010 /* Saves the channel key found in the encoded `key_payload' buffer. This
4011 function is used when we receive Channel Key Payload and also when we're
4012 processing JOIN command reply. Returns entry to the channel. */
4014 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4015 SilcBuffer key_payload,
4016 SilcChannelEntry channel)
4018 SilcChannelKeyPayload payload = NULL;
4020 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4024 /* Decode channel key payload */
4025 payload = silc_channel_key_payload_parse(key_payload->data,
4026 silc_buffer_len(key_payload));
4028 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4033 /* Get the channel entry */
4036 /* Get channel ID */
4037 tmp = silc_channel_key_get_id(payload, &tmp_len);
4038 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4043 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4045 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4047 if (server->server_type == SILC_ROUTER)
4048 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4049 silc_id_render(&id, SILC_ID_CHANNEL)));
4055 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4057 tmp = silc_channel_key_get_key(payload, &tmp_len);
4063 cipher = silc_channel_key_get_cipher(payload, NULL);
4069 /* Remove old key if exists */
4071 memset(channel->key, 0, channel->key_len / 8);
4072 silc_free(channel->key);
4073 silc_cipher_free(channel->send_key);
4074 silc_cipher_free(channel->receive_key);
4077 /* Create new cipher */
4078 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4079 channel->send_key = NULL;
4083 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4084 silc_cipher_free(channel->send_key);
4085 channel->send_key = channel->receive_key = NULL;
4090 if (channel->cipher)
4091 silc_free(channel->cipher);
4092 channel->cipher = strdup(cipher);
4095 channel->key_len = tmp_len * 8;
4096 channel->key = silc_memdup(tmp, tmp_len);
4097 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4098 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4100 /* Generate HMAC key from the channel key data and set it */
4102 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4103 memset(channel->key, 0, channel->key_len / 8);
4104 silc_free(channel->key);
4105 silc_cipher_free(channel->send_key);
4106 silc_cipher_free(channel->receive_key);
4107 channel->send_key = channel->receive_key = NULL;
4110 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4111 silc_hmac_set_key(channel->hmac, hash,
4112 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4114 memset(hash, 0, sizeof(hash));
4115 memset(tmp, 0, tmp_len);
4117 if (server->server_type == SILC_ROUTER) {
4118 if (!channel->rekey)
4119 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4120 channel->rekey->channel = channel;
4121 if (channel->rekey->task)
4122 silc_schedule_task_del(server->schedule, channel->rekey->task);
4124 channel->rekey->task =
4125 silc_schedule_task_add_timeout(server->schedule,
4126 silc_server_channel_key_rekey,
4127 (void *)channel->rekey,
4128 server->config->channel_rekey_secs, 0);
4133 silc_channel_key_payload_free(payload);
4138 /* Returns assembled of all servers in the given ID list. The packet's
4139 form is dictated by the New ID payload. */
4141 static void silc_server_announce_get_servers(SilcServer server,
4142 SilcServerEntry remote,
4144 SilcBuffer *servers,
4145 unsigned long creation_time)
4148 SilcIDCacheEntry id_cache;
4149 SilcServerEntry entry;
4153 /* Go through all clients in the list */
4154 if (silc_idcache_get_all(id_list->servers, &list)) {
4155 silc_list_start(list);
4156 while ((id_cache = silc_list_get(list))) {
4157 entry = (SilcServerEntry)id_cache->context;
4159 /* Do not announce the one we've sending our announcements and
4160 do not announce ourself. Also check the creation time if it's
4162 if ((entry == remote) || (entry == server->id_entry) ||
4163 (creation_time && entry->data.created < creation_time))
4166 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4168 tmp = silc_buffer_realloc(*servers,
4170 silc_buffer_truelen((*servers)) +
4171 silc_buffer_len(idp) :
4172 silc_buffer_len(idp)));
4176 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4177 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4178 silc_buffer_pull(*servers, silc_buffer_len(idp));
4179 silc_buffer_free(idp);
4185 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4191 p = silc_notify_payload_encode(notify, argc, ap);
4197 /* This function is used by router to announce existing servers to our
4198 primary router when we've connected to it. If `creation_time' is non-zero
4199 then only the servers that has been created after the `creation_time'
4200 will be announced. */
4202 void silc_server_announce_servers(SilcServer server, SilcBool global,
4203 unsigned long creation_time,
4204 SilcPacketStream remote)
4206 SilcBuffer servers = NULL;
4208 SILC_LOG_DEBUG(("Announcing servers"));
4210 /* Get servers in local list */
4211 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4212 server->local_list, &servers,
4216 /* Get servers in global list */
4217 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4218 server->global_list, &servers,
4222 silc_buffer_push(servers, servers->data - servers->head);
4223 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4225 /* Send the packet */
4226 silc_server_packet_send(server, remote,
4227 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4228 servers->data, silc_buffer_len(servers));
4230 silc_buffer_free(servers);
4234 /* Returns assembled packet of all clients in the given ID list. The
4235 packet's form is dictated by the New ID Payload. */
4237 static void silc_server_announce_get_clients(SilcServer server,
4239 SilcBuffer *clients,
4241 unsigned long creation_time)
4244 SilcIDCacheEntry id_cache;
4245 SilcClientEntry client;
4248 unsigned char mode[4];
4251 /* Go through all clients in the list */
4252 if (silc_idcache_get_all(id_list->clients, &list)) {
4253 silc_list_start(list);
4254 while ((id_cache = silc_list_get(list))) {
4255 client = (SilcClientEntry)id_cache->context;
4257 if (creation_time && client->data.created < creation_time)
4259 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4261 if (!client->connection && !client->router)
4264 SILC_LOG_DEBUG(("Announce Client ID %s",
4265 silc_id_render(client->id, SILC_ID_CLIENT)));
4267 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4271 tmp2 = silc_buffer_realloc(*clients,
4273 silc_buffer_truelen((*clients)) +
4274 silc_buffer_len(idp) :
4275 silc_buffer_len(idp)));
4279 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4280 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4281 silc_buffer_pull(*clients, silc_buffer_len(idp));
4283 SILC_PUT32_MSB(client->mode, mode);
4285 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4286 2, idp->data, silc_buffer_len(idp),
4288 tmp2 = silc_buffer_realloc(*umodes,
4290 silc_buffer_truelen((*umodes)) +
4291 silc_buffer_len(tmp) :
4292 silc_buffer_len(tmp)));
4296 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4297 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4298 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4299 silc_buffer_free(tmp);
4301 silc_buffer_free(idp);
4306 /* This function is used to announce our existing clients to our router
4307 when we've connected to it. If `creation_time' is non-zero then only
4308 the clients that has been created after the `creation_time' will be
4311 void silc_server_announce_clients(SilcServer server,
4312 unsigned long creation_time,
4313 SilcPacketStream remote)
4315 SilcBuffer clients = NULL;
4316 SilcBuffer umodes = NULL;
4318 SILC_LOG_DEBUG(("Announcing clients"));
4320 /* Get clients in local list */
4321 silc_server_announce_get_clients(server, server->local_list,
4322 &clients, &umodes, creation_time);
4324 /* As router we announce our global list as well */
4325 if (server->server_type == SILC_ROUTER)
4326 silc_server_announce_get_clients(server, server->global_list,
4327 &clients, &umodes, creation_time);
4330 silc_buffer_push(clients, clients->data - clients->head);
4331 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4333 /* Send the packet */
4334 silc_server_packet_send(server, remote,
4335 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4336 clients->data, silc_buffer_len(clients));
4338 silc_buffer_free(clients);
4342 silc_buffer_push(umodes, umodes->data - umodes->head);
4343 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4345 /* Send the packet */
4346 silc_server_packet_send(server, remote,
4347 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4348 umodes->data, silc_buffer_len(umodes));
4350 silc_buffer_free(umodes);
4354 /* Returns channel's topic for announcing it */
4356 void silc_server_announce_get_channel_topic(SilcServer server,
4357 SilcChannelEntry channel,
4362 if (channel->topic) {
4363 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4364 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4366 silc_buffer_len(chidp),
4368 strlen(channel->topic));
4369 silc_buffer_free(chidp);
4373 /* Returns channel's invite and ban lists */
4375 void silc_server_announce_get_inviteban(SilcServer server,
4376 SilcChannelEntry channel,
4380 SilcBuffer list, idp, idp2, tmp2;
4383 SilcHashTableList htl;
4384 const unsigned char a[1] = { 0x03 };
4386 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4388 /* Encode invite list */
4389 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4390 list = silc_buffer_alloc_size(2);
4391 type = silc_hash_table_count(channel->invite_list);
4392 SILC_PUT16_MSB(type, list->data);
4393 silc_hash_table_list(channel->invite_list, &htl);
4394 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4395 list = silc_argument_payload_encode_one(list, tmp2->data,
4396 silc_buffer_len(tmp2),
4397 SILC_PTR_TO_32(ptype));
4398 silc_hash_table_list_reset(&htl);
4400 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4402 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4403 idp->data, silc_buffer_len(idp),
4404 channel->channel_name,
4405 strlen(channel->channel_name),
4406 idp2->data, silc_buffer_len(idp2),
4408 list->data, silc_buffer_len(list));
4409 silc_buffer_free(idp2);
4410 silc_buffer_free(list);
4413 /* Encode ban list */
4414 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4415 list = silc_buffer_alloc_size(2);
4416 type = silc_hash_table_count(channel->ban_list);
4417 SILC_PUT16_MSB(type, list->data);
4418 silc_hash_table_list(channel->ban_list, &htl);
4419 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4420 list = silc_argument_payload_encode_one(list, tmp2->data,
4421 silc_buffer_len(tmp2),
4422 SILC_PTR_TO_32(ptype));
4423 silc_hash_table_list_reset(&htl);
4426 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4427 idp->data, silc_buffer_len(idp),
4429 list->data, silc_buffer_len(list));
4430 silc_buffer_free(list);
4433 silc_buffer_free(idp);
4436 /* Returns assembled packets for channel users of the `channel'. */
4438 void silc_server_announce_get_channel_users(SilcServer server,
4439 SilcChannelEntry channel,
4440 SilcBuffer *channel_modes,
4441 SilcBuffer *channel_users,
4442 SilcBuffer *channel_users_modes)
4444 SilcChannelClientEntry chl;
4445 SilcHashTableList htl;
4446 SilcBuffer chidp, clidp, csidp;
4447 SilcBuffer tmp, fkey = NULL, chpklist;
4449 unsigned char mode[4], ulimit[4];
4453 SILC_LOG_DEBUG(("Start"));
4455 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4456 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4457 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4460 SILC_PUT32_MSB(channel->mode, mode);
4461 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4462 SILC_PUT32_MSB(channel->user_limit, ulimit);
4463 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4464 if (channel->founder_key)
4465 fkey = silc_public_key_payload_encode(channel->founder_key);
4467 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4469 silc_buffer_len(csidp),
4472 hmac, hmac ? strlen(hmac) : 0,
4473 channel->passphrase,
4474 channel->passphrase ?
4475 strlen(channel->passphrase) : 0,
4476 fkey ? fkey->data : NULL,
4477 fkey ? silc_buffer_len(fkey) : 0,
4478 chpklist ? chpklist->data : NULL,
4480 silc_buffer_len(chpklist) : 0,
4482 SILC_CHANNEL_MODE_ULIMIT ?
4485 SILC_CHANNEL_MODE_ULIMIT ?
4486 sizeof(ulimit) : 0));
4487 len = silc_buffer_len(tmp);
4489 silc_buffer_realloc(*channel_modes,
4491 silc_buffer_truelen((*channel_modes)) + len : len));
4494 *channel_modes = tmp2;
4495 silc_buffer_pull_tail(*channel_modes,
4496 ((*channel_modes)->end -
4497 (*channel_modes)->data));
4498 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4499 silc_buffer_pull(*channel_modes, len);
4500 silc_buffer_free(tmp);
4501 silc_buffer_free(fkey);
4504 /* Now find all users on the channel */
4505 silc_hash_table_list(channel->user_list, &htl);
4506 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4507 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4509 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4513 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4515 silc_buffer_len(clidp),
4517 silc_buffer_len(chidp));
4518 len = silc_buffer_len(tmp);
4520 silc_buffer_realloc(*channel_users,
4522 silc_buffer_truelen((*channel_users)) + len : len));
4525 *channel_users = tmp2;
4526 silc_buffer_pull_tail(*channel_users,
4527 ((*channel_users)->end -
4528 (*channel_users)->data));
4530 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4531 silc_buffer_pull(*channel_users, len);
4532 silc_buffer_free(tmp);
4534 /* CUMODE notify for mode change on the channel */
4535 SILC_PUT32_MSB(chl->mode, mode);
4536 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4537 fkey = silc_public_key_payload_encode(channel->founder_key);
4538 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4540 silc_buffer_len(csidp),
4543 silc_buffer_len(clidp),
4544 fkey ? fkey->data : NULL,
4545 fkey ? silc_buffer_len(fkey) : 0);
4546 len = silc_buffer_len(tmp);
4548 silc_buffer_realloc(*channel_users_modes,
4549 (*channel_users_modes ?
4550 silc_buffer_truelen((*channel_users_modes)) +
4554 *channel_users_modes = tmp2;
4555 silc_buffer_pull_tail(*channel_users_modes,
4556 ((*channel_users_modes)->end -
4557 (*channel_users_modes)->data));
4559 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4560 silc_buffer_pull(*channel_users_modes, len);
4561 silc_buffer_free(tmp);
4562 silc_buffer_free(fkey);
4564 silc_buffer_free(clidp);
4566 silc_hash_table_list_reset(&htl);
4567 silc_buffer_free(chidp);
4568 silc_buffer_free(csidp);
4571 /* Returns assembled packets for all channels and users on those channels
4572 from the given ID List. The packets are in the form dictated by the
4573 New Channel and New Channel User payloads. */
4575 void silc_server_announce_get_channels(SilcServer server,
4577 SilcBuffer *channels,
4578 SilcBuffer **channel_modes,
4579 SilcBuffer *channel_users,
4580 SilcBuffer **channel_users_modes,
4581 SilcUInt32 *channel_users_modes_c,
4582 SilcBuffer **channel_topics,
4583 SilcBuffer **channel_invites,
4584 SilcBuffer **channel_bans,
4585 SilcChannelID ***channel_ids,
4586 unsigned long creation_time)
4589 SilcIDCacheEntry id_cache;
4590 SilcChannelEntry channel;
4591 unsigned char cid[32];
4593 SilcUInt16 name_len;
4595 int i = *channel_users_modes_c;
4599 SILC_LOG_DEBUG(("Start"));
4601 /* Go through all channels in the list */
4602 if (silc_idcache_get_all(id_list->channels, &list)) {
4603 silc_list_start(list);
4604 while ((id_cache = silc_list_get(list))) {
4605 channel = (SilcChannelEntry)id_cache->context;
4607 if (creation_time && channel->created < creation_time)
4612 SILC_LOG_DEBUG(("Announce Channel ID %s",
4613 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4615 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4616 name_len = strlen(channel->channel_name);
4619 len = 4 + name_len + id_len + 4;
4621 silc_buffer_realloc(*channels,
4623 silc_buffer_truelen((*channels)) +
4629 silc_buffer_pull_tail(*channels,
4630 ((*channels)->end - (*channels)->data));
4631 silc_buffer_format(*channels,
4632 SILC_STR_UI_SHORT(name_len),
4633 SILC_STR_UI_XNSTRING(channel->channel_name,
4635 SILC_STR_UI_SHORT(id_len),
4636 SILC_STR_UI_XNSTRING(cid, id_len),
4637 SILC_STR_UI_INT(channel->mode),
4639 silc_buffer_pull(*channels, len);
4642 if (creation_time && channel->updated < creation_time)
4648 /* Channel user modes */
4649 tmp = silc_realloc(*channel_users_modes,
4650 sizeof(**channel_users_modes) * (i + 1));
4653 *channel_users_modes = tmp;
4654 (*channel_users_modes)[i] = NULL;
4655 tmp = silc_realloc(*channel_modes,
4656 sizeof(**channel_modes) * (i + 1));
4659 *channel_modes = tmp;
4660 (*channel_modes)[i] = NULL;
4661 tmp = silc_realloc(*channel_ids,
4662 sizeof(**channel_ids) * (i + 1));
4666 (*channel_ids)[i] = NULL;
4667 silc_server_announce_get_channel_users(server, channel,
4668 &(*channel_modes)[i],
4670 &(*channel_users_modes)[i]);
4671 (*channel_ids)[i] = channel->id;
4673 /* Channel's topic */
4674 tmp = silc_realloc(*channel_topics,
4675 sizeof(**channel_topics) * (i + 1));
4678 *channel_topics = tmp;
4679 (*channel_topics)[i] = NULL;
4680 silc_server_announce_get_channel_topic(server, channel,
4681 &(*channel_topics)[i]);
4683 /* Channel's invite and ban list */
4684 tmp = silc_realloc(*channel_invites,
4685 sizeof(**channel_invites) * (i + 1));
4688 *channel_invites = tmp;
4689 (*channel_invites)[i] = NULL;
4690 tmp = silc_realloc(*channel_bans,
4691 sizeof(**channel_bans) * (i + 1));
4694 *channel_bans = tmp;
4695 (*channel_bans)[i] = NULL;
4696 silc_server_announce_get_inviteban(server, channel,
4697 &(*channel_invites)[i],
4698 &(*channel_bans)[i]);
4700 (*channel_users_modes_c)++;
4708 /* This function is used to announce our existing channels to our router
4709 when we've connected to it. This also announces the users on the
4710 channels to the router. If the `creation_time' is non-zero only the
4711 channels that was created after the `creation_time' are announced.
4712 Note that the channel users are still announced even if the `creation_time'
4715 void silc_server_announce_channels(SilcServer server,
4716 unsigned long creation_time,
4717 SilcPacketStream remote)
4719 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4720 SilcBuffer *channel_users_modes = NULL;
4721 SilcBuffer *channel_topics = NULL;
4722 SilcBuffer *channel_invites = NULL;
4723 SilcBuffer *channel_bans = NULL;
4724 SilcUInt32 channel_users_modes_c = 0;
4725 SilcChannelID **channel_ids = NULL;
4727 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4729 /* Get channels and channel users in local list */
4730 silc_server_announce_get_channels(server, server->local_list,
4731 &channels, &channel_modes,
4733 &channel_users_modes,
4734 &channel_users_modes_c,
4738 &channel_ids, creation_time);
4740 /* Get channels and channel users in global list */
4741 if (server->server_type != SILC_SERVER)
4742 silc_server_announce_get_channels(server, server->global_list,
4743 &channels, &channel_modes,
4745 &channel_users_modes,
4746 &channel_users_modes_c,
4750 &channel_ids, creation_time);
4753 silc_buffer_push(channels, channels->data - channels->head);
4754 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4756 /* Send the packet */
4757 silc_server_packet_send(server, remote,
4758 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4759 channels->data, silc_buffer_len(channels));
4761 silc_buffer_free(channels);
4764 if (channel_users) {
4765 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4766 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4767 silc_buffer_len(channel_users));
4769 /* Send the packet */
4770 silc_server_packet_send(server, remote,
4771 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4772 channel_users->data, silc_buffer_len(channel_users));
4774 silc_buffer_free(channel_users);
4777 if (channel_modes) {
4780 for (i = 0; i < channel_users_modes_c; i++) {
4781 if (!channel_modes[i])
4783 silc_buffer_push(channel_modes[i],
4784 channel_modes[i]->data -
4785 channel_modes[i]->head);
4786 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4787 silc_buffer_len(channel_modes[i]));
4788 silc_server_packet_send_dest(server, remote,
4789 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4790 channel_ids[i], SILC_ID_CHANNEL,
4791 channel_modes[i]->data,
4792 silc_buffer_len(channel_modes[i]));
4793 silc_buffer_free(channel_modes[i]);
4795 silc_free(channel_modes);
4798 if (channel_users_modes) {
4801 for (i = 0; i < channel_users_modes_c; i++) {
4802 if (!channel_users_modes[i])
4804 silc_buffer_push(channel_users_modes[i],
4805 channel_users_modes[i]->data -
4806 channel_users_modes[i]->head);
4807 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4808 silc_buffer_len(channel_users_modes[i]));
4809 silc_server_packet_send_dest(server, remote,
4810 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4811 channel_ids[i], SILC_ID_CHANNEL,
4812 channel_users_modes[i]->data,
4813 silc_buffer_len(channel_users_modes[i]));
4814 silc_buffer_free(channel_users_modes[i]);
4816 silc_free(channel_users_modes);
4819 if (channel_topics) {
4822 for (i = 0; i < channel_users_modes_c; i++) {
4823 if (!channel_topics[i])
4826 silc_buffer_push(channel_topics[i],
4827 channel_topics[i]->data -
4828 channel_topics[i]->head);
4829 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4830 silc_buffer_len(channel_topics[i]));
4831 silc_server_packet_send_dest(server, remote,
4832 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4833 channel_ids[i], SILC_ID_CHANNEL,
4834 channel_topics[i]->data,
4835 silc_buffer_len(channel_topics[i]));
4836 silc_buffer_free(channel_topics[i]);
4838 silc_free(channel_topics);
4841 if (channel_invites) {
4844 for (i = 0; i < channel_users_modes_c; i++) {
4845 if (!channel_invites[i])
4848 silc_buffer_push(channel_invites[i],
4849 channel_invites[i]->data -
4850 channel_invites[i]->head);
4851 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4852 silc_buffer_len(channel_invites[i]));
4853 silc_server_packet_send_dest(server, remote,
4854 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4855 channel_ids[i], SILC_ID_CHANNEL,
4856 channel_invites[i]->data,
4857 silc_buffer_len(channel_invites[i]));
4858 silc_buffer_free(channel_invites[i]);
4860 silc_free(channel_invites);
4866 for (i = 0; i < channel_users_modes_c; i++) {
4867 if (!channel_bans[i])
4870 silc_buffer_push(channel_bans[i],
4871 channel_bans[i]->data -
4872 channel_bans[i]->head);
4873 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4874 silc_buffer_len(channel_bans[i]));
4875 silc_server_packet_send_dest(server, remote,
4876 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4877 channel_ids[i], SILC_ID_CHANNEL,
4878 channel_bans[i]->data,
4879 silc_buffer_len(channel_bans[i]));
4880 silc_buffer_free(channel_bans[i]);
4882 silc_free(channel_bans);
4885 silc_free(channel_ids);
4888 /* Announces WATCH list. */
4890 void silc_server_announce_watches(SilcServer server,
4891 SilcPacketStream remote)
4893 SilcHashTableList htl;
4894 SilcBuffer buffer, idp, args, pkp;
4895 SilcClientEntry client;
4898 SILC_LOG_DEBUG(("Announcing watch list"));
4900 /* XXX because way we save the nicks (hash) we cannot announce them. */
4902 /* XXX we should send all public keys in one command if client is
4903 watching more than one key */
4904 silc_hash_table_list(server->watcher_list_pk, &htl);
4905 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4906 if (!client || !client->id)
4909 server->stat.commands_sent++;
4911 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4912 args = silc_buffer_alloc_size(2);
4913 silc_buffer_format(args,
4914 SILC_STR_UI_SHORT(1),
4916 pkp = silc_public_key_payload_encode(key);
4917 args = silc_argument_payload_encode_one(args, pkp->data,
4918 silc_buffer_len(pkp), 0x00);
4919 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4920 ++server->cmd_ident, 2,
4921 1, idp->data, silc_buffer_len(idp),
4923 silc_buffer_len(args));
4926 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4927 buffer->data, silc_buffer_len(buffer));
4929 silc_buffer_free(pkp);
4930 silc_buffer_free(args);
4931 silc_buffer_free(idp);
4932 silc_buffer_free(buffer);
4934 silc_hash_table_list_reset(&htl);
4937 /* Assembles user list and users mode list from the `channel'. */
4939 SilcBool silc_server_get_users_on_channel(SilcServer server,
4940 SilcChannelEntry channel,
4941 SilcBuffer *user_list,
4942 SilcBuffer *mode_list,
4943 SilcUInt32 *user_count)
4945 SilcChannelClientEntry chl;
4946 SilcHashTableList htl;
4947 SilcBuffer client_id_list;
4948 SilcBuffer client_mode_list;
4950 SilcUInt32 list_count = 0, len = 0;
4952 if (!silc_hash_table_count(channel->user_list))
4955 silc_hash_table_list(channel->user_list, &htl);
4956 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4957 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4958 silc_hash_table_list_reset(&htl);
4960 client_id_list = silc_buffer_alloc(len);
4962 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4963 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4964 silc_buffer_pull_tail(client_mode_list,
4965 silc_buffer_truelen(client_mode_list));
4967 silc_hash_table_list(channel->user_list, &htl);
4968 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4970 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4971 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4972 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4973 silc_buffer_free(idp);
4975 /* Client's mode on channel */
4976 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4977 silc_buffer_pull(client_mode_list, 4);
4981 silc_hash_table_list_reset(&htl);
4982 silc_buffer_push(client_id_list,
4983 client_id_list->data - client_id_list->head);
4984 silc_buffer_push(client_mode_list,
4985 client_mode_list->data - client_mode_list->head);
4987 *user_list = client_id_list;
4988 *mode_list = client_mode_list;
4989 *user_count = list_count;
4993 /* Saves users and their modes to the `channel'. */
4995 void silc_server_save_users_on_channel(SilcServer server,
4996 SilcPacketStream sock,
4997 SilcChannelEntry channel,
4998 SilcClientID *noadd,
4999 SilcBuffer user_list,
5000 SilcBuffer mode_list,
5001 SilcUInt32 user_count)
5007 SilcClientEntry client;
5008 SilcIDCacheEntry cache;
5009 SilcChannelClientEntry chl;
5011 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5012 channel->channel_name));
5014 for (i = 0; i < user_count; i++) {
5016 SILC_GET16_MSB(idp_len, user_list->data + 2);
5018 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5020 silc_buffer_pull(user_list, idp_len);
5023 SILC_GET32_MSB(mode, mode_list->data);
5024 silc_buffer_pull(mode_list, 4);
5026 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5031 /* Check if we have this client cached already. */
5032 client = silc_idlist_find_client_by_id(server->local_list,
5034 server->server_type, &cache);
5036 client = silc_idlist_find_client_by_id(server->global_list,
5038 server->server_type, &cache);
5040 /* If router did not find such Client ID in its lists then this must
5041 be bogus client or some router in the net is buggy. */
5042 if (server->server_type != SILC_SERVER)
5045 /* We don't have that client anywhere, add it. The client is added
5046 to global list since server didn't have it in the lists so it must be
5048 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5049 silc_id_dup(&id.u.client_id,
5051 silc_packet_get_context(sock),
5054 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5058 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5060 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
5061 server->stat.clients + 1));
5062 server->stat.clients++;
5065 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5066 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5067 "%s", channel->channel_name));
5071 if (!silc_server_client_on_channel(client, channel, &chl)) {
5072 /* Client was not on the channel, add it. */
5073 chl = silc_calloc(1, sizeof(*chl));
5074 chl->client = client;
5076 chl->channel = channel;
5077 silc_hash_table_add(channel->user_list, chl->client, chl);
5078 silc_hash_table_add(client->channels, chl->channel, chl);
5079 channel->user_count++;
5087 /* Saves channels and channels user modes to the `client'. Removes
5088 the client from those channels that are not sent in the list but
5091 void silc_server_save_user_channels(SilcServer server,
5092 SilcPacketStream sock,
5093 SilcClientEntry client,
5094 SilcBuffer channels,
5095 SilcBuffer channels_user_modes)
5098 SilcUInt32 *chumodes;
5099 SilcChannelPayload entry;
5100 SilcChannelEntry channel;
5101 SilcChannelID channel_id;
5102 SilcChannelClientEntry chl;
5103 SilcHashTable ht = NULL;
5104 SilcHashTableList htl;
5108 if (!channels || !channels_user_modes ||
5109 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5112 ch = silc_channel_payload_parse_list(channels->data,
5113 silc_buffer_len(channels));
5114 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5116 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5117 NULL, NULL, NULL, TRUE);
5118 silc_dlist_start(ch);
5119 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5120 /* Check if we have this channel, and add it if we don't have it.
5121 Also add the client on the channel unless it is there already. */
5122 if (!silc_channel_get_id_parse(entry, &channel_id))
5124 channel = silc_idlist_find_channel_by_id(server->local_list,
5127 channel = silc_idlist_find_channel_by_id(server->global_list,
5130 if (server->server_type != SILC_SERVER) {
5135 /* We don't have that channel anywhere, add it. */
5136 name = silc_channel_get_name(entry, NULL);
5137 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5138 silc_id_dup(&channel_id,
5140 server->router, NULL, NULL, 0);
5147 channel->mode = silc_channel_get_mode(entry);
5149 /* Add the client on the channel */
5150 if (!silc_server_client_on_channel(client, channel, &chl)) {
5151 chl = silc_calloc(1, sizeof(*chl));
5152 chl->client = client;
5153 chl->mode = chumodes[i++];
5154 chl->channel = channel;
5155 silc_hash_table_add(channel->user_list, chl->client, chl);
5156 silc_hash_table_add(client->channels, chl->channel, chl);
5157 channel->user_count++;
5160 chl->mode = chumodes[i++];
5163 silc_hash_table_add(ht, channel, channel);
5165 silc_channel_payload_list_free(ch);
5166 silc_free(chumodes);
5170 /* Go through the list again and remove client from channels that
5171 are no part of the list. */
5173 silc_hash_table_list(client->channels, &htl);
5174 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5175 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5176 silc_hash_table_del(chl->channel->user_list, chl->client);
5177 silc_hash_table_del(chl->client->channels, chl->channel);
5181 silc_hash_table_list_reset(&htl);
5182 silc_hash_table_free(ht);
5184 silc_hash_table_list(client->channels, &htl);
5185 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5186 silc_hash_table_del(chl->channel->user_list, chl->client);
5187 silc_hash_table_del(chl->client->channels, chl->channel);
5190 silc_hash_table_list_reset(&htl);
5194 /* Lookups route to the client indicated by the `id_data'. The connection
5195 object and internal data object is returned. Returns NULL if route
5196 could not be found to the client. If the `client_id' is specified then
5197 it is used and the `id_data' is ignored. */
5200 silc_server_get_client_route(SilcServer server,
5201 unsigned char *id_data,
5203 SilcClientID *client_id,
5204 SilcIDListData *idata,
5205 SilcClientEntry *client_entry)
5207 SilcClientID *id, clid;
5208 SilcClientEntry client;
5210 SILC_LOG_DEBUG(("Start"));
5213 *client_entry = NULL;
5215 /* Decode destination Client ID */
5217 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5219 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5221 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5224 /* If the destination belongs to our server we don't have to route
5225 the packet anywhere but to send it to the local destination. */
5226 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5230 /* If we are router and the client has router then the client is in
5231 our cell but not directly connected to us. */
5232 if (server->server_type == SILC_ROUTER && client->router) {
5233 /* We are of course in this case the client's router thus the route
5234 to the client is the server who owns the client. So, we will send
5235 the packet to that server. */
5237 *idata = (SilcIDListData)client->router;
5238 return client->router->connection;
5241 /* Seems that client really is directly connected to us */
5243 *idata = (SilcIDListData)client;
5245 *client_entry = client;
5246 return client->connection;
5249 /* Destination belongs to someone not in this server. If we are normal
5250 server our action is to send the packet to our router. */
5251 if (server->server_type != SILC_ROUTER && !server->standalone) {
5254 *idata = (SilcIDListData)server->router;
5255 return SILC_PRIMARY_ROUTE(server);
5258 /* We are router and we will perform route lookup for the destination
5259 and send the packet to fastest route. */
5260 if (server->server_type == SILC_ROUTER && !server->standalone) {
5261 /* Check first that the ID is valid */
5262 client = silc_idlist_find_client_by_id(server->global_list, id,
5265 SilcPacketStream dst_sock;
5267 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5270 if (idata && dst_sock)
5271 *idata = silc_packet_get_context(dst_sock);
5280 /* Encodes and returns channel list of channels the `client' has joined.
5281 Secret channels are not put to the list. */
5283 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5284 SilcClientEntry client,
5285 SilcBool get_private,
5286 SilcBool get_secret,
5287 SilcBuffer *user_mode_list)
5289 SilcBuffer buffer = NULL;
5290 SilcChannelEntry channel;
5291 SilcChannelClientEntry chl;
5292 SilcHashTableList htl;
5293 unsigned char cid[32];
5295 SilcUInt16 name_len;
5299 *user_mode_list = NULL;
5301 silc_hash_table_list(client->channels, &htl);
5302 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5303 channel = chl->channel;
5305 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5307 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5310 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5311 name_len = strlen(channel->channel_name);
5313 len = 4 + name_len + id_len + 4;
5314 buffer = silc_buffer_realloc(buffer,
5316 silc_buffer_truelen(buffer) + len : len));
5317 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5318 silc_buffer_format(buffer,
5319 SILC_STR_UI_SHORT(name_len),
5320 SILC_STR_DATA(channel->channel_name, name_len),
5321 SILC_STR_UI_SHORT(id_len),
5322 SILC_STR_DATA(cid, id_len),
5323 SILC_STR_UI_INT(chl->channel->mode),
5325 silc_buffer_pull(buffer, len);
5327 if (user_mode_list) {
5329 silc_buffer_realloc(*user_mode_list,
5331 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5332 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5333 (*user_mode_list)->data));
5334 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5335 silc_buffer_pull(*user_mode_list, 4);
5338 silc_hash_table_list_reset(&htl);
5341 silc_buffer_push(buffer, buffer->data - buffer->head);
5342 if (user_mode_list && *user_mode_list)
5343 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5344 (*user_mode_list)->head));
5349 /* Task callback used to retrieve network statistical information from
5350 router server once in a while. */
5352 SILC_TASK_CALLBACK(silc_server_get_stats)
5354 SilcServer server = (SilcServer)context;
5355 SilcBuffer idp, packet;
5357 if (!server->standalone) {
5358 SILC_LOG_DEBUG(("Retrieving stats from router"));
5359 server->stat.commands_sent++;
5360 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5362 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5363 ++server->cmd_ident, 1,
5365 silc_buffer_len(idp));
5366 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5367 SILC_PACKET_COMMAND, 0, packet->data,
5368 silc_buffer_len(packet));
5369 silc_buffer_free(packet);
5370 silc_buffer_free(idp);
5374 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,