5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2008 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));
202 if (server->router_conn && server->router_conn->sock == stream &&
203 !server->router && server->standalone) {
204 if (idata->sconn && idata->sconn->callback)
205 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
206 silc_server_create_connections(server);
207 silc_server_free_sock_user_data(server, stream, NULL);
209 /* If backup disconnected then mark that resuming will not be allowed */
210 if (server->server_type == SILC_ROUTER && !server->backup_router &&
211 idata->conn_type == SILC_CONN_SERVER) {
212 SilcServerEntry server_entry = (SilcServerEntry)idata;
213 if (server_entry->server_type == SILC_BACKUP_ROUTER)
214 server->backup_closed = TRUE;
217 if (idata->sconn && idata->sconn->callback)
218 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
219 silc_server_free_sock_user_data(server, stream, NULL);
222 silc_server_close_connection(server, stream);
225 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
227 SilcServer server = app_context;
228 SilcPacketStream stream = context;
229 SilcIDListData idata = silc_packet_get_context(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);
257 /* Packet engine callback to indicate error */
259 static void silc_server_packet_error(SilcPacketEngine engine,
260 SilcPacketStream stream,
261 SilcPacketError error,
262 void *callback_context,
263 void *stream_context)
265 SilcServer server = callback_context;
266 SilcIDListData idata = silc_packet_get_context(stream);
267 SilcStream sock = silc_packet_stream_get_stream(stream);
271 SILC_LOG_DEBUG(("Packet error, sock %p", stream));
276 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
279 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
280 SILC_CONNTYPE_STRING(idata->conn_type),
281 silc_packet_error_string(error)));
283 if (!silc_packet_stream_is_valid(stream))
286 /* In case we get here many times, register only one timeout */
287 silc_schedule_task_del_by_all(server->schedule, 0,
288 silc_server_packet_error_timeout, stream);
290 /* Close connection with random timeout */
291 silc_schedule_task_add_timeout(server->schedule,
292 silc_server_packet_error_timeout, stream,
293 silc_rng_get_byte(server->rng) % 10, 0);
296 /* Packet stream callbacks */
297 static SilcPacketCallbacks silc_server_stream_cbs =
299 silc_server_packet_receive,
300 silc_server_packet_eos,
301 silc_server_packet_error
304 /* Parses the packet type and calls what ever routines the packet type
305 requires. This is done for all incoming packets. */
307 static void silc_server_packet_parse_type(SilcServer server,
308 SilcPacketStream sock,
311 SilcPacketType type = packet->type;
312 SilcIDListData idata = silc_packet_get_context(sock);
314 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
315 silc_get_packet_name(type), packet->flags));
317 /* Parse the packet type */
319 case SILC_PACKET_NOTIFY:
321 * Received notify packet. Server can receive notify packets from
322 * router. Server then relays the notify messages to clients if needed.
324 if (packet->flags & SILC_PACKET_FLAG_LIST)
325 silc_server_notify_list(server, sock, packet);
327 silc_server_notify(server, sock, packet);
331 * Private Message packets
333 case SILC_PACKET_PRIVATE_MESSAGE:
335 * Received private message packet. The packet is coming from either
338 if (packet->flags & SILC_PACKET_FLAG_LIST)
340 idata->last_receive = time(NULL);
341 silc_server_private_message(server, sock, packet);
347 case SILC_PACKET_CHANNEL_MESSAGE:
349 * Received channel message. Channel messages are special packets
350 * (although probably most common ones) thus they are handled
353 if (packet->flags & SILC_PACKET_FLAG_LIST)
355 idata->last_receive = time(NULL);
356 silc_server_channel_message(server, sock, packet);
362 case SILC_PACKET_COMMAND:
364 * Recived command. Processes the command request and allocates the
365 * command context and calls the command.
367 if (packet->flags & SILC_PACKET_FLAG_LIST)
369 server->stat.commands_received++;
370 silc_server_command_process(server, sock, packet);
373 case SILC_PACKET_COMMAND_REPLY:
375 * Received command reply packet. Received command reply to command. It
376 * may be reply to command sent by us or reply to command sent by client
377 * that we've routed further.
379 if (packet->flags & SILC_PACKET_FLAG_LIST)
381 server->stat.commands_received++;
382 silc_server_command_reply(server, sock, packet);
385 case SILC_PACKET_DISCONNECT:
388 char *message = NULL;
389 const char *hostname, *ip;
391 if (packet->flags & SILC_PACKET_FLAG_LIST)
393 if (silc_buffer_len(&packet->buffer) < 1)
396 status = (SilcStatus)packet->buffer.data[0];
397 if (silc_buffer_len(&packet->buffer) > 1 &&
398 silc_utf8_valid(packet->buffer.data + 1,
399 silc_buffer_len(&packet->buffer) - 1))
400 message = silc_memdup(packet->buffer.data + 1,
401 silc_buffer_len(&packet->buffer) - 1);
403 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
404 NULL, &hostname, &ip, NULL))
407 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
408 silc_get_status_message(status), status,
409 message ? message : ""));
413 /* Do not switch to backup in case of error */
414 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
416 /* If backup disconnected then mark that resuming will not be allowed */
417 if (server->server_type == SILC_ROUTER && !server->backup_router &&
418 idata->conn_type == SILC_CONN_SERVER) {
419 SilcServerEntry server_entry = (SilcServerEntry)idata;
420 if (server_entry->server_type == SILC_BACKUP_ROUTER)
421 server->backup_closed = TRUE;
424 /* Handle the disconnection from our end too */
425 if (SILC_IS_LOCAL(idata))
426 silc_server_free_sock_user_data(server, sock, NULL);
427 silc_server_close_connection(server, sock);
428 server->backup_noswitch = FALSE;
432 case SILC_PACKET_CHANNEL_KEY:
434 * Received key for channel. As channels are created by the router
435 * the keys are as well. We will distribute the key to all of our
436 * locally connected clients on the particular channel. Router
437 * never receives this channel and thus is ignored.
439 if (packet->flags & SILC_PACKET_FLAG_LIST)
441 silc_server_channel_key(server, sock, packet);
444 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
446 * Private message key packet.
448 if (packet->flags & SILC_PACKET_FLAG_LIST)
450 silc_server_private_message_key(server, sock, packet);
453 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
455 * Connection authentication request packet. When we receive this packet
456 * we will send to the other end information about our mandatory
457 * authentication method for the connection. This packet maybe received
460 if (packet->flags & SILC_PACKET_FLAG_LIST)
462 silc_server_connection_auth_request(server, sock, packet);
465 case SILC_PACKET_NEW_ID:
467 * Received New ID packet. This includes some new ID that has been
468 * created. It may be for client, server or channel. This is the way
469 * to distribute information about new registered entities in the
472 if (packet->flags & SILC_PACKET_FLAG_LIST)
473 silc_server_new_id_list(server, sock, packet);
475 silc_server_new_id(server, sock, packet);
478 case SILC_PACKET_NEW_CLIENT:
480 * Received new client packet. This includes client information that
481 * we will use to create initial client ID. After creating new
482 * ID we will send it to the client.
484 if (packet->flags & SILC_PACKET_FLAG_LIST)
486 silc_server_new_client(server, sock, packet);
489 case SILC_PACKET_NEW_SERVER:
491 * Received new server packet. This includes Server ID and some other
492 * information that we may save. This is received after server has
495 if (packet->flags & SILC_PACKET_FLAG_LIST)
497 silc_server_new_server(server, sock, packet);
500 case SILC_PACKET_NEW_CHANNEL:
502 * Received new channel packet. Information about new channel in the
503 * network are distributed using this packet.
505 if (packet->flags & SILC_PACKET_FLAG_LIST)
506 silc_server_new_channel_list(server, sock, packet);
508 silc_server_new_channel(server, sock, packet);
511 case SILC_PACKET_HEARTBEAT:
513 * Received heartbeat.
515 if (packet->flags & SILC_PACKET_FLAG_LIST)
519 case SILC_PACKET_KEY_AGREEMENT:
521 * Received heartbeat.
523 if (packet->flags & SILC_PACKET_FLAG_LIST)
525 silc_server_key_agreement(server, sock, packet);
528 case SILC_PACKET_REKEY:
530 * Received re-key packet. The sender wants to regenerate the session
533 if (packet->flags & SILC_PACKET_FLAG_LIST)
535 silc_server_rekey(server, sock, packet);
538 case SILC_PACKET_FTP:
540 if (packet->flags & SILC_PACKET_FLAG_LIST)
542 silc_server_ftp(server, sock, packet);
545 case SILC_PACKET_RESUME_CLIENT:
547 if (packet->flags & SILC_PACKET_FLAG_LIST)
549 silc_server_resume_client(server, sock, packet);
552 case SILC_PACKET_RESUME_ROUTER:
553 /* Resume router packet received. This packet is received for backup
554 router resuming protocol. */
555 if (packet->flags & SILC_PACKET_FLAG_LIST)
557 silc_server_backup_resume_router(server, sock, packet);
561 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
566 /****************************** Server API **********************************/
568 /* Allocates a new SILC server object. This has to be done before the server
569 can be used. After allocation one must call silc_server_init to initialize
570 the server. The new allocated server object is returned to the new_server
573 SilcBool silc_server_alloc(SilcServer *new_server)
577 SILC_LOG_DEBUG(("Allocating new server object"));
579 server = silc_calloc(1, sizeof(*server));
582 server->server_type = SILC_SERVER;
583 server->standalone = TRUE;
584 server->local_list = silc_calloc(1, sizeof(*server->local_list));
585 if (!server->local_list)
587 server->global_list = silc_calloc(1, sizeof(*server->global_list));
588 if (!server->global_list)
590 server->pending_commands = silc_dlist_init();
591 if (!server->pending_commands)
593 server->listeners = silc_dlist_init();
594 if (!server->listeners)
596 server->repository = silc_skr_alloc();
597 if (!server->repository)
599 server->conns = silc_dlist_init();
602 server->expired_clients = silc_dlist_init();
603 if (!server->expired_clients)
606 *new_server = server;
611 /* Free's the SILC server object. This is called at the very end before
614 void silc_server_free(SilcServer server)
617 SilcIDCacheEntry cache;
618 SilcIDListData idata;
620 SILC_LOG_DEBUG(("Free server %p", server));
625 silc_server_backup_free(server);
626 silc_server_config_unref(&server->config_ref);
628 silc_rng_free(server->rng);
629 if (server->public_key)
630 silc_pkcs_public_key_free(server->public_key);
631 if (server->private_key)
632 silc_pkcs_private_key_free(server->private_key);
633 if (server->pending_commands)
634 silc_dlist_uninit(server->pending_commands);
635 if (server->id_entry) {
636 if (server->id_entry->data.sconn)
637 silc_schedule_task_del_by_context(server->schedule,
638 server->id_entry->data.sconn->sock);
639 silc_idlist_del_server(server->local_list, server->id_entry);
642 /* Delete all channels */
643 if (silc_idcache_get_all(server->local_list->channels, &list)) {
644 silc_list_start(list);
645 while ((cache = silc_list_get(list)))
646 silc_idlist_del_channel(server->local_list, cache->context);
648 if (silc_idcache_get_all(server->global_list->channels, &list)) {
649 silc_list_start(list);
650 while ((cache = silc_list_get(list)))
651 silc_idlist_del_channel(server->global_list, cache->context);
654 /* Delete all clients */
655 if (silc_idcache_get_all(server->local_list->clients, &list)) {
656 silc_list_start(list);
657 while ((cache = silc_list_get(list))) {
658 silc_schedule_task_del_by_context(server->schedule, cache->context);
659 silc_idlist_del_client(server->local_list, cache->context);
662 if (silc_idcache_get_all(server->global_list->clients, &list)) {
663 silc_list_start(list);
664 while ((cache = silc_list_get(list))) {
665 silc_schedule_task_del_by_context(server->schedule, cache->context);
666 silc_idlist_del_client(server->global_list, cache->context);
670 /* Delete all servers */
671 if (silc_idcache_get_all(server->local_list->servers, &list)) {
672 silc_list_start(list);
673 while ((cache = silc_list_get(list))) {
674 idata = (SilcIDListData)cache->context;
676 silc_schedule_task_del_by_context(server->schedule,
678 silc_idlist_del_server(server->local_list, cache->context);
681 if (silc_idcache_get_all(server->global_list->servers, &list)) {
682 while ((cache = silc_list_get(list))) {
683 idata = (SilcIDListData)cache->context;
685 silc_schedule_task_del_by_context(server->schedule,
687 silc_idlist_del_server(server->global_list, cache->context);
691 silc_schedule_task_del_by_context(server->schedule, server);
692 silc_schedule_uninit(server->schedule);
693 server->schedule = NULL;
695 silc_idcache_free(server->local_list->clients);
696 silc_idcache_free(server->local_list->servers);
697 silc_idcache_free(server->local_list->channels);
698 silc_idcache_free(server->global_list->clients);
699 silc_idcache_free(server->global_list->servers);
700 silc_idcache_free(server->global_list->channels);
701 silc_hash_table_free(server->watcher_list);
702 silc_hash_table_free(server->watcher_list_pk);
703 silc_hash_free(server->md5hash);
704 silc_hash_free(server->sha1hash);
706 silc_dlist_uninit(server->listeners);
707 silc_dlist_uninit(server->conns);
708 silc_dlist_uninit(server->expired_clients);
709 silc_skr_free(server->repository);
710 silc_packet_engine_stop(server->packet_engine);
712 silc_free(server->local_list);
713 silc_free(server->global_list);
714 silc_free(server->server_name);
715 silc_free(server->id);
718 silc_hmac_unregister_all();
719 silc_hash_unregister_all();
720 silc_cipher_unregister_all();
721 silc_pkcs_unregister_all();
724 /* Creates a new server listener. */
726 static SilcNetListener
727 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
729 SilcNetListener listener;
732 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
733 server->config->require_reverse_lookup,
735 silc_server_accept_new_connection, server);
737 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
745 /* Adds a secondary listener. */
747 SilcBool silc_server_init_secondary(SilcServer server)
749 SilcServerConfigServerInfoInterface *interface;
750 SilcNetListener listener;
752 for (interface = server->config->server_info->secondary; interface;
753 interface = interface->next) {
754 listener = silc_server_listen(server, interface->server_ip,
758 silc_dlist_add(server->listeners, listener);
764 /* Initializes the entire SILC server. This is called always before running
765 the server. This is called only once at the initialization of the program.
766 This binds the server to its listenning port. After this function returns
767 one should call silc_server_run to start the server. This returns TRUE
768 when everything is ok to run the server. Configuration file must be
769 read and parsed before calling this. */
771 SilcBool silc_server_init(SilcServer server)
774 SilcServerEntry id_entry;
775 SilcNetListener listener;
779 SILC_LOG_DEBUG(("Initializing server"));
781 server->starttime = time(NULL);
783 /* Take config object for us */
784 silc_server_config_ref(&server->config_ref, server->config,
788 /* Set debugging on if configured */
789 if (server->config->debug_string) {
790 silc_log_debug(TRUE);
791 silc_log_set_debug_string(server->config->debug_string);
793 #endif /* SILC_DEBUG */
795 /* Steal public and private key from the config object */
796 server->public_key = server->config->server_info->public_key;
797 server->private_key = server->config->server_info->private_key;
798 server->config->server_info->public_key = NULL;
799 server->config->server_info->private_key = NULL;
801 /* Register all configured ciphers, PKCS and hash functions. */
802 if (!silc_server_config_register_ciphers(server))
803 silc_cipher_register_default();
804 if (!silc_server_config_register_pkcs(server))
805 silc_pkcs_register_default();
806 if (!silc_server_config_register_hashfuncs(server))
807 silc_hash_register_default();
808 if (!silc_server_config_register_hmacs(server))
809 silc_hmac_register_default();
811 /* Initialize random number generator for the server. */
812 server->rng = silc_rng_alloc();
813 silc_rng_init(server->rng);
814 silc_rng_global_init(server->rng);
816 /* Initialize hash functions for server to use */
817 silc_hash_alloc("md5", &server->md5hash);
818 silc_hash_alloc("sha1", &server->sha1hash);
820 /* Initialize the scheduler */
821 server->schedule = silc_schedule_init(server->config->param.connections_max,
823 if (!server->schedule)
826 /* First, register log files configuration for error output */
827 silc_server_config_setlogfiles(server);
829 /* Initialize ID caches */
830 server->local_list->clients =
831 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
833 server->local_list->servers =
834 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
836 server->local_list->channels =
837 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
840 /* These are allocated for normal server as well as these hold some
841 global information that the server has fetched from its router. For
842 router these are used as they are supposed to be used on router. */
843 server->global_list->clients =
844 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
846 server->global_list->servers =
847 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
849 server->global_list->channels =
850 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
853 /* Init watcher lists */
854 server->watcher_list =
855 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
856 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
858 if (!server->watcher_list)
860 server->watcher_list_pk =
861 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
862 silc_hash_public_key_compare, NULL,
864 if (!server->watcher_list_pk)
867 /* Create TCP listener */
868 listener = silc_server_listen(
870 server->config->server_info->primary == NULL ? NULL :
871 server->config->server_info->primary->server_ip,
872 server->config->server_info->primary == NULL ? 0 :
873 server->config->server_info->primary->port);
876 silc_dlist_add(server->listeners, listener);
878 /* Create a Server ID for the server. */
879 port = silc_net_listener_get_port(listener, NULL);
880 ip = silc_net_listener_get_ip(listener, NULL);
881 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
882 server->config->server_info->primary->public_ip :
883 ip[0], port[0], server->rng, &id);
892 server->server_name = server->config->server_info->server_name;
893 server->config->server_info->server_name = NULL;
894 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
895 sizeof(server->id_string), &server->id_string_len);
897 /* Add ourselves to the server list. We don't have a router yet
898 beacuse we haven't established a route yet. It will be done later.
899 For now, NULL is sent as router. This allocates new entry to
902 silc_idlist_add_server(server->local_list, strdup(server->server_name),
904 silc_id_dup(server->id, SILC_ID_SERVER),
907 SILC_LOG_ERROR(("Could not add local server to cache"));
910 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
911 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
912 SILC_CONN_SERVER : SILC_CONN_ROUTER);
913 server->id_entry = id_entry;
915 /* Create secondary TCP listeners */
916 if (silc_server_init_secondary(server) == FALSE)
919 server->listenning = TRUE;
921 /* Create connections to configured routers. */
922 silc_server_create_connections(server);
924 /* If server connections has been configured then we must be router as
925 normal server cannot have server connections, only router connections. */
926 if (server->config->servers) {
927 SilcServerConfigServer *ptr = server->config->servers;
929 server->server_type = SILC_ROUTER;
931 if (ptr->backup_router) {
932 server->server_type = SILC_BACKUP_ROUTER;
933 server->backup_router = TRUE;
934 server->id_entry->server_type = SILC_BACKUP_ROUTER;
941 if (server->server_type != SILC_ROUTER) {
942 server->stat.servers = 1;
943 server->stat.cell_servers = 1;
945 server->stat.routers = 1;
948 /* If we are normal server we'll retrieve network statisticial information
949 once in a while from the router. */
950 if (server->server_type != SILC_ROUTER)
951 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
954 /* Start packet engine */
955 server->packet_engine =
956 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
957 &silc_server_stream_cbs, server);
958 if (!server->packet_engine)
961 /* Register client entry expiration timeout */
962 silc_schedule_task_add_timeout(server->schedule,
963 silc_server_purge_expired_clients, server,
966 /* Initialize HTTP server */
967 silc_server_http_init(server);
969 SILC_LOG_DEBUG(("Server initialized"));
971 /* We are done here, return succesfully */
975 silc_server_config_unref(&server->config_ref);
979 /* Task callback to close a socket connection after rehash */
981 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
983 SilcServer server = app_context;
984 SilcPacketStream sock = context;
985 SilcIDListData idata = silc_packet_get_context(sock);
986 const char *hostname;
989 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
990 NULL, &hostname, NULL, &port);
992 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
993 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
994 silc_schedule_task_del_by_context(server->schedule, sock);
995 silc_server_disconnect_remote(server, sock,
996 SILC_STATUS_ERR_BANNED_FROM_SERVER,
997 "This connection is removed from "
999 silc_server_free_sock_user_data(server, sock, NULL);
1002 /* This function basically reads the config file again and switches the config
1003 object pointed by the server object. After that, we have to fix various
1004 things such as the server_name and the listening ports.
1005 Keep in mind that we no longer have the root privileges at this point. */
1007 SilcBool silc_server_rehash(SilcServer server)
1009 SilcServerConfig newconfig;
1011 SILC_LOG_INFO(("Rehashing server"));
1013 /* Reset the logging system */
1014 silc_log_quick(TRUE);
1015 silc_log_flush_all();
1017 /* Start the main rehash phase (read again the config file) */
1018 newconfig = silc_server_config_alloc(server->config_file, server);
1020 SILC_LOG_ERROR(("Rehash FAILED."));
1024 /* Fix the server_name field */
1025 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1026 silc_free(server->server_name);
1028 /* Check server name */
1029 server->server_name =
1030 silc_identifier_check(newconfig->server_info->server_name,
1031 strlen(newconfig->server_info->server_name),
1032 SILC_STRING_LOCALE, 256, NULL);
1033 if (!server->server_name) {
1034 SILC_LOG_ERROR(("Malformed server name string '%s'",
1035 server->config->server_info->server_name));
1039 /* Update the idcache list with a fresh pointer */
1040 silc_free(server->id_entry->server_name);
1041 server->id_entry->server_name = strdup(server->server_name);
1042 silc_idcache_update_by_context(server->local_list->servers,
1043 server->id_entry, NULL,
1044 strdup(server->id_entry->server_name),
1049 silc_server_config_setlogfiles(server);
1051 /* Change new key pair if necessary */
1052 if (newconfig->server_info->public_key &&
1053 !silc_pkcs_public_key_compare(server->public_key,
1054 newconfig->server_info->public_key)) {
1055 silc_pkcs_public_key_free(server->public_key);
1056 silc_pkcs_private_key_free(server->private_key);
1057 server->public_key = newconfig->server_info->public_key;
1058 server->private_key = newconfig->server_info->private_key;
1059 newconfig->server_info->public_key = NULL;
1060 newconfig->server_info->private_key = NULL;
1063 /* Check for unconfigured server and router connections and close
1064 connections that were unconfigured. */
1066 if (server->config->routers) {
1067 SilcServerConfigRouter *ptr;
1068 SilcServerConfigRouter *newptr;
1071 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1074 /* Check whether new config has this one too */
1075 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1076 if (silc_string_compare(newptr->host, ptr->host) &&
1077 newptr->port == ptr->port &&
1078 newptr->initiator == ptr->initiator) {
1084 if (!found && ptr->host) {
1085 /* Remove this connection */
1086 SilcPacketStream sock;
1087 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1088 ptr->host, ptr->port);
1090 silc_schedule_task_add_timeout(server->schedule,
1091 silc_server_rehash_close_connection,
1097 if (server->config->servers) {
1098 SilcServerConfigServer *ptr;
1099 SilcServerConfigServer *newptr;
1102 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1105 /* Check whether new config has this one too */
1106 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1107 if (silc_string_compare(newptr->host, ptr->host)) {
1113 if (!found && ptr->host) {
1114 /* Remove this connection */
1115 SilcPacketStream sock;
1116 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1119 silc_schedule_task_add_timeout(server->schedule,
1120 silc_server_rehash_close_connection,
1126 if (server->config->clients) {
1127 SilcServerConfigClient *ptr;
1128 SilcServerConfigClient *newptr;
1131 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1134 /* Check whether new config has this one too */
1135 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1136 if (silc_string_compare(newptr->host, ptr->host)) {
1142 if (!found && ptr->host) {
1143 /* Remove this connection */
1144 SilcPacketStream sock;
1145 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1148 silc_schedule_task_add_timeout(server->schedule,
1149 silc_server_rehash_close_connection,
1155 /* Create connections after rehash */
1156 silc_server_create_connections(server);
1158 /* Check whether our router status has changed */
1159 if (newconfig->servers) {
1160 SilcServerConfigServer *ptr = newconfig->servers;
1162 server->server_type = SILC_ROUTER;
1164 if (ptr->backup_router) {
1165 server->server_type = SILC_BACKUP_ROUTER;
1166 server->backup_router = TRUE;
1167 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1174 /* Our old config is gone now. We'll unreference our reference made in
1175 silc_server_init and then destroy it since we are destroying it
1176 underneath the application (layer which called silc_server_init). */
1177 silc_server_config_unref(&server->config_ref);
1178 silc_server_config_destroy(server->config);
1180 /* Take new config context */
1181 server->config = newconfig;
1182 silc_server_config_ref(&server->config_ref, server->config, server->config);
1185 /* Set debugging on if configured */
1186 if (server->config->debug_string) {
1187 silc_log_debug(TRUE);
1188 silc_log_set_debug_string(server->config->debug_string);
1190 #endif /* SILC_DEBUG */
1192 SILC_LOG_DEBUG(("Server rehashed"));
1197 /* The heart of the server. This runs the scheduler thus runs the server.
1198 When this returns the server has been stopped and the program will
1201 void silc_server_run(SilcServer server)
1203 SILC_LOG_INFO(("SILC Server started"));
1205 /* Start the scheduler, the heart of the SILC server. When this returns
1206 the program will be terminated. */
1207 silc_schedule(server->schedule);
1210 /* Stops the SILC server. This function is used to shutdown the server.
1211 This is usually called after the scheduler has returned. After stopping
1212 the server one should call silc_server_free. */
1214 void silc_server_stop(SilcServer server)
1217 SilcPacketStream ps;
1218 SilcNetListener listener;
1220 SILC_LOG_INFO(("SILC Server shutting down"));
1222 server->server_shutdown = TRUE;
1224 /* Close all connections */
1225 if (server->packet_engine) {
1226 list = silc_packet_engine_get_streams(server->packet_engine);
1228 silc_dlist_start(list);
1229 while ((ps = silc_dlist_get(list))) {
1230 SilcIDListData idata = silc_packet_get_context(ps);
1232 if (!silc_packet_stream_is_valid(ps))
1236 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1238 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1239 "Server is shutting down");
1240 silc_server_free_sock_user_data(server, ps,
1241 "Server is shutting down");
1243 silc_packet_engine_free_streams_list(list);
1246 /* We are not connected to network anymore */
1247 server->standalone = TRUE;
1249 silc_dlist_start(server->listeners);
1250 while ((listener = silc_dlist_get(server->listeners)))
1251 silc_net_close_listener(listener);
1253 silc_server_http_uninit(server);
1255 /* Cancel any possible retry timeouts */
1256 silc_schedule_task_del_by_callback(server->schedule,
1257 silc_server_connect_router);
1258 silc_schedule_task_del_by_callback(server->schedule,
1259 silc_server_connect_to_router_retry);
1260 silc_schedule_task_del_by_callback(server->schedule,
1261 silc_server_connect_to_router);
1263 silc_schedule_stop(server->schedule);
1265 SILC_LOG_DEBUG(("Server stopped"));
1268 /* Purge expired client entries from the server */
1270 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1272 SilcServer server = context;
1273 SilcClientEntry client;
1275 SilcUInt64 curtime = silc_time();
1277 SILC_LOG_DEBUG(("Expire timeout"));
1279 silc_dlist_start(server->expired_clients);
1280 while ((client = silc_dlist_get(server->expired_clients))) {
1281 /* For unregistered clients the created timestamp is actually
1282 unregistered timestamp. Make sure client remains in history
1283 at least 500 seconds. */
1284 if (client->data.created && curtime - client->data.created < 500)
1287 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1288 server->local_list : server->global_list);
1290 silc_idlist_del_data(client);
1291 silc_idlist_del_client(id_list, client);
1292 silc_dlist_del(server->expired_clients, client);
1295 silc_schedule_task_add_timeout(server->schedule,
1296 silc_server_purge_expired_clients, server,
1301 /******************************* Connecting *********************************/
1303 /* Free connection context */
1305 void silc_server_connection_free(SilcServerConnection sconn)
1309 SILC_LOG_DEBUG(("Free connection %p", sconn));
1310 silc_dlist_del(sconn->server->conns, sconn);
1311 silc_server_config_unref(&sconn->conn);
1312 silc_free(sconn->remote_host);
1313 silc_free(sconn->backup_replace_ip);
1317 /* Creates connection to a remote router. */
1319 void silc_server_create_connection(SilcServer server,
1322 const char *remote_host, SilcUInt32 port,
1323 SilcServerConnectCallback callback,
1326 SilcServerConnection sconn;
1328 /* Allocate connection object for hold connection specific stuff. */
1329 sconn = silc_calloc(1, sizeof(*sconn));
1332 sconn->remote_host = strdup(remote_host);
1333 sconn->remote_port = port;
1334 sconn->no_reconnect = reconnect == FALSE;
1335 sconn->callback = callback;
1336 sconn->callback_context = context;
1337 sconn->no_conf = dynamic;
1338 sconn->server = server;
1340 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1341 remote_host, port));
1343 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1347 /* Connection authentication completion callback */
1350 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1353 SilcServerConnection sconn = context;
1354 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1355 SilcServer server = entry->server;
1356 SilcServerConfigServer *conn;
1357 SilcServerConfigConnParams *param;
1358 SilcIDListData idata;
1359 SilcServerEntry id_entry = NULL;
1360 unsigned char id[32];
1365 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1370 if (success == FALSE) {
1371 /* Authentication failed */
1373 /* Try reconnecting if configuration wants it */
1374 if (!sconn->no_reconnect) {
1375 silc_schedule_task_add_timeout(server->schedule,
1376 silc_server_connect_to_router_retry,
1378 silc_dlist_del(server->conns, sconn);
1382 if (sconn->callback)
1383 (*sconn->callback)(server, NULL, sconn->callback_context);
1384 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1385 silc_server_disconnect_remote(server, sconn->sock,
1386 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1390 /* XXX For now remote is router always */
1391 entry->data.conn_type = SILC_CONN_ROUTER;
1393 SILC_LOG_INFO(("Connected to %s %s",
1394 SILC_CONNTYPE_STRING(entry->data.conn_type),
1395 sconn->remote_host));
1397 /* Create the actual entry for remote entity */
1398 switch (entry->data.conn_type) {
1399 case SILC_CONN_SERVER:
1400 SILC_LOG_DEBUG(("Remote is SILC server"));
1402 /* Add new server. The server must register itself to us before it
1403 becomes registered to SILC network. */
1404 id_entry = silc_idlist_add_server(server->local_list,
1405 strdup(sconn->remote_host),
1406 SILC_SERVER, NULL, NULL, sconn->sock);
1408 if (sconn->callback)
1409 (*sconn->callback)(server, NULL, sconn->callback_context);
1410 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1411 silc_server_disconnect_remote(server, sconn->sock,
1412 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1417 server->stat.my_servers++;
1418 if (server->server_type == SILC_ROUTER)
1419 server->stat.servers++;
1420 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1422 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1425 case SILC_CONN_ROUTER:
1426 SILC_LOG_DEBUG(("Remote is SILC router"));
1428 /* Register to network */
1429 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1430 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1431 SILC_STR_UI_SHORT(id_len),
1432 SILC_STR_DATA(id, id_len),
1433 SILC_STR_UI_SHORT(strlen(server->server_name)),
1434 SILC_STR_DATA(server->server_name,
1435 strlen(server->server_name)),
1437 if (sconn->callback)
1438 (*sconn->callback)(server, NULL, sconn->callback_context);
1439 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1440 silc_server_disconnect_remote(server, sconn->sock,
1441 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1446 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1448 /* Check that we do not have this ID already */
1449 id_entry = silc_idlist_find_server_by_id(server->local_list,
1450 &remote_id.u.server_id,
1453 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1455 id_entry = silc_idlist_find_server_by_id(server->global_list,
1456 &remote_id.u.server_id,
1459 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1463 SILC_LOG_DEBUG(("New server id(%s)",
1464 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1466 /* Add the connected router to global server list. Router is sent
1467 as NULL since it's local to us. */
1468 id_entry = silc_idlist_add_server(server->global_list,
1469 strdup(sconn->remote_host),
1471 silc_id_dup(&remote_id.u.server_id,
1475 /* Try reconnecting if configuration wants it */
1476 if (!sconn->no_reconnect) {
1477 silc_schedule_task_add_timeout(server->schedule,
1478 silc_server_connect_to_router_retry,
1480 silc_dlist_del(server->conns, sconn);
1484 if (sconn->callback)
1485 (*sconn->callback)(server, NULL, sconn->callback_context);
1486 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1487 silc_server_disconnect_remote(server, sconn->sock,
1488 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1493 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1494 idata = (SilcIDListData)id_entry;
1495 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1496 SILC_IDLIST_STATUS_LOCAL);
1497 idata->sconn = sconn;
1498 idata->sconn->callback = NULL;
1501 server->stat.my_routers++;
1502 if (server->server_type == SILC_ROUTER)
1503 server->stat.routers++;
1504 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1506 if (!sconn->backup) {
1507 /* Mark this router our primary router if we're still standalone */
1508 if (server->standalone) {
1509 SILC_LOG_DEBUG(("This connection is our primary router"));
1510 server->id_entry->router = id_entry;
1511 server->router = id_entry;
1512 server->router->server_type = SILC_ROUTER;
1513 server->standalone = FALSE;
1514 server->backup_primary = FALSE;
1516 /* Announce data if we are not backup router (unless not as primary
1517 currently). Backup router announces later at the end of
1518 resuming protocol. */
1519 if (server->backup_router && server->server_type == SILC_ROUTER) {
1520 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1522 /* If we are router then announce our possible servers. Backup
1523 router announces also global servers. */
1524 if (server->server_type == SILC_ROUTER)
1525 silc_server_announce_servers(server,
1526 server->backup_router ? TRUE : FALSE,
1527 0, SILC_PRIMARY_ROUTE(server));
1529 /* Announce our clients and channels to the router */
1530 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1531 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1534 /* If we are backup router then this primary router is whom we are
1536 if (server->server_type == SILC_BACKUP_ROUTER) {
1537 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1539 NULL, NULL, &ip, NULL);
1540 silc_server_backup_add(server, server->id_entry, ip,
1541 sconn->remote_port, TRUE);
1546 /* We already have primary router. Disconnect this connection */
1547 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1548 silc_idlist_del_server(server->global_list, id_entry);
1549 if (sconn->callback)
1550 (*sconn->callback)(server, NULL, sconn->callback_context);
1551 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1552 silc_server_disconnect_remote(server, sconn->sock,
1553 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1558 /* Add this server to be our backup router */
1559 id_entry->server_type = SILC_BACKUP_ROUTER;
1560 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1561 sconn->backup_replace_port, FALSE);
1567 if (sconn->callback)
1568 (*sconn->callback)(server, NULL, sconn->callback_context);
1569 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1570 silc_server_disconnect_remote(server, sconn->sock,
1571 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1575 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1577 conn = sconn->conn.ref_ptr;
1578 param = &server->config->param;
1579 if (conn && conn->param)
1580 param = conn->param;
1582 /* Register rekey timeout */
1583 sconn->rekey_timeout = param->key_exchange_rekey;
1584 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1585 sconn->sock, sconn->rekey_timeout, 0);
1587 /* Set the entry as packet stream context */
1588 silc_packet_set_context(sconn->sock, id_entry);
1590 /* Call the completion callback to indicate that we've connected to
1592 if (sconn && sconn->callback)
1593 (*sconn->callback)(server, id_entry, sconn->callback_context);
1595 if (sconn == server->router_conn)
1596 server->router_conn = NULL;
1601 /* SKE completion callback */
1603 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1604 SilcSKESecurityProperties prop,
1605 SilcSKEKeyMaterial keymat,
1606 SilcSKERekeyMaterial rekey,
1609 SilcPacketStream sock = context;
1610 SilcUnknownEntry entry = silc_packet_get_context(sock);
1611 SilcServerConnection sconn;
1613 SilcServerConfigRouter *conn;
1614 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1615 void *auth_data = NULL;
1616 SilcUInt32 auth_data_len = 0;
1617 SilcConnAuth connauth;
1618 SilcCipher send_key, receive_key;
1619 SilcHmac hmac_send, hmac_receive;
1621 server = entry->server;
1622 sconn = entry->data.sconn;
1623 conn = sconn->conn.ref_ptr;
1626 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1628 if (status != SILC_SKE_STATUS_OK) {
1630 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1631 silc_ske_map_status(status), entry->hostname, entry->ip));
1634 /* Try reconnecting if configuration wants it */
1635 if (!sconn->no_reconnect) {
1636 silc_schedule_task_add_timeout(server->schedule,
1637 silc_server_connect_to_router_retry,
1639 silc_dlist_del(server->conns, sconn);
1643 if (sconn->callback)
1644 (*sconn->callback)(server, NULL, sconn->callback_context);
1645 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1646 silc_server_disconnect_remote(server, sconn->sock,
1647 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1651 SILC_LOG_DEBUG(("Setting keys into use"));
1653 /* Set the keys into use. The data will be encrypted after this. */
1654 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1655 &hmac_send, &hmac_receive, NULL)) {
1658 /* Try reconnecting if configuration wants it */
1659 if (!sconn->no_reconnect) {
1660 silc_schedule_task_add_timeout(server->schedule,
1661 silc_server_connect_to_router_retry,
1663 silc_dlist_del(server->conns, sconn);
1667 /* Error setting keys */
1668 if (sconn->callback)
1669 (*sconn->callback)(server, NULL, sconn->callback_context);
1670 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1671 silc_server_disconnect_remote(server, sconn->sock,
1672 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1675 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1676 hmac_receive, FALSE);
1678 SILC_LOG_DEBUG(("Starting connection authentication"));
1680 connauth = silc_connauth_alloc(server->schedule, ske,
1681 server->config->conn_auth_timeout);
1685 /* Try reconnecting if configuration wants it */
1686 if (!sconn->no_reconnect) {
1687 silc_schedule_task_add_timeout(server->schedule,
1688 silc_server_connect_to_router_retry,
1690 silc_dlist_del(server->conns, sconn);
1694 /** Error allocating auth protocol */
1695 if (sconn->callback)
1696 (*sconn->callback)(server, NULL, sconn->callback_context);
1697 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1698 silc_server_disconnect_remote(server, sconn->sock,
1699 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1703 /* Get authentication method */
1705 if (conn->passphrase) {
1706 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1707 auth_meth = SILC_AUTH_PUBLIC_KEY;
1708 auth_data = server->private_key;
1710 auth_meth = SILC_AUTH_PASSWORD;
1711 auth_data = conn->passphrase;
1712 auth_data_len = conn->passphrase_len;
1715 auth_meth = SILC_AUTH_PUBLIC_KEY;
1716 auth_data = server->private_key;
1720 entry->data.rekey = rekey;
1722 /* Start connection authentication */
1724 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1725 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1726 auth_data, auth_data_len,
1727 silc_server_ke_auth_compl, sconn);
1730 /* Function that is called when the network connection to a router has
1731 been established. This will continue with the key exchange protocol
1732 with the remote router. */
1734 void silc_server_start_key_exchange(SilcServerConnection sconn)
1736 SilcServer server = sconn->server;
1737 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1738 SilcUnknownEntry entry;
1739 SilcSKEParamsStruct params;
1742 /* Cancel any possible retry timeouts */
1743 silc_schedule_task_del_by_context(server->schedule, sconn);
1745 /* Create packet stream */
1746 sconn->sock = silc_packet_stream_create(server->packet_engine,
1747 server->schedule, sconn->stream);
1749 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1750 silc_stream_destroy(sconn->stream);
1752 /* Try reconnecting if configuration wants it */
1753 if (!sconn->no_reconnect) {
1754 silc_schedule_task_add_timeout(server->schedule,
1755 silc_server_connect_to_router_retry,
1757 silc_dlist_del(server->conns, sconn);
1761 if (sconn->callback)
1762 (*sconn->callback)(server, NULL, sconn->callback_context);
1763 silc_server_connection_free(sconn);
1766 server->stat.conn_num++;
1768 /* Set source ID to packet stream */
1769 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1771 silc_packet_stream_destroy(sconn->sock);
1773 /* Try reconnecting if configuration wants it */
1774 if (!sconn->no_reconnect) {
1775 silc_schedule_task_add_timeout(server->schedule,
1776 silc_server_connect_to_router_retry,
1778 silc_dlist_del(server->conns, sconn);
1782 if (sconn->callback)
1783 (*sconn->callback)(server, NULL, sconn->callback_context);
1784 silc_server_connection_free(sconn);
1788 /* Create entry for remote entity */
1789 entry = silc_calloc(1, sizeof(*entry));
1791 silc_packet_stream_destroy(sconn->sock);
1793 /* Try reconnecting if configuration wants it */
1794 if (!sconn->no_reconnect) {
1795 silc_schedule_task_add_timeout(server->schedule,
1796 silc_server_connect_to_router_retry,
1798 silc_dlist_del(server->conns, sconn);
1802 if (sconn->callback)
1803 (*sconn->callback)(server, NULL, sconn->callback_context);
1804 silc_server_connection_free(sconn);
1807 entry->server = server;
1808 entry->data.sconn = sconn;
1809 entry->data.conn_type = SILC_CONN_UNKNOWN;
1810 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1811 silc_packet_set_context(sconn->sock, entry);
1813 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1815 /* Set Key Exchange flags from configuration, but fall back to global
1817 memset(¶ms, 0, sizeof(params));
1818 SILC_GET_SKE_FLAGS(conn, params.flags);
1819 if (server->config->param.key_exchange_pfs)
1820 params.flags |= SILC_SKE_SP_FLAG_PFS;
1822 /* Start SILC Key Exchange protocol */
1823 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1824 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1825 server->public_key, server->private_key, sconn);
1828 silc_packet_stream_destroy(sconn->sock);
1830 /* Try reconnecting if configuration wants it */
1831 if (!sconn->no_reconnect) {
1832 silc_schedule_task_add_timeout(server->schedule,
1833 silc_server_connect_to_router_retry,
1835 silc_dlist_del(server->conns, sconn);
1839 if (sconn->callback)
1840 (*sconn->callback)(server, NULL, sconn->callback_context);
1841 silc_server_connection_free(sconn);
1844 silc_ske_set_callbacks(ske, silc_server_verify_key,
1845 silc_server_ke_completed, sconn->sock);
1847 /* Start key exchange protocol */
1848 params.version = silc_version_string;
1849 params.timeout_secs = server->config->key_exchange_timeout;
1850 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1853 /* Timeout callback that will be called to retry connecting to remote
1854 router. This is used by both normal and router server. This will wait
1855 before retrying the connecting. The timeout is generated by exponential
1856 backoff algorithm. */
1858 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1860 SilcServerConnection sconn = context;
1861 SilcServer server = sconn->server;
1862 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1863 SilcServerConfigConnParams *param =
1864 (conn->param ? conn->param : &server->config->param);
1866 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1867 sconn->remote_port));
1869 /* Calculate next timeout */
1870 if (sconn->retry_count >= 1) {
1871 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1872 if (sconn->retry_timeout > param->reconnect_interval_max)
1873 sconn->retry_timeout = param->reconnect_interval_max;
1875 sconn->retry_timeout = param->reconnect_interval;
1877 sconn->retry_count++;
1878 sconn->retry_timeout = sconn->retry_timeout +
1879 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1881 /* If we've reached max retry count, give up. */
1882 if ((sconn->retry_count > param->reconnect_count) &&
1883 sconn->no_reconnect) {
1884 SILC_LOG_ERROR(("Could not connect, giving up"));
1886 if (sconn->callback)
1887 (*sconn->callback)(server, NULL, sconn->callback_context);
1888 silc_server_connection_free(sconn);
1892 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1894 /* We will lookup a fresh pointer later */
1895 silc_server_config_unref(&sconn->conn);
1897 /* Wait before retrying */
1898 silc_schedule_task_del_by_context(server->schedule, sconn);
1899 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1900 sconn, sconn->retry_timeout, 0);
1903 /* Callback for async connection to remote router */
1905 static void silc_server_connection_established(SilcNetStatus status,
1909 SilcServerConnection sconn = context;
1910 SilcServer server = sconn->server;
1912 silc_schedule_task_del_by_context(server->schedule, sconn);
1917 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1918 sconn->remote_host, sconn->remote_port));
1920 /* Continue with key exchange protocol */
1921 sconn->stream = stream;
1922 silc_server_start_key_exchange(sconn);
1925 case SILC_NET_UNKNOWN_IP:
1926 case SILC_NET_UNKNOWN_HOST:
1927 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1928 sconn->remote_host, sconn->remote_port,
1929 silc_net_get_error_string(status)));
1930 if (!sconn->no_reconnect) {
1931 silc_schedule_task_add_timeout(sconn->server->schedule,
1932 silc_server_connect_to_router_retry,
1934 silc_dlist_del(server->conns, sconn);
1936 if (sconn->callback)
1937 (*sconn->callback)(server, NULL, sconn->callback_context);
1938 silc_server_connection_free(sconn);
1943 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1944 sconn->remote_host, sconn->remote_port,
1945 silc_net_get_error_string(status)));
1946 if (!sconn->no_reconnect) {
1947 silc_schedule_task_add_timeout(sconn->server->schedule,
1948 silc_server_connect_to_router_retry,
1950 silc_dlist_del(server->conns, sconn);
1952 if (sconn->callback)
1953 (*sconn->callback)(server, NULL, sconn->callback_context);
1954 silc_server_connection_free(sconn);
1960 /* Generic routine to use connect to a router. */
1962 SILC_TASK_CALLBACK(silc_server_connect_router)
1964 SilcServerConnection sconn = context;
1965 SilcServer server = sconn->server;
1966 SilcServerConfigRouter *rconn;
1968 silc_schedule_task_del_by_context(server->schedule, sconn);
1970 /* Don't connect if we are shutting down. */
1971 if (server->server_shutdown) {
1972 if (sconn->callback)
1973 (*sconn->callback)(server, NULL, sconn->callback_context);
1974 silc_server_connection_free(sconn);
1978 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1979 (sconn->backup ? "backup router" : "router"),
1980 sconn->remote_host, sconn->remote_port));
1982 if (!sconn->no_conf) {
1983 /* Find connection configuration */
1984 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1985 sconn->remote_port);
1987 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1988 (sconn->backup ? "backup router" : "router"),
1989 sconn->remote_host, sconn->remote_port));
1990 if (sconn->callback)
1991 (*sconn->callback)(server, NULL, sconn->callback_context);
1992 silc_server_connection_free(sconn);
1995 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1998 /* Connect to remote host */
2000 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
2001 server->config->server_info->primary->server_ip),
2002 sconn->remote_host, sconn->remote_port,
2003 server->schedule, silc_server_connection_established,
2006 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2007 sconn->remote_host, sconn->remote_port));
2008 if (sconn->callback)
2009 (*sconn->callback)(server, NULL, sconn->callback_context);
2010 silc_server_connection_free(sconn);
2014 /* Add to connection list */
2015 silc_dlist_add(server->conns, sconn);
2018 /* This function connects to our primary router or if we are a router this
2019 establishes all our primary routes. This is called at the start of the
2020 server to do authentication and key exchange with our router - called
2023 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2025 SilcServer server = context;
2026 SilcServerConnection sconn;
2027 SilcServerConfigRouter *ptr;
2028 SilcServerConfigConnParams *param;
2030 /* Don't connect if we are shutting down. */
2031 if (server->server_shutdown)
2034 SILC_LOG_DEBUG(("We are %s",
2035 (server->server_type == SILC_SERVER ?
2036 "normal server" : server->server_type == SILC_ROUTER ?
2037 "router" : "backup router/normal server")));
2039 if (!server->config->routers) {
2040 /* There wasn't a configured router, we will continue but we don't
2041 have a connection to outside world. We will be standalone server. */
2042 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2043 server->standalone = TRUE;
2047 /* Cancel any possible retry timeouts */
2048 silc_schedule_task_del_by_callback(server->schedule,
2049 silc_server_connect_router);
2050 silc_schedule_task_del_by_callback(server->schedule,
2051 silc_server_connect_to_router_retry);
2053 /* Create the connections to all our routes */
2054 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2056 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2057 ptr->backup_router ? "Backup router" : "Router",
2058 ptr->initiator ? "Initiator" : "Responder",
2059 ptr->host, ptr->port));
2061 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2062 ptr->initiator == FALSE && !server->backup_router &&
2063 !silc_server_config_get_backup_router(server))
2064 server->wait_backup = TRUE;
2066 if (!ptr->initiator)
2068 if (ptr->dynamic_connection)
2071 /* Check whether we are connecting or connected to this host already */
2072 if (silc_server_num_sockets_by_remote(server,
2073 silc_net_is_ip(ptr->host) ?
2075 silc_net_is_ip(ptr->host) ?
2076 NULL : ptr->host, ptr->port,
2077 SILC_CONN_ROUTER)) {
2078 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2079 ptr->host, ptr->port));
2081 /* If we don't have primary router and this connection is our
2082 primary router we are in desync. Reconnect to the primary. */
2083 if (server->standalone && !server->router) {
2085 SilcPacketStream sock;
2086 SilcServerConfigRouter *primary =
2087 silc_server_config_get_primary_router(server);
2090 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2091 ptr->host, ptr->port);
2094 server->backup_noswitch = TRUE;
2095 silc_server_free_sock_user_data(server, sock, NULL);
2096 silc_server_disconnect_remote(server, sock, 0, NULL);
2097 server->backup_noswitch = FALSE;
2098 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2104 param = (ptr->param ? ptr->param : &server->config->param);
2106 /* Allocate connection object for hold connection specific stuff. */
2107 sconn = silc_calloc(1, sizeof(*sconn));
2110 sconn->server = server;
2111 sconn->remote_host = strdup(ptr->host);
2112 sconn->remote_port = ptr->port;
2113 sconn->backup = ptr->backup_router;
2114 if (sconn->backup) {
2115 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2116 sconn->backup_replace_port = ptr->backup_replace_port;
2118 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2120 SILC_LOG_DEBUG(("Created connection %p", sconn));
2122 if (!server->router_conn && !sconn->backup)
2123 server->router_conn = sconn;
2126 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2132 /************************ Accepting new connection **************************/
2134 /* After this is called, server don't wait for backup router anymore.
2135 This gets called automatically even after we have backup router
2136 connection established. */
2138 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2140 SilcServer server = context;
2141 server->wait_backup = FALSE;
2144 /* Authentication data callback */
2147 silc_server_accept_get_auth(SilcConnAuth connauth,
2148 SilcConnectionType conn_type,
2149 unsigned char **passphrase,
2150 SilcUInt32 *passphrase_len,
2151 SilcSKR *repository,
2154 SilcPacketStream sock = context;
2155 SilcUnknownEntry entry = silc_packet_get_context(sock);
2156 SilcServer server = entry->server;
2158 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2160 /* Remote end is client */
2161 if (conn_type == SILC_CONN_CLIENT) {
2162 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2166 *passphrase = cconfig->passphrase;
2167 *passphrase_len = cconfig->passphrase_len;
2168 if (cconfig->publickeys)
2169 *repository = server->repository;
2171 if (cconfig->publickeys) {
2172 if (server->config->prefer_passphrase_auth) {
2176 *passphrase_len = 0;
2180 entry->conn_type = conn_type;
2184 /* Remote end is server */
2185 if (conn_type == SILC_CONN_SERVER) {
2186 SilcServerConfigServer *sconfig;
2188 /* If we are normal server, don't accept the connection */
2189 if (server->server_type == SILC_SERVER)
2192 sconfig = entry->sconfig.ref_ptr;
2196 *passphrase = sconfig->passphrase;
2197 *passphrase_len = sconfig->passphrase_len;
2198 if (sconfig->publickeys)
2199 *repository = server->repository;
2201 if (sconfig->publickeys) {
2202 if (server->config->prefer_passphrase_auth) {
2206 *passphrase_len = 0;
2210 entry->conn_type = conn_type;
2214 /* Remote end is router */
2215 if (conn_type == SILC_CONN_ROUTER) {
2216 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2220 *passphrase = rconfig->passphrase;
2221 *passphrase_len = rconfig->passphrase_len;
2222 if (rconfig->publickeys)
2223 *repository = server->repository;
2225 if (rconfig->publickeys) {
2226 if (server->config->prefer_passphrase_auth) {
2230 *passphrase_len = 0;
2234 entry->conn_type = conn_type;
2241 /* Authentication completion callback. */
2244 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2247 SilcPacketStream sock = context;
2248 SilcUnknownEntry entry = silc_packet_get_context(sock);
2249 SilcIDListData idata = (SilcIDListData)entry;
2250 SilcServer server = entry->server;
2251 SilcServerConfigConnParams *param = &server->config->param;
2252 SilcServerConnection sconn;
2254 const char *hostname, *ip;
2258 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2259 NULL, &hostname, &ip, &port);
2261 if (success == FALSE) {
2262 /* Authentication failed */
2263 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2264 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2265 server->stat.auth_failures++;
2266 silc_server_disconnect_remote(server, sock,
2267 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2268 silc_server_config_unref(&entry->cconfig);
2269 silc_server_config_unref(&entry->sconfig);
2270 silc_server_config_unref(&entry->rconfig);
2271 silc_server_free_sock_user_data(server, sock, NULL);
2275 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2277 switch (entry->conn_type) {
2278 case SILC_CONN_CLIENT:
2280 SilcClientEntry client;
2281 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2283 /* Verify whether this connection is after all allowed to connect */
2284 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2285 &server->config->param,
2287 silc_connauth_get_ske(connauth))) {
2288 server->stat.auth_failures++;
2292 /* If we are primary router and we have backup router configured
2293 but it has not connected to use yet, do not accept any other
2295 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2296 !server->backup_router) {
2297 SilcServerConfigRouter *router;
2298 router = silc_server_config_get_backup_router(server);
2299 if (router && strcmp(server->config->server_info->primary->server_ip,
2301 silc_server_find_socket_by_host(server,
2303 router->backup_replace_ip, 0)) {
2304 SILC_LOG_INFO(("Will not accept connections because we do "
2305 "not have backup router connection established"));
2306 silc_server_disconnect_remote(server, sock,
2307 SILC_STATUS_ERR_PERM_DENIED,
2308 "We do not have connection to backup "
2309 "router established, try later");
2310 silc_server_config_unref(&entry->cconfig);
2311 silc_server_config_unref(&entry->sconfig);
2312 silc_server_config_unref(&entry->rconfig);
2313 silc_server_free_sock_user_data(server, sock, NULL);
2314 server->stat.auth_failures++;
2316 /* From here on, wait 20 seconds for the backup router to appear. */
2317 silc_schedule_task_add_timeout(server->schedule,
2318 silc_server_backup_router_wait,
2319 (void *)server, 20, 0);
2324 SILC_LOG_DEBUG(("Remote host is client"));
2325 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2328 /* Add the client to the client ID cache. The nickname and Client ID
2329 and other information is created after we have received NEW_CLIENT
2330 packet from client. */
2331 client = silc_idlist_add_client(server->local_list,
2332 NULL, NULL, NULL, NULL, NULL, sock);
2334 SILC_LOG_ERROR(("Could not add new client to cache"));
2335 server->stat.auth_failures++;
2336 silc_server_disconnect_remote(server, sock,
2337 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2338 silc_server_config_unref(&entry->cconfig);
2339 silc_server_config_unref(&entry->sconfig);
2340 silc_server_config_unref(&entry->rconfig);
2341 silc_server_free_sock_user_data(server, sock, NULL);
2344 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2345 entry->data.conn_type = SILC_CONN_CLIENT;
2348 server->stat.my_clients++;
2349 server->stat.clients++;
2350 server->stat.cell_clients++;
2352 /* Get connection parameters */
2354 param = conn->param;
2356 if (!param->keepalive_secs)
2357 param->keepalive_secs = server->config->param.keepalive_secs;
2359 if (!param->qos && server->config->param.qos) {
2360 param->qos = server->config->param.qos;
2361 param->qos_rate_limit = server->config->param.qos_rate_limit;
2362 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2363 param->qos_limit_sec = server->config->param.qos_limit_sec;
2364 param->qos_limit_usec = server->config->param.qos_limit_usec;
2367 /* Check if to be anonymous connection */
2368 if (param->anonymous)
2369 client->mode |= SILC_UMODE_ANONYMOUS;
2372 /* Add public key to repository */
2373 SILC_LOG_DEBUG(("Add client public key to repository"));
2374 if (!silc_server_get_public_key_by_client(server, client, NULL))
2375 silc_skr_add_public_key_simple(server->repository,
2376 entry->data.public_key,
2377 SILC_SKR_USAGE_IDENTIFICATION, client,
2380 id_entry = (void *)client;
2384 case SILC_CONN_SERVER:
2385 case SILC_CONN_ROUTER:
2387 SilcServerEntry new_server;
2388 SilcBool initiator = FALSE;
2389 SilcBool backup_local = FALSE;
2390 SilcBool backup_router = FALSE;
2391 char *backup_replace_ip = NULL;
2392 SilcUInt16 backup_replace_port = 0;
2393 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2394 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2396 /* If we are backup router and this is incoming server connection
2397 and we do not have connection to primary router, do not allow
2399 if (server->server_type == SILC_BACKUP_ROUTER &&
2400 entry->conn_type == SILC_CONN_SERVER &&
2401 !SILC_PRIMARY_ROUTE(server)) {
2402 SILC_LOG_INFO(("Will not accept server connection because we do "
2403 "not have primary router connection established"));
2404 silc_server_disconnect_remote(server, sock,
2405 SILC_STATUS_ERR_PERM_DENIED,
2406 "We do not have connection to primary "
2407 "router established, try later");
2408 silc_server_config_unref(&entry->cconfig);
2409 silc_server_config_unref(&entry->sconfig);
2410 silc_server_config_unref(&entry->rconfig);
2411 silc_server_free_sock_user_data(server, sock, NULL);
2412 server->stat.auth_failures++;
2416 if (entry->conn_type == SILC_CONN_ROUTER) {
2417 /* Verify whether this connection is after all allowed to connect */
2418 if (!silc_server_connection_allowed(server, sock,
2420 &server->config->param,
2421 rconn ? rconn->param : NULL,
2422 silc_connauth_get_ske(connauth))) {
2423 silc_server_config_unref(&entry->cconfig);
2424 silc_server_config_unref(&entry->sconfig);
2425 silc_server_config_unref(&entry->rconfig);
2426 server->stat.auth_failures++;
2432 param = rconn->param;
2434 if (!param->keepalive_secs)
2435 param->keepalive_secs = server->config->param.keepalive_secs;
2437 if (!param->qos && server->config->param.qos) {
2438 param->qos = server->config->param.qos;
2439 param->qos_rate_limit = server->config->param.qos_rate_limit;
2440 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2441 param->qos_limit_sec = server->config->param.qos_limit_sec;
2442 param->qos_limit_usec = server->config->param.qos_limit_usec;
2446 initiator = rconn->initiator;
2447 backup_local = rconn->backup_local;
2448 backup_router = rconn->backup_router;
2449 backup_replace_ip = rconn->backup_replace_ip;
2450 backup_replace_port = rconn->backup_replace_port;
2454 if (entry->conn_type == SILC_CONN_SERVER) {
2455 /* Verify whether this connection is after all allowed to connect */
2456 if (!silc_server_connection_allowed(server, sock,
2458 &server->config->param,
2459 srvconn ? srvconn->param : NULL,
2460 silc_connauth_get_ske(connauth))) {
2461 server->stat.auth_failures++;
2465 if (srvconn->param) {
2466 param = srvconn->param;
2468 if (!param->keepalive_secs)
2469 param->keepalive_secs = server->config->param.keepalive_secs;
2471 if (!param->qos && server->config->param.qos) {
2472 param->qos = server->config->param.qos;
2473 param->qos_rate_limit = server->config->param.qos_rate_limit;
2474 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2475 param->qos_limit_sec = server->config->param.qos_limit_sec;
2476 param->qos_limit_usec = server->config->param.qos_limit_usec;
2480 backup_router = srvconn->backup_router;
2484 /* If we are primary router and we have backup router configured
2485 but it has not connected to use yet, do not accept any other
2487 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2488 !server->backup_router && !backup_router) {
2489 SilcServerConfigRouter *router;
2490 router = silc_server_config_get_backup_router(server);
2491 if (router && strcmp(server->config->server_info->primary->server_ip,
2493 silc_server_find_socket_by_host(server,
2495 router->backup_replace_ip, 0)) {
2496 SILC_LOG_INFO(("Will not accept connections because we do "
2497 "not have backup router connection established"));
2498 silc_server_disconnect_remote(server, sock,
2499 SILC_STATUS_ERR_PERM_DENIED,
2500 "We do not have connection to backup "
2501 "router established, try later");
2502 silc_server_config_unref(&entry->cconfig);
2503 silc_server_config_unref(&entry->sconfig);
2504 silc_server_config_unref(&entry->rconfig);
2505 silc_server_free_sock_user_data(server, sock, NULL);
2506 server->stat.auth_failures++;
2508 /* From here on, wait 20 seconds for the backup router to appear. */
2509 silc_schedule_task_add_timeout(server->schedule,
2510 silc_server_backup_router_wait,
2511 (void *)server, 20, 0);
2516 SILC_LOG_DEBUG(("Remote host is %s",
2517 entry->conn_type == SILC_CONN_SERVER ?
2518 "server" : (backup_router ?
2519 "backup router" : "router")));
2520 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2521 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2522 "server" : (backup_router ?
2523 "backup router" : "router")));
2525 /* Add the server into server cache. The server name and Server ID
2526 is updated after we have received NEW_SERVER packet from the
2527 server. We mark ourselves as router for this server if we really
2530 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2531 server->local_list : (backup_router ?
2532 server->local_list :
2533 server->global_list)),
2535 (entry->conn_type == SILC_CONN_SERVER ?
2536 SILC_SERVER : SILC_ROUTER),
2538 (entry->conn_type == SILC_CONN_SERVER ?
2539 server->id_entry : (backup_router ?
2540 server->id_entry : NULL)),
2543 SILC_LOG_ERROR(("Could not add new server to cache"));
2544 silc_server_disconnect_remote(server, sock,
2545 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2546 silc_server_config_unref(&entry->cconfig);
2547 silc_server_config_unref(&entry->sconfig);
2548 silc_server_config_unref(&entry->rconfig);
2549 silc_server_free_sock_user_data(server, sock, NULL);
2550 server->stat.auth_failures++;
2553 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2554 entry->data.conn_type = entry->conn_type;
2556 id_entry = (void *)new_server;
2558 /* If the incoming connection is router and marked as backup router
2559 then add it to be one of our backups */
2560 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2561 /* Change it back to SERVER type since that's what it really is. */
2563 entry->data.conn_type = SILC_CONN_SERVER;
2564 new_server->server_type = SILC_BACKUP_ROUTER;
2566 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2567 ("Backup router %s is now online",
2570 /* Remove the backup waiting with timeout */
2571 silc_schedule_task_add_timeout(server->schedule,
2572 silc_server_backup_router_wait,
2573 (void *)server, 10, 0);
2577 if (entry->data.conn_type == SILC_CONN_SERVER) {
2578 server->stat.my_servers++;
2579 server->stat.servers++;
2580 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2582 server->stat.my_routers++;
2583 server->stat.routers++;
2584 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2587 /* Check whether this connection is to be our primary router connection
2588 if we do not already have the primary route. */
2589 if (!backup_router &&
2590 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2591 if (silc_server_config_is_primary_route(server) && !initiator)
2594 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2595 server->standalone = FALSE;
2596 if (!server->id_entry->router) {
2597 server->id_entry->router = id_entry;
2598 server->router = id_entry;
2610 /* Add connection to server->conns so that we know we have connection
2612 sconn = silc_calloc(1, sizeof(*sconn));
2613 sconn->server = server;
2615 sconn->remote_host = strdup(hostname);
2616 sconn->remote_port = port;
2617 silc_dlist_add(server->conns, sconn);
2618 idata->sconn = sconn;
2619 idata->sconn->callback = NULL;
2620 idata->last_receive = time(NULL);
2622 /* Add the common data structure to the ID entry. */
2623 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2624 silc_packet_set_context(sock, id_entry);
2626 /* Connection has been fully established now. Everything is ok. */
2627 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2629 /* Perform Quality of Service */
2631 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2632 param->qos_rate_limit, param->qos_bytes_limit,
2633 param->qos_limit_sec, param->qos_limit_usec);
2635 silc_server_config_unref(&entry->cconfig);
2636 silc_server_config_unref(&entry->sconfig);
2637 silc_server_config_unref(&entry->rconfig);
2641 silc_ske_free(silc_connauth_get_ske(connauth));
2642 silc_connauth_free(connauth);
2645 /* SKE completion callback. We set the new keys into use here. */
2648 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2649 SilcSKESecurityProperties prop,
2650 SilcSKEKeyMaterial keymat,
2651 SilcSKERekeyMaterial rekey,
2654 SilcPacketStream sock = context;
2655 SilcUnknownEntry entry = silc_packet_get_context(sock);
2656 SilcIDListData idata = (SilcIDListData)entry;
2657 SilcServer server = entry->server;
2658 SilcConnAuth connauth;
2659 SilcCipher send_key, receive_key;
2660 SilcHmac hmac_send, hmac_receive;
2667 if (status != SILC_SKE_STATUS_OK) {
2669 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2670 silc_ske_map_status(status), entry->hostname, entry->ip));
2672 silc_server_disconnect_remote(server, sock,
2673 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2674 silc_server_config_unref(&entry->cconfig);
2675 silc_server_config_unref(&entry->sconfig);
2676 silc_server_config_unref(&entry->rconfig);
2677 silc_server_free_sock_user_data(server, sock, NULL);
2681 SILC_LOG_DEBUG(("Setting keys into use"));
2683 /* Set the keys into use. The data will be encrypted after this. */
2684 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2685 &hmac_send, &hmac_receive, &hash)) {
2686 /* Error setting keys */
2688 silc_server_disconnect_remote(server, sock,
2689 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2690 silc_server_free_sock_user_data(server, sock, NULL);
2693 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2694 hmac_receive, FALSE);
2696 idata->rekey = rekey;
2697 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2698 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2700 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2705 SILC_LOG_DEBUG(("Starting connection authentication"));
2706 server->stat.auth_attempts++;
2708 connauth = silc_connauth_alloc(server->schedule, ske,
2709 server->config->conn_auth_timeout);
2711 /** Error allocating auth protocol */
2713 silc_server_disconnect_remote(server, sock,
2714 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2715 silc_server_config_unref(&entry->cconfig);
2716 silc_server_config_unref(&entry->sconfig);
2717 silc_server_config_unref(&entry->rconfig);
2718 silc_server_free_sock_user_data(server, sock, NULL);
2722 /* Start connection authentication */
2724 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2725 silc_server_accept_auth_compl, sock);
2728 /* Accept new TCP connection */
2730 static void silc_server_accept_new_connection(SilcNetStatus status,
2734 SilcServer server = context;
2735 SilcPacketStream packet_stream;
2736 SilcServerConfigClient *cconfig = NULL;
2737 SilcServerConfigServer *sconfig = NULL;
2738 SilcServerConfigRouter *rconfig = NULL;
2739 SilcServerConfigDeny *deny;
2740 SilcUnknownEntry entry;
2742 SilcSKEParamsStruct params;
2743 char *hostname, *ip;
2746 SILC_LOG_DEBUG(("Accepting new connection"));
2748 /* Check for maximum allowed connections */
2749 server->stat.conn_attempts++;
2750 if (silc_dlist_count(server->conns) >
2751 server->config->param.connections_max) {
2752 SILC_LOG_ERROR(("Refusing connection, server is full"));
2753 server->stat.conn_failures++;
2754 silc_stream_destroy(stream);
2758 /* Get hostname, IP and port */
2759 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2760 (const char **)&ip, &port)) {
2761 /* Bad socket stream */
2762 server->stat.conn_failures++;
2763 silc_stream_destroy(stream);
2767 /* Create packet stream */
2768 packet_stream = silc_packet_stream_create(server->packet_engine,
2769 server->schedule, stream);
2770 if (!packet_stream) {
2771 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2772 server->stat.conn_failures++;
2773 silc_stream_destroy(stream);
2776 server->stat.conn_num++;
2778 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2780 /* Set source ID to packet stream */
2781 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2784 server->stat.conn_failures++;
2785 silc_packet_stream_destroy(packet_stream);
2789 /* Check whether this connection is denied to connect to us. */
2790 deny = silc_server_config_find_denied(server, ip);
2792 deny = silc_server_config_find_denied(server, hostname);
2794 /* The connection is denied */
2795 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2796 silc_server_disconnect_remote(server, packet_stream,
2797 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2799 silc_server_free_sock_user_data(server, packet_stream, NULL);
2803 /* Check whether we have configured this sort of connection at all. We
2804 have to check all configurations since we don't know what type of
2805 connection this is. */
2806 if (!(cconfig = silc_server_config_find_client(server, ip)))
2807 cconfig = silc_server_config_find_client(server, hostname);
2808 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2809 sconfig = silc_server_config_find_server_conn(server, hostname);
2810 if (server->server_type == SILC_ROUTER)
2811 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2812 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2813 if (!cconfig && !sconfig && !rconfig) {
2814 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2815 server->stat.conn_failures++;
2816 silc_server_disconnect_remote(server, packet_stream,
2817 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2818 silc_server_free_sock_user_data(server, packet_stream, NULL);
2822 /* The connection is allowed */
2823 entry = silc_calloc(1, sizeof(*entry));
2825 server->stat.conn_failures++;
2826 silc_server_disconnect_remote(server, packet_stream,
2827 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2828 silc_server_free_sock_user_data(server, packet_stream, NULL);
2831 entry->hostname = hostname;
2834 entry->server = server;
2835 entry->data.conn_type = SILC_CONN_UNKNOWN;
2836 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2837 silc_packet_set_context(packet_stream, entry);
2839 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2841 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2842 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2843 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2845 /* Take flags for key exchange. Since we do not know what type of connection
2846 this is, we go through all found configurations and use the global ones
2847 as well. This will result always into strictest key exchange flags. */
2848 memset(¶ms, 0, sizeof(params));
2849 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2850 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2851 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2852 if (server->config->param.key_exchange_pfs)
2853 params.flags |= SILC_SKE_SP_FLAG_PFS;
2855 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2856 server->stat.conn_attempts++;
2858 /* Start SILC Key Exchange protocol */
2859 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2860 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2861 server->public_key, server->private_key,
2864 server->stat.conn_failures++;
2865 silc_server_disconnect_remote(server, packet_stream,
2866 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2867 silc_server_free_sock_user_data(server, packet_stream, NULL);
2870 silc_ske_set_callbacks(ske, silc_server_verify_key,
2871 silc_server_accept_completed, packet_stream);
2873 /* Start key exchange protocol */
2874 params.version = silc_version_string;
2875 params.timeout_secs = server->config->key_exchange_timeout;
2876 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2880 /********************************** Rekey ***********************************/
2882 /* Initiator rekey completion callback */
2884 static void silc_server_rekey_completion(SilcSKE ske,
2885 SilcSKEStatus status,
2886 const SilcSKESecurityProperties prop,
2887 const SilcSKEKeyMaterial keymat,
2888 SilcSKERekeyMaterial rekey,
2891 SilcPacketStream sock = context;
2892 SilcIDListData idata = silc_packet_get_context(sock);
2893 SilcServer server = idata->sconn->server;
2895 idata->sconn->op = NULL;
2896 if (status != SILC_SKE_STATUS_OK) {
2897 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2898 idata->sconn->remote_host));
2902 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2903 idata->sconn->remote_host, idata->sconn->remote_port,
2904 SILC_CONNTYPE_STRING(idata->conn_type)));
2906 /* Save rekey data for next rekey */
2907 idata->rekey = rekey;
2909 /* Register new rekey timeout */
2910 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2911 sock, idata->sconn->rekey_timeout, 0);
2914 /* Helper to stop future rekeys on a link. */
2915 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2917 if (!client->connection)
2920 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2922 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2923 client->connection);
2926 /* Rekey callback. Start rekey as initiator */
2928 SILC_TASK_CALLBACK(silc_server_do_rekey)
2930 SilcServer server = app_context;
2931 SilcPacketStream sock = context;
2932 SilcIDListData idata = silc_packet_get_context(sock);
2935 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2937 /* Do not execute rekey with disabled connections */
2938 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2941 /* If another protocol is active do not start rekey */
2942 if (idata->sconn->op) {
2943 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2944 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2949 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2950 idata->sconn->remote_host, idata->sconn->remote_port,
2951 SILC_CONNTYPE_STRING(idata->conn_type)));
2954 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2955 server->public_key, NULL, sock);
2959 /* Set SKE callbacks */
2960 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2963 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2966 /* Responder rekey completion callback */
2969 silc_server_rekey_resp_completion(SilcSKE ske,
2970 SilcSKEStatus status,
2971 const SilcSKESecurityProperties prop,
2972 const SilcSKEKeyMaterial keymat,
2973 SilcSKERekeyMaterial rekey,
2976 SilcPacketStream sock = context;
2977 SilcIDListData idata = silc_packet_get_context(sock);
2979 idata->sconn->op = NULL;
2980 if (status != SILC_SKE_STATUS_OK) {
2981 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2982 idata->sconn->remote_host));
2986 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2987 idata->sconn->remote_host, idata->sconn->remote_port,
2988 SILC_CONNTYPE_STRING(idata->conn_type)));
2990 /* Save rekey data for next rekey */
2991 idata->rekey = rekey;
2994 /* Start rekey as responder */
2996 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2999 SilcIDListData idata = silc_packet_get_context(sock);
3002 if (!idata->rekey) {
3003 silc_packet_free(packet);
3007 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3008 idata->sconn->remote_host, idata->sconn->remote_port,
3009 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3012 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3013 server->public_key, NULL, sock);
3015 silc_packet_free(packet);
3019 /* Set SKE callbacks */
3020 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3023 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3028 /****************************** Disconnection *******************************/
3030 /* Destroys packet stream. */
3032 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3034 silc_packet_stream_unref(context);
3037 /* Closes connection to socket connection */
3039 void silc_server_close_connection(SilcServer server,
3040 SilcPacketStream sock)
3042 SilcIDListData idata = silc_packet_get_context(sock);
3044 const char *hostname;
3047 if (!silc_packet_stream_is_valid(sock))
3050 memset(tmp, 0, sizeof(tmp));
3051 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3052 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3053 NULL, &hostname, NULL, &port);
3054 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3055 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3056 tmp[0] ? tmp : ""));
3058 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3060 if (idata && idata->sconn) {
3061 silc_server_connection_free(idata->sconn);
3062 idata->sconn = NULL;
3065 /* Take a reference and then destroy the stream. The last reference
3066 is released later in a timeout callback. */
3067 silc_packet_stream_ref(sock);
3068 silc_packet_stream_destroy(sock);
3070 /* Close connection with timeout */
3071 server->stat.conn_num--;
3072 silc_schedule_task_del_by_all(server->schedule, 0,
3073 silc_server_close_connection_final, sock);
3074 silc_schedule_task_add_timeout(server->schedule,
3075 silc_server_close_connection_final,
3079 /* Sends disconnect message to remote connection and disconnects the
3082 void silc_server_disconnect_remote(SilcServer server,
3083 SilcPacketStream sock,
3084 SilcStatus status, ...)
3086 unsigned char buf[512];
3093 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock));
3095 va_start(ap, status);
3096 cp = va_arg(ap, char *);
3098 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3101 /* Send SILC_PACKET_DISCONNECT */
3102 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3103 SILC_STR_UI_CHAR(status),
3104 SILC_STR_UI8_STRING(cp ? buf : NULL),
3107 /* Close connection */
3108 silc_server_close_connection(server, sock);
3111 /* Frees client data and notifies about client's signoff. */
3113 void silc_server_free_client_data(SilcServer server,
3114 SilcPacketStream sock,
3115 SilcClientEntry client,
3117 const char *signoff)
3119 SILC_LOG_DEBUG(("Freeing client %p data", client));
3122 /* Check if anyone is watching this nickname */
3123 if (server->server_type == SILC_ROUTER)
3124 silc_server_check_watcher_list(server, client, NULL,
3125 SILC_NOTIFY_TYPE_SIGNOFF);
3127 /* Send SIGNOFF notify to routers. */
3129 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3130 SILC_BROADCAST(server), client->id,
3134 /* Remove client from all channels */
3136 silc_server_remove_from_channels(server, NULL, client,
3137 TRUE, (char *)signoff, TRUE, FALSE);
3139 silc_server_remove_from_channels(server, NULL, client,
3140 FALSE, NULL, FALSE, FALSE);
3142 /* Remove this client from watcher list if it is */
3143 silc_server_del_from_watcher_list(server, client);
3145 /* Remove client's public key from repository, this will free it too. */
3146 if (client->data.public_key) {
3147 silc_skr_del_public_key(server->repository, client->data.public_key,
3149 client->data.public_key = NULL;
3152 /* Update statistics */
3153 server->stat.my_clients--;
3154 SILC_VERIFY(server->stat.clients > 0);
3155 server->stat.clients--;
3156 if (server->stat.cell_clients)
3157 server->stat.cell_clients--;
3158 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3159 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3160 silc_schedule_task_del_by_context(server->schedule, client);
3162 if (client->data.sconn) {
3163 silc_server_connection_free(client->data.sconn);
3164 client->data.sconn = NULL;
3167 /* We will not delete the client entry right away. We will take it
3168 into history (for WHOWAS command) for 5 minutes, unless we're
3169 shutting down server. */
3170 if (!server->server_shutdown) {
3171 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3173 client->router = NULL;
3174 client->connection = NULL;
3175 client->data.created = silc_time();
3176 silc_dlist_del(server->expired_clients, client);
3177 silc_dlist_add(server->expired_clients, client);
3179 /* Delete directly since we're shutting down server */
3180 SILC_LOG_DEBUG(("Delete client directly"));
3181 silc_idlist_del_data(client);
3182 silc_idlist_del_client(server->local_list, client);
3186 /* Frees user_data pointer from socket connection object. This also sends
3187 appropriate notify packets to the network to inform about leaving
3190 void silc_server_free_sock_user_data(SilcServer server,
3191 SilcPacketStream sock,
3192 const char *signoff_message)
3194 SilcIDListData idata;
3201 SILC_LOG_DEBUG(("Start, sock %p", sock));
3203 idata = silc_packet_get_context(sock);
3207 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3210 /* Cancel active protocols */
3212 if (idata->sconn && idata->sconn->op) {
3213 SILC_LOG_DEBUG(("Abort active protocol"));
3214 silc_async_abort(idata->sconn->op, NULL, NULL);
3216 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3217 ((SilcUnknownEntry)idata)->op) {
3218 SILC_LOG_DEBUG(("Abort active protocol"));
3219 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3223 switch (idata->conn_type) {
3224 case SILC_CONN_CLIENT:
3226 SilcClientEntry client_entry = (SilcClientEntry)idata;
3227 silc_server_free_client_data(server, sock, client_entry, TRUE,
3229 silc_packet_set_context(sock, NULL);
3233 case SILC_CONN_SERVER:
3234 case SILC_CONN_ROUTER:
3236 SilcServerEntry user_data = (SilcServerEntry)idata;
3237 SilcServerEntry backup_router = NULL;
3239 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3242 backup_router = silc_server_backup_get(server, user_data->id);
3244 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3245 backup_router == server->id_entry &&
3246 idata->conn_type != SILC_CONN_ROUTER)
3247 backup_router = NULL;
3249 if (server->server_shutdown || server->backup_noswitch)
3250 backup_router = NULL;
3252 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3253 NULL, NULL, &ip, &port);
3255 /* If this was our primary router connection then we're lost to
3256 the outside world. */
3257 if (server->router == user_data) {
3258 /* Check whether we have a backup router connection */
3259 if (!backup_router || backup_router == user_data) {
3260 if (!server->no_reconnect)
3261 silc_server_create_connections(server);
3262 server->id_entry->router = NULL;
3263 server->router = NULL;
3264 server->standalone = TRUE;
3265 server->backup_primary = FALSE;
3266 backup_router = NULL;
3268 if (server->id_entry != backup_router) {
3269 SILC_LOG_INFO(("New primary router is backup router %s",
3270 backup_router->server_name));
3271 server->id_entry->router = backup_router;
3272 server->router = backup_router;
3273 server->router_connect = time(0);
3274 server->backup_primary = TRUE;
3275 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3277 /* Send START_USE to backup router to indicate we have switched */
3278 silc_server_backup_send_start_use(server,
3279 backup_router->connection,
3282 SILC_LOG_INFO(("We are now new primary router in this cell"));
3283 server->id_entry->router = NULL;
3284 server->router = NULL;
3285 server->standalone = TRUE;
3288 /* We stop here to take a breath */
3291 if (server->backup_router) {
3292 server->server_type = SILC_ROUTER;
3294 /* We'll need to constantly try to reconnect to the primary
3295 router so that we'll see when it comes back online. */
3296 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3297 silc_server_backup_connected,
3301 /* Mark this connection as replaced */
3302 silc_server_backup_replaced_add(server, user_data->id,
3305 } else if (backup_router) {
3306 SILC_LOG_INFO(("Enabling the use of backup router %s",
3307 backup_router->server_name));
3309 /* Mark this connection as replaced */
3310 silc_server_backup_replaced_add(server, user_data->id,
3312 } else if (server->server_type == SILC_SERVER &&
3313 idata->conn_type == SILC_CONN_ROUTER) {
3314 /* Reconnect to the router (backup) */
3315 if (!server->no_reconnect)
3316 silc_server_create_connections(server);
3319 if (user_data->server_name)
3320 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3321 ("Server %s signoff", user_data->server_name));
3323 if (!backup_router) {
3324 /* Remove all servers that are originated from this server, and
3325 remove the clients of those servers too. */
3326 silc_server_remove_servers_by_server(server, user_data, TRUE);
3329 /* Remove the clients that this server owns as they will become
3330 invalid now too. For backup router the server is actually
3331 coming from the primary router, so mark that as the owner
3333 if (server->server_type == SILC_BACKUP_ROUTER &&
3334 sock->type == SILC_CONN_SERVER)
3335 silc_server_remove_clients_by_server(server, server->router,
3339 silc_server_remove_clients_by_server(server, user_data,
3342 /* Remove channels owned by this server */
3343 if (server->server_type == SILC_SERVER)
3344 silc_server_remove_channels_by_server(server, user_data);
3346 /* Enable local server connections that may be disabled */
3347 silc_server_local_servers_toggle_enabled(server, TRUE);
3349 /* Update the client entries of this server to the new backup
3350 router. If we are the backup router we also resolve the real
3351 servers for the clients. After updating is over this also
3352 removes the clients that this server explicitly owns. */
3353 silc_server_update_clients_by_server(server, user_data,
3354 backup_router, TRUE);
3356 /* If we are router and just lost our primary router (now standlaone)
3357 we remove everything that was behind it, since we don't know
3359 if (server->server_type == SILC_ROUTER && server->standalone)
3360 /* Remove all servers that are originated from this server, and
3361 remove the clients of those servers too. */
3362 silc_server_remove_servers_by_server(server, user_data, TRUE);
3364 /* Finally remove the clients that are explicitly owned by this
3365 server. They go down with the server. */
3366 silc_server_remove_clients_by_server(server, user_data,
3369 /* Update our server cache to use the new backup router too. */
3370 silc_server_update_servers_by_server(server, user_data, backup_router);
3371 if (server->server_type == SILC_SERVER)
3372 silc_server_update_channels_by_server(server, user_data,
3375 /* Send notify about primary router going down to local operators */
3376 if (server->backup_router)
3377 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3378 SILC_NOTIFY_TYPE_NONE,
3379 ("%s switched to backup router %s "
3380 "(we are primary router now)",
3381 server->server_name, server->server_name));
3382 else if (server->router)
3383 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3384 SILC_NOTIFY_TYPE_NONE,
3385 ("%s switched to backup router %s",
3386 server->server_name,
3387 server->router->server_name));
3389 server->backup_noswitch = FALSE;
3392 silc_server_connection_free(idata->sconn);
3393 idata->sconn = NULL;
3397 if (idata->conn_type == SILC_CONN_SERVER) {
3398 server->stat.my_servers--;
3399 server->stat.servers--;
3400 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3401 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3402 server->stat.my_routers--;
3403 server->stat.routers--;
3404 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3406 if (server->server_type == SILC_ROUTER)
3407 server->stat.cell_servers--;
3409 /* Free the server entry */
3410 silc_server_backup_del(server, user_data);
3411 silc_server_backup_replaced_del(server, user_data);
3412 silc_idlist_del_data(user_data);
3413 if (!silc_idlist_del_server(server->local_list, user_data))
3414 silc_idlist_del_server(server->global_list, user_data);
3416 if (backup_router && backup_router != server->id_entry) {
3417 /* Announce all of our stuff that was created about 5 minutes ago.
3418 The backup router knows all the other stuff already. */
3419 if (server->server_type == SILC_ROUTER)
3420 silc_server_announce_servers(server, FALSE, time(0) - 300,
3421 backup_router->connection);
3423 /* Announce our clients and channels to the router */
3424 silc_server_announce_clients(server, time(0) - 300,
3425 backup_router->connection);
3426 silc_server_announce_channels(server, time(0) - 300,
3427 backup_router->connection);
3430 silc_packet_set_context(sock, NULL);
3436 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3438 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3441 if (server->router_conn == idata->sconn) {
3442 if (!server->no_reconnect)
3443 silc_server_create_connections(server);
3444 server->router_conn = NULL;
3447 silc_server_connection_free(idata->sconn);
3448 idata->sconn = NULL;
3450 silc_idlist_del_data(idata);
3452 silc_packet_set_context(sock, NULL);
3458 /* Removes client from all channels it has joined. This is used when client
3459 connection is disconnected. If the client on a channel is last, the
3460 channel is removed as well. This sends the SIGNOFF notify types. */
3462 void silc_server_remove_from_channels(SilcServer server,
3463 SilcPacketStream sock,
3464 SilcClientEntry client,
3466 const char *signoff_message,
3470 SilcChannelEntry channel;
3471 SilcChannelClientEntry chl;
3472 SilcHashTableList htl;
3473 SilcBuffer clidp = NULL;
3478 if (notify && !client->id)
3481 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3482 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3485 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3490 /* Remove the client from all channels. The client is removed from
3491 the channels' user list. */
3492 silc_hash_table_list(client->channels, &htl);
3493 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3494 channel = chl->channel;
3496 /* Remove channel if this is last client leaving the channel, unless
3497 the channel is permanent. */
3498 if (server->server_type != SILC_SERVER &&
3499 silc_hash_table_count(channel->user_list) < 2) {
3500 silc_server_channel_delete(server, channel);
3504 silc_hash_table_del(client->channels, channel);
3505 silc_hash_table_del(channel->user_list, client);
3506 channel->user_count--;
3508 /* If there is no global users on the channel anymore mark the channel
3509 as local channel. Do not check if the removed client is local client. */
3510 if (server->server_type == SILC_SERVER && channel->global_users &&
3511 chl->client->router && !silc_server_channel_has_global(channel))
3512 channel->global_users = FALSE;
3514 memset(chl, 'A', sizeof(*chl));
3517 /* Update statistics */
3518 if (SILC_IS_LOCAL(client))
3519 server->stat.my_chanclients--;
3520 if (server->server_type == SILC_ROUTER) {
3521 server->stat.cell_chanclients--;
3522 server->stat.chanclients--;
3525 /* If there is not at least one local user on the channel then we don't
3526 need the channel entry anymore, we can remove it safely, unless the
3527 channel is permanent channel */
3528 if (server->server_type == SILC_SERVER &&
3529 !silc_server_channel_has_local(channel)) {
3530 /* Notify about leaving client if this channel has global users. */
3531 if (notify && channel->global_users)
3532 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3533 SILC_NOTIFY_TYPE_SIGNOFF,
3534 signoff_message ? 2 : 1,
3535 clidp->data, silc_buffer_len(clidp),
3536 signoff_message, signoff_message ?
3537 strlen(signoff_message) : 0);
3539 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3540 silc_server_channel_delete(server, channel);
3544 /* Send notify to channel about client leaving SILC and channel too */
3546 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3547 SILC_NOTIFY_TYPE_SIGNOFF,
3548 signoff_message ? 2 : 1,
3549 clidp->data, silc_buffer_len(clidp),
3550 signoff_message, signoff_message ?
3551 strlen(signoff_message) : 0);
3553 if (killed && clidp) {
3554 /* Remove the client from channel's invite list */
3555 if (channel->invite_list &&
3556 silc_hash_table_count(channel->invite_list)) {
3558 SilcArgumentPayload iargs;
3559 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3560 silc_buffer_len(clidp), 3);
3561 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3562 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3563 silc_buffer_free(ab);
3564 silc_argument_payload_free(iargs);
3568 /* Don't create keys if we are shutting down */
3569 if (server->server_shutdown)
3572 /* Re-generate channel key if needed */
3573 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3574 if (!silc_server_create_channel_key(server, channel, 0))
3577 /* Send the channel key to the channel. The key of course is not sent
3578 to the client who was removed from the channel. */
3579 silc_server_send_channel_key(server, client->connection, channel,
3580 server->server_type == SILC_ROUTER ?
3581 FALSE : !server->standalone);
3585 silc_hash_table_list_reset(&htl);
3587 silc_buffer_free(clidp);
3590 /* Removes client from one channel. This is used for example when client
3591 calls LEAVE command to remove itself from the channel. Returns TRUE
3592 if channel still exists and FALSE if the channel is removed when
3593 last client leaves the channel. If `notify' is FALSE notify messages
3596 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3597 SilcPacketStream sock,
3598 SilcChannelEntry channel,
3599 SilcClientEntry client,
3602 SilcChannelClientEntry chl;
3605 SILC_LOG_DEBUG(("Removing %s from channel %s",
3606 silc_id_render(client->id, SILC_ID_CLIENT),
3607 channel->channel_name));
3609 /* Get the entry to the channel, if this client is not on the channel
3611 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3614 /* Remove channel if this is last client leaving the channel, unless
3615 the channel is permanent. */
3616 if (server->server_type != SILC_SERVER &&
3617 silc_hash_table_count(channel->user_list) < 2) {
3618 silc_server_channel_delete(server, channel);
3622 silc_hash_table_del(client->channels, channel);
3623 silc_hash_table_del(channel->user_list, client);
3624 channel->user_count--;
3626 /* If there is no global users on the channel anymore mark the channel
3627 as local channel. Do not check if the client is local client. */
3628 if (server->server_type == SILC_SERVER && channel->global_users &&
3629 chl->client->router && !silc_server_channel_has_global(channel))
3630 channel->global_users = FALSE;
3632 memset(chl, 'O', sizeof(*chl));
3635 /* Update statistics */
3636 if (SILC_IS_LOCAL(client))
3637 server->stat.my_chanclients--;
3638 if (server->server_type == SILC_ROUTER) {
3639 server->stat.cell_chanclients--;
3640 server->stat.chanclients--;
3643 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3647 /* If there is not at least one local user on the channel then we don't
3648 need the channel entry anymore, we can remove it safely, unless the
3649 channel is permanent channel */
3650 if (server->server_type == SILC_SERVER &&
3651 !silc_server_channel_has_local(channel)) {
3652 /* Notify about leaving client if this channel has global users. */
3653 if (notify && channel->global_users)
3654 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3655 SILC_NOTIFY_TYPE_LEAVE, 1,
3656 clidp->data, silc_buffer_len(clidp));
3658 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3659 silc_server_channel_delete(server, channel);
3660 silc_buffer_free(clidp);
3664 /* Send notify to channel about client leaving the channel */
3666 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3667 SILC_NOTIFY_TYPE_LEAVE, 1,
3668 clidp->data, silc_buffer_len(clidp));
3670 silc_buffer_free(clidp);
3674 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3675 function may be used only by router. In real SILC network all channels
3676 are created by routers thus this function is never used by normal
3679 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3680 SilcServerID *router_id,
3686 SilcChannelID *channel_id;
3687 SilcChannelEntry entry;
3688 SilcCipher send_key, receive_key;
3691 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3694 cipher = SILC_DEFAULT_CIPHER;
3696 hmac = SILC_DEFAULT_HMAC;
3698 /* Allocate cipher */
3699 if (!silc_cipher_alloc(cipher, &send_key))
3701 if (!silc_cipher_alloc(cipher, &receive_key)) {
3702 silc_cipher_free(send_key);
3707 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3708 silc_cipher_free(send_key);
3709 silc_cipher_free(receive_key);
3713 channel_name = strdup(channel_name);
3715 /* Create the channel ID */
3716 if (!silc_id_create_channel_id(server, router_id, server->rng,
3718 silc_free(channel_name);
3719 silc_cipher_free(send_key);
3720 silc_cipher_free(receive_key);
3721 silc_hmac_free(newhmac);
3725 /* Create the channel */
3726 entry = silc_idlist_add_channel(server->local_list, channel_name,
3727 SILC_CHANNEL_MODE_NONE, channel_id,
3728 NULL, send_key, receive_key, newhmac);
3730 silc_free(channel_name);
3731 silc_cipher_free(send_key);
3732 silc_cipher_free(receive_key);
3733 silc_hmac_free(newhmac);
3734 silc_free(channel_id);
3738 entry->cipher = strdup(cipher);
3739 entry->hmac_name = strdup(hmac);
3741 /* Now create the actual key material */
3742 if (!silc_server_create_channel_key(server, entry,
3743 silc_cipher_get_key_len(send_key) / 8)) {
3744 silc_idlist_del_channel(server->local_list, entry);
3748 /* Notify other routers about the new channel. We send the packet
3749 to our primary route. */
3751 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3752 channel_name, entry->id,
3753 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3756 /* Distribute to backup routers */
3757 if (broadcast && server->server_type == SILC_ROUTER) {
3759 unsigned char cid[32];
3760 SilcUInt32 name_len = strlen(channel_name);
3763 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3764 packet = silc_channel_payload_encode(channel_name, name_len,
3765 cid, id_len, entry->mode);
3766 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3767 packet->data, silc_buffer_len(packet), FALSE,
3769 silc_buffer_free(packet);
3772 server->stat.my_channels++;
3773 if (server->server_type == SILC_ROUTER) {
3774 server->stat.channels++;
3775 server->stat.cell_channels++;
3776 entry->users_resolved = TRUE;
3782 /* Same as above but creates the channel with Channel ID `channel_id. */
3785 silc_server_create_new_channel_with_id(SilcServer server,
3789 SilcChannelID *channel_id,
3792 SilcChannelEntry entry;
3793 SilcCipher send_key, receive_key;
3796 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3799 cipher = SILC_DEFAULT_CIPHER;
3801 hmac = SILC_DEFAULT_HMAC;
3803 /* Allocate cipher */
3804 if (!silc_cipher_alloc(cipher, &send_key))
3806 if (!silc_cipher_alloc(cipher, &receive_key)) {
3807 silc_cipher_free(send_key);
3812 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3813 silc_cipher_free(send_key);
3814 silc_cipher_free(receive_key);
3818 channel_name = strdup(channel_name);
3820 /* Create the channel */
3821 entry = silc_idlist_add_channel(server->local_list, channel_name,
3822 SILC_CHANNEL_MODE_NONE, channel_id,
3823 NULL, send_key, receive_key, newhmac);
3825 silc_cipher_free(send_key);
3826 silc_cipher_free(receive_key);
3827 silc_hmac_free(newhmac);
3828 silc_free(channel_name);
3832 /* Now create the actual key material */
3833 if (!silc_server_create_channel_key(server, entry,
3834 silc_cipher_get_key_len(send_key) / 8)) {
3835 silc_idlist_del_channel(server->local_list, entry);
3839 /* Notify other routers about the new channel. We send the packet
3840 to our primary route. */
3842 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3843 channel_name, entry->id,
3844 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3847 /* Distribute to backup routers */
3848 if (broadcast && server->server_type == SILC_ROUTER) {
3850 unsigned char cid[32];
3851 SilcUInt32 name_len = strlen(channel_name);
3854 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3855 packet = silc_channel_payload_encode(channel_name, name_len,
3856 cid, id_len, entry->mode);
3857 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3858 packet->data, silc_buffer_len(packet), FALSE,
3860 silc_buffer_free(packet);
3863 server->stat.my_channels++;
3864 if (server->server_type == SILC_ROUTER) {
3865 server->stat.channels++;
3866 server->stat.cell_channels++;
3867 entry->users_resolved = TRUE;
3873 /* Channel's key re-key timeout callback. */
3875 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3877 SilcServer server = app_context;
3878 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3882 /* Return now if we are shutting down */
3883 if (server->server_shutdown)
3886 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3889 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3892 /* Generates new channel key. This is used to create the initial channel key
3893 but also to re-generate new key for channel. If `key_len' is provided
3894 it is the bytes of the key length. */
3896 SilcBool silc_server_create_channel_key(SilcServer server,
3897 SilcChannelEntry channel,
3901 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3904 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3905 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3909 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3911 if (!channel->send_key)
3912 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3913 channel->send_key = NULL;
3916 if (!channel->receive_key)
3917 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3918 silc_cipher_free(channel->send_key);
3919 channel->send_key = channel->receive_key = NULL;
3925 else if (channel->key_len)
3926 len = channel->key_len / 8;
3928 len = silc_cipher_get_key_len(channel->send_key) / 8;
3930 /* Create channel key */
3931 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3934 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3935 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3937 /* Remove old key if exists */
3939 memset(channel->key, 0, channel->key_len / 8);
3940 silc_free(channel->key);
3944 channel->key_len = len * 8;
3945 channel->key = silc_memdup(channel_key, len);
3946 memset(channel_key, 0, sizeof(channel_key));
3948 /* Generate HMAC key from the channel key data and set it */
3950 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3951 memset(channel->key, 0, channel->key_len / 8);
3952 silc_free(channel->key);
3953 silc_cipher_free(channel->send_key);
3954 silc_cipher_free(channel->receive_key);
3955 channel->send_key = channel->receive_key = NULL;
3958 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3959 silc_hmac_set_key(channel->hmac, hash,
3960 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3961 memset(hash, 0, sizeof(hash));
3963 if (server->server_type == SILC_ROUTER) {
3964 if (!channel->rekey)
3965 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3966 channel->rekey->channel = channel;
3967 channel->rekey->key_len = key_len;
3968 if (channel->rekey->task)
3969 silc_schedule_task_del(server->schedule, channel->rekey->task);
3971 channel->rekey->task =
3972 silc_schedule_task_add_timeout(server->schedule,
3973 silc_server_channel_key_rekey,
3974 (void *)channel->rekey,
3975 server->config->channel_rekey_secs, 0);
3981 /* Saves the channel key found in the encoded `key_payload' buffer. This
3982 function is used when we receive Channel Key Payload and also when we're
3983 processing JOIN command reply. Returns entry to the channel. */
3985 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3986 SilcBuffer key_payload,
3987 SilcChannelEntry channel)
3989 SilcChannelKeyPayload payload = NULL;
3991 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3995 /* Decode channel key payload */
3996 payload = silc_channel_key_payload_parse(key_payload->data,
3997 silc_buffer_len(key_payload));
3999 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4004 /* Get the channel entry */
4007 /* Get channel ID */
4008 tmp = silc_channel_key_get_id(payload, &tmp_len);
4009 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4014 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4016 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4018 if (server->server_type == SILC_ROUTER)
4019 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4020 silc_id_render(&id, SILC_ID_CHANNEL)));
4026 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4028 tmp = silc_channel_key_get_key(payload, &tmp_len);
4034 cipher = silc_channel_key_get_cipher(payload, NULL);
4040 /* Remove old key if exists */
4042 memset(channel->key, 0, channel->key_len / 8);
4043 silc_free(channel->key);
4044 silc_cipher_free(channel->send_key);
4045 silc_cipher_free(channel->receive_key);
4048 /* Create new cipher */
4049 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4050 channel->send_key = NULL;
4054 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4055 silc_cipher_free(channel->send_key);
4056 channel->send_key = channel->receive_key = NULL;
4061 if (channel->cipher)
4062 silc_free(channel->cipher);
4063 channel->cipher = strdup(cipher);
4066 channel->key_len = tmp_len * 8;
4067 channel->key = silc_memdup(tmp, tmp_len);
4068 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4069 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4071 /* Generate HMAC key from the channel key data and set it */
4073 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4074 memset(channel->key, 0, channel->key_len / 8);
4075 silc_free(channel->key);
4076 silc_cipher_free(channel->send_key);
4077 silc_cipher_free(channel->receive_key);
4078 channel->send_key = channel->receive_key = NULL;
4081 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4082 silc_hmac_set_key(channel->hmac, hash,
4083 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4085 memset(hash, 0, sizeof(hash));
4086 memset(tmp, 0, tmp_len);
4088 if (server->server_type == SILC_ROUTER) {
4089 if (!channel->rekey)
4090 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4091 channel->rekey->channel = channel;
4092 if (channel->rekey->task)
4093 silc_schedule_task_del(server->schedule, channel->rekey->task);
4095 channel->rekey->task =
4096 silc_schedule_task_add_timeout(server->schedule,
4097 silc_server_channel_key_rekey,
4098 (void *)channel->rekey,
4099 server->config->channel_rekey_secs, 0);
4104 silc_channel_key_payload_free(payload);
4109 /* Returns assembled of all servers in the given ID list. The packet's
4110 form is dictated by the New ID payload. */
4112 static void silc_server_announce_get_servers(SilcServer server,
4113 SilcServerEntry remote,
4115 SilcBuffer *servers,
4116 unsigned long creation_time)
4119 SilcIDCacheEntry id_cache;
4120 SilcServerEntry entry;
4124 /* Go through all clients in the list */
4125 if (silc_idcache_get_all(id_list->servers, &list)) {
4126 silc_list_start(list);
4127 while ((id_cache = silc_list_get(list))) {
4128 entry = (SilcServerEntry)id_cache->context;
4130 /* Do not announce the one we've sending our announcements and
4131 do not announce ourself. Also check the creation time if it's
4133 if ((entry == remote) || (entry == server->id_entry) ||
4134 (creation_time && entry->data.created < creation_time))
4137 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4139 tmp = silc_buffer_realloc(*servers,
4141 silc_buffer_truelen((*servers)) +
4142 silc_buffer_len(idp) :
4143 silc_buffer_len(idp)));
4147 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4148 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4149 silc_buffer_pull(*servers, silc_buffer_len(idp));
4150 silc_buffer_free(idp);
4156 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4162 p = silc_notify_payload_encode(notify, argc, ap);
4168 /* This function is used by router to announce existing servers to our
4169 primary router when we've connected to it. If `creation_time' is non-zero
4170 then only the servers that has been created after the `creation_time'
4171 will be announced. */
4173 void silc_server_announce_servers(SilcServer server, SilcBool global,
4174 unsigned long creation_time,
4175 SilcPacketStream remote)
4177 SilcBuffer servers = NULL;
4179 SILC_LOG_DEBUG(("Announcing servers"));
4181 /* Get servers in local list */
4182 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4183 server->local_list, &servers,
4187 /* Get servers in global list */
4188 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4189 server->global_list, &servers,
4193 silc_buffer_push(servers, servers->data - servers->head);
4194 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4196 /* Send the packet */
4197 silc_server_packet_send(server, remote,
4198 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4199 servers->data, silc_buffer_len(servers));
4201 silc_buffer_free(servers);
4205 /* Returns assembled packet of all clients in the given ID list. The
4206 packet's form is dictated by the New ID Payload. */
4208 static void silc_server_announce_get_clients(SilcServer server,
4210 SilcBuffer *clients,
4212 unsigned long creation_time)
4215 SilcIDCacheEntry id_cache;
4216 SilcClientEntry client;
4219 unsigned char mode[4];
4222 /* Go through all clients in the list */
4223 if (silc_idcache_get_all(id_list->clients, &list)) {
4224 silc_list_start(list);
4225 while ((id_cache = silc_list_get(list))) {
4226 client = (SilcClientEntry)id_cache->context;
4228 if (creation_time && client->data.created < creation_time)
4230 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4232 if (!client->connection && !client->router)
4235 SILC_LOG_DEBUG(("Announce Client ID %s",
4236 silc_id_render(client->id, SILC_ID_CLIENT)));
4238 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4242 tmp2 = silc_buffer_realloc(*clients,
4244 silc_buffer_truelen((*clients)) +
4245 silc_buffer_len(idp) :
4246 silc_buffer_len(idp)));
4250 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4251 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4252 silc_buffer_pull(*clients, silc_buffer_len(idp));
4254 SILC_PUT32_MSB(client->mode, mode);
4256 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4257 2, idp->data, silc_buffer_len(idp),
4259 tmp2 = silc_buffer_realloc(*umodes,
4261 silc_buffer_truelen((*umodes)) +
4262 silc_buffer_len(tmp) :
4263 silc_buffer_len(tmp)));
4267 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4268 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4269 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4270 silc_buffer_free(tmp);
4272 silc_buffer_free(idp);
4277 /* This function is used to announce our existing clients to our router
4278 when we've connected to it. If `creation_time' is non-zero then only
4279 the clients that has been created after the `creation_time' will be
4282 void silc_server_announce_clients(SilcServer server,
4283 unsigned long creation_time,
4284 SilcPacketStream remote)
4286 SilcBuffer clients = NULL;
4287 SilcBuffer umodes = NULL;
4289 SILC_LOG_DEBUG(("Announcing clients"));
4291 /* Get clients in local list */
4292 silc_server_announce_get_clients(server, server->local_list,
4293 &clients, &umodes, creation_time);
4295 /* As router we announce our global list as well */
4296 if (server->server_type == SILC_ROUTER)
4297 silc_server_announce_get_clients(server, server->global_list,
4298 &clients, &umodes, creation_time);
4301 silc_buffer_push(clients, clients->data - clients->head);
4302 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4304 /* Send the packet */
4305 silc_server_packet_send(server, remote,
4306 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4307 clients->data, silc_buffer_len(clients));
4309 silc_buffer_free(clients);
4313 silc_buffer_push(umodes, umodes->data - umodes->head);
4314 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4316 /* Send the packet */
4317 silc_server_packet_send(server, remote,
4318 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4319 umodes->data, silc_buffer_len(umodes));
4321 silc_buffer_free(umodes);
4325 /* Returns channel's topic for announcing it */
4327 void silc_server_announce_get_channel_topic(SilcServer server,
4328 SilcChannelEntry channel,
4333 if (channel->topic) {
4334 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4335 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4337 silc_buffer_len(chidp),
4339 strlen(channel->topic));
4340 silc_buffer_free(chidp);
4344 /* Returns channel's invite and ban lists */
4346 void silc_server_announce_get_inviteban(SilcServer server,
4347 SilcChannelEntry channel,
4351 SilcBuffer list, idp, idp2, tmp2;
4354 SilcHashTableList htl;
4355 const unsigned char a[1] = { 0x03 };
4357 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4359 /* Encode invite list */
4360 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4361 list = silc_buffer_alloc_size(2);
4362 type = silc_hash_table_count(channel->invite_list);
4363 SILC_PUT16_MSB(type, list->data);
4364 silc_hash_table_list(channel->invite_list, &htl);
4365 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4366 list = silc_argument_payload_encode_one(list, tmp2->data,
4367 silc_buffer_len(tmp2),
4368 SILC_PTR_TO_32(ptype));
4369 silc_hash_table_list_reset(&htl);
4371 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4373 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4374 idp->data, silc_buffer_len(idp),
4375 channel->channel_name,
4376 strlen(channel->channel_name),
4377 idp2->data, silc_buffer_len(idp2),
4379 list->data, silc_buffer_len(list));
4380 silc_buffer_free(idp2);
4381 silc_buffer_free(list);
4384 /* Encode ban list */
4385 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4386 list = silc_buffer_alloc_size(2);
4387 type = silc_hash_table_count(channel->ban_list);
4388 SILC_PUT16_MSB(type, list->data);
4389 silc_hash_table_list(channel->ban_list, &htl);
4390 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4391 list = silc_argument_payload_encode_one(list, tmp2->data,
4392 silc_buffer_len(tmp2),
4393 SILC_PTR_TO_32(ptype));
4394 silc_hash_table_list_reset(&htl);
4397 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4398 idp->data, silc_buffer_len(idp),
4400 list->data, silc_buffer_len(list));
4401 silc_buffer_free(list);
4404 silc_buffer_free(idp);
4407 /* Returns assembled packets for channel users of the `channel'. */
4409 void silc_server_announce_get_channel_users(SilcServer server,
4410 SilcChannelEntry channel,
4411 SilcBuffer *channel_modes,
4412 SilcBuffer *channel_users,
4413 SilcBuffer *channel_users_modes)
4415 SilcChannelClientEntry chl;
4416 SilcHashTableList htl;
4417 SilcBuffer chidp, clidp, csidp;
4418 SilcBuffer tmp, fkey = NULL, chpklist;
4420 unsigned char mode[4], ulimit[4];
4424 SILC_LOG_DEBUG(("Start"));
4426 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4427 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4428 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4431 SILC_PUT32_MSB(channel->mode, mode);
4432 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4433 SILC_PUT32_MSB(channel->user_limit, ulimit);
4434 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4435 if (channel->founder_key)
4436 fkey = silc_public_key_payload_encode(channel->founder_key);
4438 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4440 silc_buffer_len(csidp),
4443 hmac, hmac ? strlen(hmac) : 0,
4444 channel->passphrase,
4445 channel->passphrase ?
4446 strlen(channel->passphrase) : 0,
4447 fkey ? fkey->data : NULL,
4448 fkey ? silc_buffer_len(fkey) : 0,
4449 chpklist ? chpklist->data : NULL,
4451 silc_buffer_len(chpklist) : 0,
4453 SILC_CHANNEL_MODE_ULIMIT ?
4456 SILC_CHANNEL_MODE_ULIMIT ?
4457 sizeof(ulimit) : 0));
4458 len = silc_buffer_len(tmp);
4460 silc_buffer_realloc(*channel_modes,
4462 silc_buffer_truelen((*channel_modes)) + len : len));
4465 *channel_modes = tmp2;
4466 silc_buffer_pull_tail(*channel_modes,
4467 ((*channel_modes)->end -
4468 (*channel_modes)->data));
4469 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4470 silc_buffer_pull(*channel_modes, len);
4471 silc_buffer_free(tmp);
4472 silc_buffer_free(fkey);
4475 /* Now find all users on the channel */
4476 silc_hash_table_list(channel->user_list, &htl);
4477 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4478 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4480 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4484 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4486 silc_buffer_len(clidp),
4488 silc_buffer_len(chidp));
4489 len = silc_buffer_len(tmp);
4491 silc_buffer_realloc(*channel_users,
4493 silc_buffer_truelen((*channel_users)) + len : len));
4496 *channel_users = tmp2;
4497 silc_buffer_pull_tail(*channel_users,
4498 ((*channel_users)->end -
4499 (*channel_users)->data));
4501 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4502 silc_buffer_pull(*channel_users, len);
4503 silc_buffer_free(tmp);
4505 /* CUMODE notify for mode change on the channel */
4506 SILC_PUT32_MSB(chl->mode, mode);
4507 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4508 fkey = silc_public_key_payload_encode(channel->founder_key);
4509 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4511 silc_buffer_len(csidp),
4514 silc_buffer_len(clidp),
4515 fkey ? fkey->data : NULL,
4516 fkey ? silc_buffer_len(fkey) : 0);
4517 len = silc_buffer_len(tmp);
4519 silc_buffer_realloc(*channel_users_modes,
4520 (*channel_users_modes ?
4521 silc_buffer_truelen((*channel_users_modes)) +
4525 *channel_users_modes = tmp2;
4526 silc_buffer_pull_tail(*channel_users_modes,
4527 ((*channel_users_modes)->end -
4528 (*channel_users_modes)->data));
4530 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4531 silc_buffer_pull(*channel_users_modes, len);
4532 silc_buffer_free(tmp);
4533 silc_buffer_free(fkey);
4535 silc_buffer_free(clidp);
4537 silc_hash_table_list_reset(&htl);
4538 silc_buffer_free(chidp);
4539 silc_buffer_free(csidp);
4542 /* Returns assembled packets for all channels and users on those channels
4543 from the given ID List. The packets are in the form dictated by the
4544 New Channel and New Channel User payloads. */
4546 void silc_server_announce_get_channels(SilcServer server,
4548 SilcBuffer *channels,
4549 SilcBuffer **channel_modes,
4550 SilcBuffer *channel_users,
4551 SilcBuffer **channel_users_modes,
4552 SilcUInt32 *channel_users_modes_c,
4553 SilcBuffer **channel_topics,
4554 SilcBuffer **channel_invites,
4555 SilcBuffer **channel_bans,
4556 SilcChannelID ***channel_ids,
4557 unsigned long creation_time)
4560 SilcIDCacheEntry id_cache;
4561 SilcChannelEntry channel;
4562 unsigned char cid[32];
4564 SilcUInt16 name_len;
4566 int i = *channel_users_modes_c;
4570 SILC_LOG_DEBUG(("Start"));
4572 /* Go through all channels in the list */
4573 if (silc_idcache_get_all(id_list->channels, &list)) {
4574 silc_list_start(list);
4575 while ((id_cache = silc_list_get(list))) {
4576 channel = (SilcChannelEntry)id_cache->context;
4578 if (creation_time && channel->created < creation_time)
4583 SILC_LOG_DEBUG(("Announce Channel ID %s",
4584 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4586 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4587 name_len = strlen(channel->channel_name);
4590 len = 4 + name_len + id_len + 4;
4592 silc_buffer_realloc(*channels,
4594 silc_buffer_truelen((*channels)) +
4600 silc_buffer_pull_tail(*channels,
4601 ((*channels)->end - (*channels)->data));
4602 silc_buffer_format(*channels,
4603 SILC_STR_UI_SHORT(name_len),
4604 SILC_STR_UI_XNSTRING(channel->channel_name,
4606 SILC_STR_UI_SHORT(id_len),
4607 SILC_STR_UI_XNSTRING(cid, id_len),
4608 SILC_STR_UI_INT(channel->mode),
4610 silc_buffer_pull(*channels, len);
4613 if (creation_time && channel->updated < creation_time)
4619 /* Channel user modes */
4620 tmp = silc_realloc(*channel_users_modes,
4621 sizeof(**channel_users_modes) * (i + 1));
4624 *channel_users_modes = tmp;
4625 (*channel_users_modes)[i] = NULL;
4626 tmp = silc_realloc(*channel_modes,
4627 sizeof(**channel_modes) * (i + 1));
4630 *channel_modes = tmp;
4631 (*channel_modes)[i] = NULL;
4632 tmp = silc_realloc(*channel_ids,
4633 sizeof(**channel_ids) * (i + 1));
4637 (*channel_ids)[i] = NULL;
4638 silc_server_announce_get_channel_users(server, channel,
4639 &(*channel_modes)[i],
4641 &(*channel_users_modes)[i]);
4642 (*channel_ids)[i] = channel->id;
4644 /* Channel's topic */
4645 tmp = silc_realloc(*channel_topics,
4646 sizeof(**channel_topics) * (i + 1));
4649 *channel_topics = tmp;
4650 (*channel_topics)[i] = NULL;
4651 silc_server_announce_get_channel_topic(server, channel,
4652 &(*channel_topics)[i]);
4654 /* Channel's invite and ban list */
4655 tmp = silc_realloc(*channel_invites,
4656 sizeof(**channel_invites) * (i + 1));
4659 *channel_invites = tmp;
4660 (*channel_invites)[i] = NULL;
4661 tmp = silc_realloc(*channel_bans,
4662 sizeof(**channel_bans) * (i + 1));
4665 *channel_bans = tmp;
4666 (*channel_bans)[i] = NULL;
4667 silc_server_announce_get_inviteban(server, channel,
4668 &(*channel_invites)[i],
4669 &(*channel_bans)[i]);
4671 (*channel_users_modes_c)++;
4679 /* This function is used to announce our existing channels to our router
4680 when we've connected to it. This also announces the users on the
4681 channels to the router. If the `creation_time' is non-zero only the
4682 channels that was created after the `creation_time' are announced.
4683 Note that the channel users are still announced even if the `creation_time'
4686 void silc_server_announce_channels(SilcServer server,
4687 unsigned long creation_time,
4688 SilcPacketStream remote)
4690 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4691 SilcBuffer *channel_users_modes = NULL;
4692 SilcBuffer *channel_topics = NULL;
4693 SilcBuffer *channel_invites = NULL;
4694 SilcBuffer *channel_bans = NULL;
4695 SilcUInt32 channel_users_modes_c = 0;
4696 SilcChannelID **channel_ids = NULL;
4698 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4700 /* Get channels and channel users in local list */
4701 silc_server_announce_get_channels(server, server->local_list,
4702 &channels, &channel_modes,
4704 &channel_users_modes,
4705 &channel_users_modes_c,
4709 &channel_ids, creation_time);
4711 /* Get channels and channel users in global list */
4712 if (server->server_type != SILC_SERVER)
4713 silc_server_announce_get_channels(server, server->global_list,
4714 &channels, &channel_modes,
4716 &channel_users_modes,
4717 &channel_users_modes_c,
4721 &channel_ids, creation_time);
4724 silc_buffer_push(channels, channels->data - channels->head);
4725 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4727 /* Send the packet */
4728 silc_server_packet_send(server, remote,
4729 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4730 channels->data, silc_buffer_len(channels));
4732 silc_buffer_free(channels);
4735 if (channel_users) {
4736 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4737 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4738 silc_buffer_len(channel_users));
4740 /* Send the packet */
4741 silc_server_packet_send(server, remote,
4742 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4743 channel_users->data, silc_buffer_len(channel_users));
4745 silc_buffer_free(channel_users);
4748 if (channel_modes) {
4751 for (i = 0; i < channel_users_modes_c; i++) {
4752 if (!channel_modes[i])
4754 silc_buffer_push(channel_modes[i],
4755 channel_modes[i]->data -
4756 channel_modes[i]->head);
4757 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4758 silc_buffer_len(channel_modes[i]));
4759 silc_server_packet_send_dest(server, remote,
4760 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4761 channel_ids[i], SILC_ID_CHANNEL,
4762 channel_modes[i]->data,
4763 silc_buffer_len(channel_modes[i]));
4764 silc_buffer_free(channel_modes[i]);
4766 silc_free(channel_modes);
4769 if (channel_users_modes) {
4772 for (i = 0; i < channel_users_modes_c; i++) {
4773 if (!channel_users_modes[i])
4775 silc_buffer_push(channel_users_modes[i],
4776 channel_users_modes[i]->data -
4777 channel_users_modes[i]->head);
4778 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4779 silc_buffer_len(channel_users_modes[i]));
4780 silc_server_packet_send_dest(server, remote,
4781 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4782 channel_ids[i], SILC_ID_CHANNEL,
4783 channel_users_modes[i]->data,
4784 silc_buffer_len(channel_users_modes[i]));
4785 silc_buffer_free(channel_users_modes[i]);
4787 silc_free(channel_users_modes);
4790 if (channel_topics) {
4793 for (i = 0; i < channel_users_modes_c; i++) {
4794 if (!channel_topics[i])
4797 silc_buffer_push(channel_topics[i],
4798 channel_topics[i]->data -
4799 channel_topics[i]->head);
4800 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4801 silc_buffer_len(channel_topics[i]));
4802 silc_server_packet_send_dest(server, remote,
4803 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4804 channel_ids[i], SILC_ID_CHANNEL,
4805 channel_topics[i]->data,
4806 silc_buffer_len(channel_topics[i]));
4807 silc_buffer_free(channel_topics[i]);
4809 silc_free(channel_topics);
4812 if (channel_invites) {
4815 for (i = 0; i < channel_users_modes_c; i++) {
4816 if (!channel_invites[i])
4819 silc_buffer_push(channel_invites[i],
4820 channel_invites[i]->data -
4821 channel_invites[i]->head);
4822 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4823 silc_buffer_len(channel_invites[i]));
4824 silc_server_packet_send_dest(server, remote,
4825 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4826 channel_ids[i], SILC_ID_CHANNEL,
4827 channel_invites[i]->data,
4828 silc_buffer_len(channel_invites[i]));
4829 silc_buffer_free(channel_invites[i]);
4831 silc_free(channel_invites);
4837 for (i = 0; i < channel_users_modes_c; i++) {
4838 if (!channel_bans[i])
4841 silc_buffer_push(channel_bans[i],
4842 channel_bans[i]->data -
4843 channel_bans[i]->head);
4844 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4845 silc_buffer_len(channel_bans[i]));
4846 silc_server_packet_send_dest(server, remote,
4847 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4848 channel_ids[i], SILC_ID_CHANNEL,
4849 channel_bans[i]->data,
4850 silc_buffer_len(channel_bans[i]));
4851 silc_buffer_free(channel_bans[i]);
4853 silc_free(channel_bans);
4856 silc_free(channel_ids);
4859 /* Announces WATCH list. */
4861 void silc_server_announce_watches(SilcServer server,
4862 SilcPacketStream remote)
4864 SilcHashTableList htl;
4865 SilcBuffer buffer, idp, args, pkp;
4866 SilcClientEntry client;
4869 SILC_LOG_DEBUG(("Announcing watch list"));
4871 /* XXX because way we save the nicks (hash) we cannot announce them. */
4873 /* XXX we should send all public keys in one command if client is
4874 watching more than one key */
4875 silc_hash_table_list(server->watcher_list_pk, &htl);
4876 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4877 if (!client || !client->id)
4880 server->stat.commands_sent++;
4882 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4883 args = silc_buffer_alloc_size(2);
4884 silc_buffer_format(args,
4885 SILC_STR_UI_SHORT(1),
4887 pkp = silc_public_key_payload_encode(key);
4888 args = silc_argument_payload_encode_one(args, pkp->data,
4889 silc_buffer_len(pkp), 0x00);
4890 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4891 ++server->cmd_ident, 2,
4892 1, idp->data, silc_buffer_len(idp),
4894 silc_buffer_len(args));
4897 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4898 buffer->data, silc_buffer_len(buffer));
4900 silc_buffer_free(pkp);
4901 silc_buffer_free(args);
4902 silc_buffer_free(idp);
4903 silc_buffer_free(buffer);
4905 silc_hash_table_list_reset(&htl);
4908 /* Assembles user list and users mode list from the `channel'. */
4910 SilcBool silc_server_get_users_on_channel(SilcServer server,
4911 SilcChannelEntry channel,
4912 SilcBuffer *user_list,
4913 SilcBuffer *mode_list,
4914 SilcUInt32 *user_count)
4916 SilcChannelClientEntry chl;
4917 SilcHashTableList htl;
4918 SilcBuffer client_id_list;
4919 SilcBuffer client_mode_list;
4921 SilcUInt32 list_count = 0, len = 0;
4923 if (!silc_hash_table_count(channel->user_list))
4926 silc_hash_table_list(channel->user_list, &htl);
4927 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4928 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4929 silc_hash_table_list_reset(&htl);
4931 client_id_list = silc_buffer_alloc(len);
4933 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4934 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4935 silc_buffer_pull_tail(client_mode_list,
4936 silc_buffer_truelen(client_mode_list));
4938 silc_hash_table_list(channel->user_list, &htl);
4939 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4941 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4942 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4943 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4944 silc_buffer_free(idp);
4946 /* Client's mode on channel */
4947 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4948 silc_buffer_pull(client_mode_list, 4);
4952 silc_hash_table_list_reset(&htl);
4953 silc_buffer_push(client_id_list,
4954 client_id_list->data - client_id_list->head);
4955 silc_buffer_push(client_mode_list,
4956 client_mode_list->data - client_mode_list->head);
4958 *user_list = client_id_list;
4959 *mode_list = client_mode_list;
4960 *user_count = list_count;
4964 /* Saves users and their modes to the `channel'. */
4966 void silc_server_save_users_on_channel(SilcServer server,
4967 SilcPacketStream sock,
4968 SilcChannelEntry channel,
4969 SilcClientID *noadd,
4970 SilcBuffer user_list,
4971 SilcBuffer mode_list,
4972 SilcUInt32 user_count)
4978 SilcClientEntry client;
4979 SilcIDCacheEntry cache;
4980 SilcChannelClientEntry chl;
4982 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4983 channel->channel_name));
4985 for (i = 0; i < user_count; i++) {
4987 SILC_GET16_MSB(idp_len, user_list->data + 2);
4989 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4991 silc_buffer_pull(user_list, idp_len);
4994 SILC_GET32_MSB(mode, mode_list->data);
4995 silc_buffer_pull(mode_list, 4);
4997 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5002 /* Check if we have this client cached already. */
5003 client = silc_idlist_find_client_by_id(server->local_list,
5005 server->server_type, &cache);
5007 client = silc_idlist_find_client_by_id(server->global_list,
5009 server->server_type, &cache);
5011 /* If router did not find such Client ID in its lists then this must
5012 be bogus client or some router in the net is buggy. */
5013 if (server->server_type != SILC_SERVER)
5016 /* We don't have that client anywhere, add it. The client is added
5017 to global list since server didn't have it in the lists so it must be
5019 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5020 silc_id_dup(&id.u.client_id,
5022 silc_packet_get_context(sock),
5025 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5029 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5032 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5033 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5034 "%s", channel->channel_name));
5038 if (!silc_server_client_on_channel(client, channel, &chl)) {
5039 /* Client was not on the channel, add it. */
5040 chl = silc_calloc(1, sizeof(*chl));
5041 chl->client = client;
5043 chl->channel = channel;
5044 silc_hash_table_add(channel->user_list, chl->client, chl);
5045 silc_hash_table_add(client->channels, chl->channel, chl);
5046 channel->user_count++;
5054 /* Saves channels and channels user modes to the `client'. Removes
5055 the client from those channels that are not sent in the list but
5058 void silc_server_save_user_channels(SilcServer server,
5059 SilcPacketStream sock,
5060 SilcClientEntry client,
5061 SilcBuffer channels,
5062 SilcBuffer channels_user_modes)
5065 SilcUInt32 *chumodes;
5066 SilcChannelPayload entry;
5067 SilcChannelEntry channel;
5068 SilcChannelID channel_id;
5069 SilcChannelClientEntry chl;
5070 SilcHashTable ht = NULL;
5071 SilcHashTableList htl;
5075 if (!channels || !channels_user_modes ||
5076 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5079 ch = silc_channel_payload_parse_list(channels->data,
5080 silc_buffer_len(channels));
5081 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5083 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5084 NULL, NULL, NULL, TRUE);
5085 silc_dlist_start(ch);
5086 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5087 /* Check if we have this channel, and add it if we don't have it.
5088 Also add the client on the channel unless it is there already. */
5089 if (!silc_channel_get_id_parse(entry, &channel_id))
5091 channel = silc_idlist_find_channel_by_id(server->local_list,
5094 channel = silc_idlist_find_channel_by_id(server->global_list,
5097 if (server->server_type != SILC_SERVER) {
5102 /* We don't have that channel anywhere, add it. */
5103 name = silc_channel_get_name(entry, NULL);
5104 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5105 silc_id_dup(&channel_id,
5107 server->router, NULL, NULL, 0);
5114 channel->mode = silc_channel_get_mode(entry);
5116 /* Add the client on the channel */
5117 if (!silc_server_client_on_channel(client, channel, &chl)) {
5118 chl = silc_calloc(1, sizeof(*chl));
5119 chl->client = client;
5120 chl->mode = chumodes[i++];
5121 chl->channel = channel;
5122 silc_hash_table_add(channel->user_list, chl->client, chl);
5123 silc_hash_table_add(client->channels, chl->channel, chl);
5124 channel->user_count++;
5127 chl->mode = chumodes[i++];
5130 silc_hash_table_add(ht, channel, channel);
5132 silc_channel_payload_list_free(ch);
5133 silc_free(chumodes);
5137 /* Go through the list again and remove client from channels that
5138 are no part of the list. */
5140 silc_hash_table_list(client->channels, &htl);
5141 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5142 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5143 silc_hash_table_del(chl->channel->user_list, chl->client);
5144 silc_hash_table_del(chl->client->channels, chl->channel);
5148 silc_hash_table_list_reset(&htl);
5149 silc_hash_table_free(ht);
5151 silc_hash_table_list(client->channels, &htl);
5152 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5153 silc_hash_table_del(chl->channel->user_list, chl->client);
5154 silc_hash_table_del(chl->client->channels, chl->channel);
5157 silc_hash_table_list_reset(&htl);
5161 /* Lookups route to the client indicated by the `id_data'. The connection
5162 object and internal data object is returned. Returns NULL if route
5163 could not be found to the client. If the `client_id' is specified then
5164 it is used and the `id_data' is ignored. */
5167 silc_server_get_client_route(SilcServer server,
5168 unsigned char *id_data,
5170 SilcClientID *client_id,
5171 SilcIDListData *idata,
5172 SilcClientEntry *client_entry)
5174 SilcClientID *id, clid;
5175 SilcClientEntry client;
5177 SILC_LOG_DEBUG(("Start"));
5180 *client_entry = NULL;
5182 /* Decode destination Client ID */
5184 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5186 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5188 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5191 /* If the destination belongs to our server we don't have to route
5192 the packet anywhere but to send it to the local destination. */
5193 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5197 /* If we are router and the client has router then the client is in
5198 our cell but not directly connected to us. */
5199 if (server->server_type == SILC_ROUTER && client->router) {
5200 /* We are of course in this case the client's router thus the route
5201 to the client is the server who owns the client. So, we will send
5202 the packet to that server. */
5204 *idata = (SilcIDListData)client->router;
5205 return client->router->connection;
5208 /* Seems that client really is directly connected to us */
5210 *idata = (SilcIDListData)client;
5212 *client_entry = client;
5213 return client->connection;
5216 /* Destination belongs to someone not in this server. If we are normal
5217 server our action is to send the packet to our router. */
5218 if (server->server_type != SILC_ROUTER && !server->standalone) {
5221 *idata = (SilcIDListData)server->router;
5222 return SILC_PRIMARY_ROUTE(server);
5225 /* We are router and we will perform route lookup for the destination
5226 and send the packet to fastest route. */
5227 if (server->server_type == SILC_ROUTER && !server->standalone) {
5228 /* Check first that the ID is valid */
5229 client = silc_idlist_find_client_by_id(server->global_list, id,
5232 SilcPacketStream dst_sock;
5234 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5237 if (idata && dst_sock)
5238 *idata = silc_packet_get_context(dst_sock);
5247 /* Encodes and returns channel list of channels the `client' has joined.
5248 Secret channels are not put to the list. */
5250 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5251 SilcClientEntry client,
5252 SilcBool get_private,
5253 SilcBool get_secret,
5254 SilcBuffer *user_mode_list)
5256 SilcBuffer buffer = NULL;
5257 SilcChannelEntry channel;
5258 SilcChannelClientEntry chl;
5259 SilcHashTableList htl;
5260 unsigned char cid[32];
5262 SilcUInt16 name_len;
5266 *user_mode_list = NULL;
5268 silc_hash_table_list(client->channels, &htl);
5269 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5270 channel = chl->channel;
5272 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5274 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5277 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5278 name_len = strlen(channel->channel_name);
5280 len = 4 + name_len + id_len + 4;
5281 buffer = silc_buffer_realloc(buffer,
5283 silc_buffer_truelen(buffer) + len : len));
5284 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5285 silc_buffer_format(buffer,
5286 SILC_STR_UI_SHORT(name_len),
5287 SILC_STR_DATA(channel->channel_name, name_len),
5288 SILC_STR_UI_SHORT(id_len),
5289 SILC_STR_DATA(cid, id_len),
5290 SILC_STR_UI_INT(chl->channel->mode),
5292 silc_buffer_pull(buffer, len);
5294 if (user_mode_list) {
5296 silc_buffer_realloc(*user_mode_list,
5298 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5299 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5300 (*user_mode_list)->data));
5301 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5302 silc_buffer_pull(*user_mode_list, 4);
5305 silc_hash_table_list_reset(&htl);
5308 silc_buffer_push(buffer, buffer->data - buffer->head);
5309 if (user_mode_list && *user_mode_list)
5310 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5311 (*user_mode_list)->head));
5316 /* Task callback used to retrieve network statistical information from
5317 router server once in a while. */
5319 SILC_TASK_CALLBACK(silc_server_get_stats)
5321 SilcServer server = (SilcServer)context;
5322 SilcBuffer idp, packet;
5324 if (!server->standalone) {
5325 SILC_LOG_DEBUG(("Retrieving stats from router"));
5326 server->stat.commands_sent++;
5327 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5329 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5330 ++server->cmd_ident, 1,
5332 silc_buffer_len(idp));
5333 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5334 SILC_PACKET_COMMAND, 0, packet->data,
5335 silc_buffer_len(packet));
5336 silc_buffer_free(packet);
5337 silc_buffer_free(idp);
5341 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,