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 */
3154 /* Local detached clients aren't counted. */
3155 if (!client->local_detached)
3156 server->stat.my_clients--;
3157 SILC_VERIFY(server->stat.clients > 0);
3158 server->stat.clients--;
3159 if (server->stat.cell_clients)
3160 server->stat.cell_clients--;
3161 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3162 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3163 silc_schedule_task_del_by_context(server->schedule, client);
3165 if (client->data.sconn) {
3166 silc_server_connection_free(client->data.sconn);
3167 client->data.sconn = NULL;
3170 /* We will not delete the client entry right away. We will take it
3171 into history (for WHOWAS command) for 5 minutes, unless we're
3172 shutting down server. */
3173 if (!server->server_shutdown) {
3174 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3176 client->router = NULL;
3177 client->connection = NULL;
3178 client->data.created = silc_time();
3179 silc_dlist_del(server->expired_clients, client);
3180 silc_dlist_add(server->expired_clients, client);
3182 /* Delete directly since we're shutting down server */
3183 SILC_LOG_DEBUG(("Delete client directly"));
3184 silc_idlist_del_data(client);
3185 silc_idlist_del_client(server->local_list, client);
3189 /* Frees user_data pointer from socket connection object. This also sends
3190 appropriate notify packets to the network to inform about leaving
3193 void silc_server_free_sock_user_data(SilcServer server,
3194 SilcPacketStream sock,
3195 const char *signoff_message)
3197 SilcIDListData idata;
3204 SILC_LOG_DEBUG(("Start, sock %p", sock));
3206 idata = silc_packet_get_context(sock);
3210 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3213 /* Cancel active protocols */
3215 if (idata->sconn && idata->sconn->op) {
3216 SILC_LOG_DEBUG(("Abort active protocol"));
3217 silc_async_abort(idata->sconn->op, NULL, NULL);
3219 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3220 ((SilcUnknownEntry)idata)->op) {
3221 SILC_LOG_DEBUG(("Abort active protocol"));
3222 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3226 switch (idata->conn_type) {
3227 case SILC_CONN_CLIENT:
3229 SilcClientEntry client_entry = (SilcClientEntry)idata;
3230 silc_server_free_client_data(server, sock, client_entry, TRUE,
3232 silc_packet_set_context(sock, NULL);
3236 case SILC_CONN_SERVER:
3237 case SILC_CONN_ROUTER:
3239 SilcServerEntry user_data = (SilcServerEntry)idata;
3240 SilcServerEntry backup_router = NULL;
3242 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3245 backup_router = silc_server_backup_get(server, user_data->id);
3247 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3248 backup_router == server->id_entry &&
3249 idata->conn_type != SILC_CONN_ROUTER)
3250 backup_router = NULL;
3252 if (server->server_shutdown || server->backup_noswitch)
3253 backup_router = NULL;
3255 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3256 NULL, NULL, &ip, &port);
3258 /* If this was our primary router connection then we're lost to
3259 the outside world. */
3260 if (server->router == user_data) {
3261 /* Check whether we have a backup router connection */
3262 if (!backup_router || backup_router == user_data) {
3263 if (!server->no_reconnect)
3264 silc_server_create_connections(server);
3265 server->id_entry->router = NULL;
3266 server->router = NULL;
3267 server->standalone = TRUE;
3268 server->backup_primary = FALSE;
3269 backup_router = NULL;
3271 if (server->id_entry != backup_router) {
3272 SILC_LOG_INFO(("New primary router is backup router %s",
3273 backup_router->server_name));
3274 server->id_entry->router = backup_router;
3275 server->router = backup_router;
3276 server->router_connect = time(0);
3277 server->backup_primary = TRUE;
3278 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3280 /* Send START_USE to backup router to indicate we have switched */
3281 silc_server_backup_send_start_use(server,
3282 backup_router->connection,
3285 SILC_LOG_INFO(("We are now new primary router in this cell"));
3286 server->id_entry->router = NULL;
3287 server->router = NULL;
3288 server->standalone = TRUE;
3291 /* We stop here to take a breath */
3294 if (server->backup_router) {
3295 server->server_type = SILC_ROUTER;
3297 /* We'll need to constantly try to reconnect to the primary
3298 router so that we'll see when it comes back online. */
3299 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3300 silc_server_backup_connected,
3304 /* Mark this connection as replaced */
3305 silc_server_backup_replaced_add(server, user_data->id,
3308 } else if (backup_router) {
3309 SILC_LOG_INFO(("Enabling the use of backup router %s",
3310 backup_router->server_name));
3312 /* Mark this connection as replaced */
3313 silc_server_backup_replaced_add(server, user_data->id,
3315 } else if (server->server_type == SILC_SERVER &&
3316 idata->conn_type == SILC_CONN_ROUTER) {
3317 /* Reconnect to the router (backup) */
3318 if (!server->no_reconnect)
3319 silc_server_create_connections(server);
3322 if (user_data->server_name)
3323 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3324 ("Server %s signoff", user_data->server_name));
3326 if (!backup_router) {
3327 /* Remove all servers that are originated from this server, and
3328 remove the clients of those servers too. */
3329 silc_server_remove_servers_by_server(server, user_data, TRUE);
3332 /* Remove the clients that this server owns as they will become
3333 invalid now too. For backup router the server is actually
3334 coming from the primary router, so mark that as the owner
3336 if (server->server_type == SILC_BACKUP_ROUTER &&
3337 sock->type == SILC_CONN_SERVER)
3338 silc_server_remove_clients_by_server(server, server->router,
3342 silc_server_remove_clients_by_server(server, user_data,
3345 /* Remove channels owned by this server */
3346 if (server->server_type == SILC_SERVER)
3347 silc_server_remove_channels_by_server(server, user_data);
3349 /* Enable local server connections that may be disabled */
3350 silc_server_local_servers_toggle_enabled(server, TRUE);
3352 /* Update the client entries of this server to the new backup
3353 router. If we are the backup router we also resolve the real
3354 servers for the clients. After updating is over this also
3355 removes the clients that this server explicitly owns. */
3356 silc_server_update_clients_by_server(server, user_data,
3357 backup_router, TRUE);
3359 /* If we are router and just lost our primary router (now standlaone)
3360 we remove everything that was behind it, since we don't know
3362 if (server->server_type == SILC_ROUTER && server->standalone)
3363 /* Remove all servers that are originated from this server, and
3364 remove the clients of those servers too. */
3365 silc_server_remove_servers_by_server(server, user_data, TRUE);
3367 /* Finally remove the clients that are explicitly owned by this
3368 server. They go down with the server. */
3369 silc_server_remove_clients_by_server(server, user_data,
3372 /* Update our server cache to use the new backup router too. */
3373 silc_server_update_servers_by_server(server, user_data, backup_router);
3374 if (server->server_type == SILC_SERVER)
3375 silc_server_update_channels_by_server(server, user_data,
3378 /* Send notify about primary router going down to local operators */
3379 if (server->backup_router)
3380 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3381 SILC_NOTIFY_TYPE_NONE,
3382 ("%s switched to backup router %s "
3383 "(we are primary router now)",
3384 server->server_name, server->server_name));
3385 else if (server->router)
3386 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3387 SILC_NOTIFY_TYPE_NONE,
3388 ("%s switched to backup router %s",
3389 server->server_name,
3390 server->router->server_name));
3392 server->backup_noswitch = FALSE;
3395 silc_server_connection_free(idata->sconn);
3396 idata->sconn = NULL;
3400 if (idata->conn_type == SILC_CONN_SERVER) {
3401 server->stat.my_servers--;
3402 server->stat.servers--;
3403 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3404 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3405 server->stat.my_routers--;
3406 server->stat.routers--;
3407 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3409 if (server->server_type == SILC_ROUTER)
3410 server->stat.cell_servers--;
3412 /* Free the server entry */
3413 silc_server_backup_del(server, user_data);
3414 silc_server_backup_replaced_del(server, user_data);
3415 silc_idlist_del_data(user_data);
3416 if (!silc_idlist_del_server(server->local_list, user_data))
3417 silc_idlist_del_server(server->global_list, user_data);
3419 if (backup_router && backup_router != server->id_entry) {
3420 /* Announce all of our stuff that was created about 5 minutes ago.
3421 The backup router knows all the other stuff already. */
3422 if (server->server_type == SILC_ROUTER)
3423 silc_server_announce_servers(server, FALSE, time(0) - 300,
3424 backup_router->connection);
3426 /* Announce our clients and channels to the router */
3427 silc_server_announce_clients(server, time(0) - 300,
3428 backup_router->connection);
3429 silc_server_announce_channels(server, time(0) - 300,
3430 backup_router->connection);
3433 silc_packet_set_context(sock, NULL);
3439 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3441 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3444 if (server->router_conn == idata->sconn) {
3445 if (!server->no_reconnect)
3446 silc_server_create_connections(server);
3447 server->router_conn = NULL;
3450 silc_server_connection_free(idata->sconn);
3451 idata->sconn = NULL;
3453 silc_idlist_del_data(idata);
3455 silc_packet_set_context(sock, NULL);
3461 /* Removes client from all channels it has joined. This is used when client
3462 connection is disconnected. If the client on a channel is last, the
3463 channel is removed as well. This sends the SIGNOFF notify types. */
3465 void silc_server_remove_from_channels(SilcServer server,
3466 SilcPacketStream sock,
3467 SilcClientEntry client,
3469 const char *signoff_message,
3473 SilcChannelEntry channel;
3474 SilcChannelClientEntry chl;
3475 SilcHashTableList htl;
3476 SilcBuffer clidp = NULL;
3481 if (notify && !client->id)
3484 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3485 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3488 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3493 /* Remove the client from all channels. The client is removed from
3494 the channels' user list. */
3495 silc_hash_table_list(client->channels, &htl);
3496 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3497 channel = chl->channel;
3499 /* Remove channel if this is last client leaving the channel, unless
3500 the channel is permanent. */
3501 if (server->server_type != SILC_SERVER &&
3502 silc_hash_table_count(channel->user_list) < 2) {
3503 silc_server_channel_delete(server, channel);
3507 silc_hash_table_del(client->channels, channel);
3508 silc_hash_table_del(channel->user_list, client);
3509 channel->user_count--;
3511 /* If there is no global users on the channel anymore mark the channel
3512 as local channel. Do not check if the removed client is local client. */
3513 if (server->server_type == SILC_SERVER && channel->global_users &&
3514 chl->client->router && !silc_server_channel_has_global(channel))
3515 channel->global_users = FALSE;
3517 memset(chl, 'A', sizeof(*chl));
3520 /* Update statistics */
3521 if (SILC_IS_LOCAL(client))
3522 server->stat.my_chanclients--;
3523 if (server->server_type == SILC_ROUTER) {
3524 server->stat.cell_chanclients--;
3525 server->stat.chanclients--;
3528 /* If there is not at least one local user on the channel then we don't
3529 need the channel entry anymore, we can remove it safely, unless the
3530 channel is permanent channel */
3531 if (server->server_type == SILC_SERVER &&
3532 !silc_server_channel_has_local(channel)) {
3533 /* Notify about leaving client if this channel has global users. */
3534 if (notify && channel->global_users)
3535 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3536 SILC_NOTIFY_TYPE_SIGNOFF,
3537 signoff_message ? 2 : 1,
3538 clidp->data, silc_buffer_len(clidp),
3539 signoff_message, signoff_message ?
3540 strlen(signoff_message) : 0);
3542 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3543 silc_server_channel_delete(server, channel);
3547 /* Send notify to channel about client leaving SILC and channel too */
3549 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3550 SILC_NOTIFY_TYPE_SIGNOFF,
3551 signoff_message ? 2 : 1,
3552 clidp->data, silc_buffer_len(clidp),
3553 signoff_message, signoff_message ?
3554 strlen(signoff_message) : 0);
3556 if (killed && clidp) {
3557 /* Remove the client from channel's invite list */
3558 if (channel->invite_list &&
3559 silc_hash_table_count(channel->invite_list)) {
3561 SilcArgumentPayload iargs;
3562 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3563 silc_buffer_len(clidp), 3);
3564 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3565 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3566 silc_buffer_free(ab);
3567 silc_argument_payload_free(iargs);
3571 /* Don't create keys if we are shutting down */
3572 if (server->server_shutdown)
3575 /* Re-generate channel key if needed */
3576 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3577 if (!silc_server_create_channel_key(server, channel, 0))
3580 /* Send the channel key to the channel. The key of course is not sent
3581 to the client who was removed from the channel. */
3582 silc_server_send_channel_key(server, client->connection, channel,
3583 server->server_type == SILC_ROUTER ?
3584 FALSE : !server->standalone);
3588 silc_hash_table_list_reset(&htl);
3590 silc_buffer_free(clidp);
3593 /* Removes client from one channel. This is used for example when client
3594 calls LEAVE command to remove itself from the channel. Returns TRUE
3595 if channel still exists and FALSE if the channel is removed when
3596 last client leaves the channel. If `notify' is FALSE notify messages
3599 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3600 SilcPacketStream sock,
3601 SilcChannelEntry channel,
3602 SilcClientEntry client,
3605 SilcChannelClientEntry chl;
3608 SILC_LOG_DEBUG(("Removing %s from channel %s",
3609 silc_id_render(client->id, SILC_ID_CLIENT),
3610 channel->channel_name));
3612 /* Get the entry to the channel, if this client is not on the channel
3614 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3617 /* Remove channel if this is last client leaving the channel, unless
3618 the channel is permanent. */
3619 if (server->server_type != SILC_SERVER &&
3620 silc_hash_table_count(channel->user_list) < 2) {
3621 silc_server_channel_delete(server, channel);
3625 silc_hash_table_del(client->channels, channel);
3626 silc_hash_table_del(channel->user_list, client);
3627 channel->user_count--;
3629 /* If there is no global users on the channel anymore mark the channel
3630 as local channel. Do not check if the client is local client. */
3631 if (server->server_type == SILC_SERVER && channel->global_users &&
3632 chl->client->router && !silc_server_channel_has_global(channel))
3633 channel->global_users = FALSE;
3635 memset(chl, 'O', sizeof(*chl));
3638 /* Update statistics */
3639 if (SILC_IS_LOCAL(client))
3640 server->stat.my_chanclients--;
3641 if (server->server_type == SILC_ROUTER) {
3642 server->stat.cell_chanclients--;
3643 server->stat.chanclients--;
3646 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3650 /* If there is not at least one local user on the channel then we don't
3651 need the channel entry anymore, we can remove it safely, unless the
3652 channel is permanent channel */
3653 if (server->server_type == SILC_SERVER &&
3654 !silc_server_channel_has_local(channel)) {
3655 /* Notify about leaving client if this channel has global users. */
3656 if (notify && channel->global_users)
3657 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3658 SILC_NOTIFY_TYPE_LEAVE, 1,
3659 clidp->data, silc_buffer_len(clidp));
3661 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3662 silc_server_channel_delete(server, channel);
3663 silc_buffer_free(clidp);
3667 /* Send notify to channel about client leaving the channel */
3669 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3670 SILC_NOTIFY_TYPE_LEAVE, 1,
3671 clidp->data, silc_buffer_len(clidp));
3673 silc_buffer_free(clidp);
3677 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3678 function may be used only by router. In real SILC network all channels
3679 are created by routers thus this function is never used by normal
3682 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3683 SilcServerID *router_id,
3689 SilcChannelID *channel_id;
3690 SilcChannelEntry entry;
3691 SilcCipher send_key, receive_key;
3694 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3697 cipher = SILC_DEFAULT_CIPHER;
3699 hmac = SILC_DEFAULT_HMAC;
3701 /* Allocate cipher */
3702 if (!silc_cipher_alloc(cipher, &send_key))
3704 if (!silc_cipher_alloc(cipher, &receive_key)) {
3705 silc_cipher_free(send_key);
3710 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3711 silc_cipher_free(send_key);
3712 silc_cipher_free(receive_key);
3716 channel_name = strdup(channel_name);
3718 /* Create the channel ID */
3719 if (!silc_id_create_channel_id(server, router_id, server->rng,
3721 silc_free(channel_name);
3722 silc_cipher_free(send_key);
3723 silc_cipher_free(receive_key);
3724 silc_hmac_free(newhmac);
3728 /* Create the channel */
3729 entry = silc_idlist_add_channel(server->local_list, channel_name,
3730 SILC_CHANNEL_MODE_NONE, channel_id,
3731 NULL, send_key, receive_key, newhmac);
3733 silc_free(channel_name);
3734 silc_cipher_free(send_key);
3735 silc_cipher_free(receive_key);
3736 silc_hmac_free(newhmac);
3737 silc_free(channel_id);
3741 entry->cipher = strdup(cipher);
3742 entry->hmac_name = strdup(hmac);
3744 /* Now create the actual key material */
3745 if (!silc_server_create_channel_key(server, entry,
3746 silc_cipher_get_key_len(send_key) / 8)) {
3747 silc_idlist_del_channel(server->local_list, entry);
3751 /* Notify other routers about the new channel. We send the packet
3752 to our primary route. */
3754 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3755 channel_name, entry->id,
3756 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3759 /* Distribute to backup routers */
3760 if (broadcast && server->server_type == SILC_ROUTER) {
3762 unsigned char cid[32];
3763 SilcUInt32 name_len = strlen(channel_name);
3766 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3767 packet = silc_channel_payload_encode(channel_name, name_len,
3768 cid, id_len, entry->mode);
3769 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3770 packet->data, silc_buffer_len(packet), FALSE,
3772 silc_buffer_free(packet);
3775 server->stat.my_channels++;
3776 if (server->server_type == SILC_ROUTER) {
3777 server->stat.channels++;
3778 server->stat.cell_channels++;
3779 entry->users_resolved = TRUE;
3785 /* Same as above but creates the channel with Channel ID `channel_id. */
3788 silc_server_create_new_channel_with_id(SilcServer server,
3792 SilcChannelID *channel_id,
3795 SilcChannelEntry entry;
3796 SilcCipher send_key, receive_key;
3799 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3802 cipher = SILC_DEFAULT_CIPHER;
3804 hmac = SILC_DEFAULT_HMAC;
3806 /* Allocate cipher */
3807 if (!silc_cipher_alloc(cipher, &send_key))
3809 if (!silc_cipher_alloc(cipher, &receive_key)) {
3810 silc_cipher_free(send_key);
3815 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3816 silc_cipher_free(send_key);
3817 silc_cipher_free(receive_key);
3821 channel_name = strdup(channel_name);
3823 /* Create the channel */
3824 entry = silc_idlist_add_channel(server->local_list, channel_name,
3825 SILC_CHANNEL_MODE_NONE, channel_id,
3826 NULL, send_key, receive_key, newhmac);
3828 silc_cipher_free(send_key);
3829 silc_cipher_free(receive_key);
3830 silc_hmac_free(newhmac);
3831 silc_free(channel_name);
3835 /* Now create the actual key material */
3836 if (!silc_server_create_channel_key(server, entry,
3837 silc_cipher_get_key_len(send_key) / 8)) {
3838 silc_idlist_del_channel(server->local_list, entry);
3842 /* Notify other routers about the new channel. We send the packet
3843 to our primary route. */
3845 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3846 channel_name, entry->id,
3847 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3850 /* Distribute to backup routers */
3851 if (broadcast && server->server_type == SILC_ROUTER) {
3853 unsigned char cid[32];
3854 SilcUInt32 name_len = strlen(channel_name);
3857 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3858 packet = silc_channel_payload_encode(channel_name, name_len,
3859 cid, id_len, entry->mode);
3860 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3861 packet->data, silc_buffer_len(packet), FALSE,
3863 silc_buffer_free(packet);
3866 server->stat.my_channels++;
3867 if (server->server_type == SILC_ROUTER) {
3868 server->stat.channels++;
3869 server->stat.cell_channels++;
3870 entry->users_resolved = TRUE;
3876 /* Channel's key re-key timeout callback. */
3878 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3880 SilcServer server = app_context;
3881 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3885 /* Return now if we are shutting down */
3886 if (server->server_shutdown)
3889 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3892 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3895 /* Generates new channel key. This is used to create the initial channel key
3896 but also to re-generate new key for channel. If `key_len' is provided
3897 it is the bytes of the key length. */
3899 SilcBool silc_server_create_channel_key(SilcServer server,
3900 SilcChannelEntry channel,
3904 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3907 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3908 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3912 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3914 if (!channel->send_key)
3915 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3916 channel->send_key = NULL;
3919 if (!channel->receive_key)
3920 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3921 silc_cipher_free(channel->send_key);
3922 channel->send_key = channel->receive_key = NULL;
3928 else if (channel->key_len)
3929 len = channel->key_len / 8;
3931 len = silc_cipher_get_key_len(channel->send_key) / 8;
3933 /* Create channel key */
3934 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3937 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3938 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3940 /* Remove old key if exists */
3942 memset(channel->key, 0, channel->key_len / 8);
3943 silc_free(channel->key);
3947 channel->key_len = len * 8;
3948 channel->key = silc_memdup(channel_key, len);
3949 memset(channel_key, 0, sizeof(channel_key));
3951 /* Generate HMAC key from the channel key data and set it */
3953 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3954 memset(channel->key, 0, channel->key_len / 8);
3955 silc_free(channel->key);
3956 silc_cipher_free(channel->send_key);
3957 silc_cipher_free(channel->receive_key);
3958 channel->send_key = channel->receive_key = NULL;
3961 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3962 silc_hmac_set_key(channel->hmac, hash,
3963 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3964 memset(hash, 0, sizeof(hash));
3966 if (server->server_type == SILC_ROUTER) {
3967 if (!channel->rekey)
3968 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3969 channel->rekey->channel = channel;
3970 channel->rekey->key_len = key_len;
3971 if (channel->rekey->task)
3972 silc_schedule_task_del(server->schedule, channel->rekey->task);
3974 channel->rekey->task =
3975 silc_schedule_task_add_timeout(server->schedule,
3976 silc_server_channel_key_rekey,
3977 (void *)channel->rekey,
3978 server->config->channel_rekey_secs, 0);
3984 /* Saves the channel key found in the encoded `key_payload' buffer. This
3985 function is used when we receive Channel Key Payload and also when we're
3986 processing JOIN command reply. Returns entry to the channel. */
3988 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3989 SilcBuffer key_payload,
3990 SilcChannelEntry channel)
3992 SilcChannelKeyPayload payload = NULL;
3994 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3998 /* Decode channel key payload */
3999 payload = silc_channel_key_payload_parse(key_payload->data,
4000 silc_buffer_len(key_payload));
4002 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4007 /* Get the channel entry */
4010 /* Get channel ID */
4011 tmp = silc_channel_key_get_id(payload, &tmp_len);
4012 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4017 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4019 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4021 if (server->server_type == SILC_ROUTER)
4022 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4023 silc_id_render(&id, SILC_ID_CHANNEL)));
4029 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4031 tmp = silc_channel_key_get_key(payload, &tmp_len);
4037 cipher = silc_channel_key_get_cipher(payload, NULL);
4043 /* Remove old key if exists */
4045 memset(channel->key, 0, channel->key_len / 8);
4046 silc_free(channel->key);
4047 silc_cipher_free(channel->send_key);
4048 silc_cipher_free(channel->receive_key);
4051 /* Create new cipher */
4052 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4053 channel->send_key = NULL;
4057 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4058 silc_cipher_free(channel->send_key);
4059 channel->send_key = channel->receive_key = NULL;
4064 if (channel->cipher)
4065 silc_free(channel->cipher);
4066 channel->cipher = strdup(cipher);
4069 channel->key_len = tmp_len * 8;
4070 channel->key = silc_memdup(tmp, tmp_len);
4071 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4072 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4074 /* Generate HMAC key from the channel key data and set it */
4076 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4077 memset(channel->key, 0, channel->key_len / 8);
4078 silc_free(channel->key);
4079 silc_cipher_free(channel->send_key);
4080 silc_cipher_free(channel->receive_key);
4081 channel->send_key = channel->receive_key = NULL;
4084 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4085 silc_hmac_set_key(channel->hmac, hash,
4086 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4088 memset(hash, 0, sizeof(hash));
4089 memset(tmp, 0, tmp_len);
4091 if (server->server_type == SILC_ROUTER) {
4092 if (!channel->rekey)
4093 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4094 channel->rekey->channel = channel;
4095 if (channel->rekey->task)
4096 silc_schedule_task_del(server->schedule, channel->rekey->task);
4098 channel->rekey->task =
4099 silc_schedule_task_add_timeout(server->schedule,
4100 silc_server_channel_key_rekey,
4101 (void *)channel->rekey,
4102 server->config->channel_rekey_secs, 0);
4107 silc_channel_key_payload_free(payload);
4112 /* Returns assembled of all servers in the given ID list. The packet's
4113 form is dictated by the New ID payload. */
4115 static void silc_server_announce_get_servers(SilcServer server,
4116 SilcServerEntry remote,
4118 SilcBuffer *servers,
4119 unsigned long creation_time)
4122 SilcIDCacheEntry id_cache;
4123 SilcServerEntry entry;
4127 /* Go through all clients in the list */
4128 if (silc_idcache_get_all(id_list->servers, &list)) {
4129 silc_list_start(list);
4130 while ((id_cache = silc_list_get(list))) {
4131 entry = (SilcServerEntry)id_cache->context;
4133 /* Do not announce the one we've sending our announcements and
4134 do not announce ourself. Also check the creation time if it's
4136 if ((entry == remote) || (entry == server->id_entry) ||
4137 (creation_time && entry->data.created < creation_time))
4140 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4142 tmp = silc_buffer_realloc(*servers,
4144 silc_buffer_truelen((*servers)) +
4145 silc_buffer_len(idp) :
4146 silc_buffer_len(idp)));
4150 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4151 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4152 silc_buffer_pull(*servers, silc_buffer_len(idp));
4153 silc_buffer_free(idp);
4159 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4165 p = silc_notify_payload_encode(notify, argc, ap);
4171 /* This function is used by router to announce existing servers to our
4172 primary router when we've connected to it. If `creation_time' is non-zero
4173 then only the servers that has been created after the `creation_time'
4174 will be announced. */
4176 void silc_server_announce_servers(SilcServer server, SilcBool global,
4177 unsigned long creation_time,
4178 SilcPacketStream remote)
4180 SilcBuffer servers = NULL;
4182 SILC_LOG_DEBUG(("Announcing servers"));
4184 /* Get servers in local list */
4185 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4186 server->local_list, &servers,
4190 /* Get servers in global list */
4191 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4192 server->global_list, &servers,
4196 silc_buffer_push(servers, servers->data - servers->head);
4197 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4199 /* Send the packet */
4200 silc_server_packet_send(server, remote,
4201 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4202 servers->data, silc_buffer_len(servers));
4204 silc_buffer_free(servers);
4208 /* Returns assembled packet of all clients in the given ID list. The
4209 packet's form is dictated by the New ID Payload. */
4211 static void silc_server_announce_get_clients(SilcServer server,
4213 SilcBuffer *clients,
4215 unsigned long creation_time)
4218 SilcIDCacheEntry id_cache;
4219 SilcClientEntry client;
4222 unsigned char mode[4];
4225 /* Go through all clients in the list */
4226 if (silc_idcache_get_all(id_list->clients, &list)) {
4227 silc_list_start(list);
4228 while ((id_cache = silc_list_get(list))) {
4229 client = (SilcClientEntry)id_cache->context;
4231 if (creation_time && client->data.created < creation_time)
4233 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4235 if (!client->connection && !client->router)
4238 SILC_LOG_DEBUG(("Announce Client ID %s",
4239 silc_id_render(client->id, SILC_ID_CLIENT)));
4241 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4245 tmp2 = silc_buffer_realloc(*clients,
4247 silc_buffer_truelen((*clients)) +
4248 silc_buffer_len(idp) :
4249 silc_buffer_len(idp)));
4253 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4254 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4255 silc_buffer_pull(*clients, silc_buffer_len(idp));
4257 SILC_PUT32_MSB(client->mode, mode);
4259 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4260 2, idp->data, silc_buffer_len(idp),
4262 tmp2 = silc_buffer_realloc(*umodes,
4264 silc_buffer_truelen((*umodes)) +
4265 silc_buffer_len(tmp) :
4266 silc_buffer_len(tmp)));
4270 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4271 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4272 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4273 silc_buffer_free(tmp);
4275 silc_buffer_free(idp);
4280 /* This function is used to announce our existing clients to our router
4281 when we've connected to it. If `creation_time' is non-zero then only
4282 the clients that has been created after the `creation_time' will be
4285 void silc_server_announce_clients(SilcServer server,
4286 unsigned long creation_time,
4287 SilcPacketStream remote)
4289 SilcBuffer clients = NULL;
4290 SilcBuffer umodes = NULL;
4292 SILC_LOG_DEBUG(("Announcing clients"));
4294 /* Get clients in local list */
4295 silc_server_announce_get_clients(server, server->local_list,
4296 &clients, &umodes, creation_time);
4298 /* As router we announce our global list as well */
4299 if (server->server_type == SILC_ROUTER)
4300 silc_server_announce_get_clients(server, server->global_list,
4301 &clients, &umodes, creation_time);
4304 silc_buffer_push(clients, clients->data - clients->head);
4305 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4307 /* Send the packet */
4308 silc_server_packet_send(server, remote,
4309 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4310 clients->data, silc_buffer_len(clients));
4312 silc_buffer_free(clients);
4316 silc_buffer_push(umodes, umodes->data - umodes->head);
4317 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4319 /* Send the packet */
4320 silc_server_packet_send(server, remote,
4321 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4322 umodes->data, silc_buffer_len(umodes));
4324 silc_buffer_free(umodes);
4328 /* Returns channel's topic for announcing it */
4330 void silc_server_announce_get_channel_topic(SilcServer server,
4331 SilcChannelEntry channel,
4336 if (channel->topic) {
4337 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4338 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4340 silc_buffer_len(chidp),
4342 strlen(channel->topic));
4343 silc_buffer_free(chidp);
4347 /* Returns channel's invite and ban lists */
4349 void silc_server_announce_get_inviteban(SilcServer server,
4350 SilcChannelEntry channel,
4354 SilcBuffer list, idp, idp2, tmp2;
4357 SilcHashTableList htl;
4358 const unsigned char a[1] = { 0x03 };
4360 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4362 /* Encode invite list */
4363 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4364 list = silc_buffer_alloc_size(2);
4365 type = silc_hash_table_count(channel->invite_list);
4366 SILC_PUT16_MSB(type, list->data);
4367 silc_hash_table_list(channel->invite_list, &htl);
4368 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4369 list = silc_argument_payload_encode_one(list, tmp2->data,
4370 silc_buffer_len(tmp2),
4371 SILC_PTR_TO_32(ptype));
4372 silc_hash_table_list_reset(&htl);
4374 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4376 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4377 idp->data, silc_buffer_len(idp),
4378 channel->channel_name,
4379 strlen(channel->channel_name),
4380 idp2->data, silc_buffer_len(idp2),
4382 list->data, silc_buffer_len(list));
4383 silc_buffer_free(idp2);
4384 silc_buffer_free(list);
4387 /* Encode ban list */
4388 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4389 list = silc_buffer_alloc_size(2);
4390 type = silc_hash_table_count(channel->ban_list);
4391 SILC_PUT16_MSB(type, list->data);
4392 silc_hash_table_list(channel->ban_list, &htl);
4393 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4394 list = silc_argument_payload_encode_one(list, tmp2->data,
4395 silc_buffer_len(tmp2),
4396 SILC_PTR_TO_32(ptype));
4397 silc_hash_table_list_reset(&htl);
4400 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4401 idp->data, silc_buffer_len(idp),
4403 list->data, silc_buffer_len(list));
4404 silc_buffer_free(list);
4407 silc_buffer_free(idp);
4410 /* Returns assembled packets for channel users of the `channel'. */
4412 void silc_server_announce_get_channel_users(SilcServer server,
4413 SilcChannelEntry channel,
4414 SilcBuffer *channel_modes,
4415 SilcBuffer *channel_users,
4416 SilcBuffer *channel_users_modes)
4418 SilcChannelClientEntry chl;
4419 SilcHashTableList htl;
4420 SilcBuffer chidp, clidp, csidp;
4421 SilcBuffer tmp, fkey = NULL, chpklist;
4423 unsigned char mode[4], ulimit[4];
4427 SILC_LOG_DEBUG(("Start"));
4429 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4430 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4431 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4434 SILC_PUT32_MSB(channel->mode, mode);
4435 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4436 SILC_PUT32_MSB(channel->user_limit, ulimit);
4437 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4438 if (channel->founder_key)
4439 fkey = silc_public_key_payload_encode(channel->founder_key);
4441 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4443 silc_buffer_len(csidp),
4446 hmac, hmac ? strlen(hmac) : 0,
4447 channel->passphrase,
4448 channel->passphrase ?
4449 strlen(channel->passphrase) : 0,
4450 fkey ? fkey->data : NULL,
4451 fkey ? silc_buffer_len(fkey) : 0,
4452 chpklist ? chpklist->data : NULL,
4454 silc_buffer_len(chpklist) : 0,
4456 SILC_CHANNEL_MODE_ULIMIT ?
4459 SILC_CHANNEL_MODE_ULIMIT ?
4460 sizeof(ulimit) : 0));
4461 len = silc_buffer_len(tmp);
4463 silc_buffer_realloc(*channel_modes,
4465 silc_buffer_truelen((*channel_modes)) + len : len));
4468 *channel_modes = tmp2;
4469 silc_buffer_pull_tail(*channel_modes,
4470 ((*channel_modes)->end -
4471 (*channel_modes)->data));
4472 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4473 silc_buffer_pull(*channel_modes, len);
4474 silc_buffer_free(tmp);
4475 silc_buffer_free(fkey);
4478 /* Now find all users on the channel */
4479 silc_hash_table_list(channel->user_list, &htl);
4480 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4481 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4483 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4487 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4489 silc_buffer_len(clidp),
4491 silc_buffer_len(chidp));
4492 len = silc_buffer_len(tmp);
4494 silc_buffer_realloc(*channel_users,
4496 silc_buffer_truelen((*channel_users)) + len : len));
4499 *channel_users = tmp2;
4500 silc_buffer_pull_tail(*channel_users,
4501 ((*channel_users)->end -
4502 (*channel_users)->data));
4504 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4505 silc_buffer_pull(*channel_users, len);
4506 silc_buffer_free(tmp);
4508 /* CUMODE notify for mode change on the channel */
4509 SILC_PUT32_MSB(chl->mode, mode);
4510 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4511 fkey = silc_public_key_payload_encode(channel->founder_key);
4512 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4514 silc_buffer_len(csidp),
4517 silc_buffer_len(clidp),
4518 fkey ? fkey->data : NULL,
4519 fkey ? silc_buffer_len(fkey) : 0);
4520 len = silc_buffer_len(tmp);
4522 silc_buffer_realloc(*channel_users_modes,
4523 (*channel_users_modes ?
4524 silc_buffer_truelen((*channel_users_modes)) +
4528 *channel_users_modes = tmp2;
4529 silc_buffer_pull_tail(*channel_users_modes,
4530 ((*channel_users_modes)->end -
4531 (*channel_users_modes)->data));
4533 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4534 silc_buffer_pull(*channel_users_modes, len);
4535 silc_buffer_free(tmp);
4536 silc_buffer_free(fkey);
4538 silc_buffer_free(clidp);
4540 silc_hash_table_list_reset(&htl);
4541 silc_buffer_free(chidp);
4542 silc_buffer_free(csidp);
4545 /* Returns assembled packets for all channels and users on those channels
4546 from the given ID List. The packets are in the form dictated by the
4547 New Channel and New Channel User payloads. */
4549 void silc_server_announce_get_channels(SilcServer server,
4551 SilcBuffer *channels,
4552 SilcBuffer **channel_modes,
4553 SilcBuffer *channel_users,
4554 SilcBuffer **channel_users_modes,
4555 SilcUInt32 *channel_users_modes_c,
4556 SilcBuffer **channel_topics,
4557 SilcBuffer **channel_invites,
4558 SilcBuffer **channel_bans,
4559 SilcChannelID ***channel_ids,
4560 unsigned long creation_time)
4563 SilcIDCacheEntry id_cache;
4564 SilcChannelEntry channel;
4565 unsigned char cid[32];
4567 SilcUInt16 name_len;
4569 int i = *channel_users_modes_c;
4573 SILC_LOG_DEBUG(("Start"));
4575 /* Go through all channels in the list */
4576 if (silc_idcache_get_all(id_list->channels, &list)) {
4577 silc_list_start(list);
4578 while ((id_cache = silc_list_get(list))) {
4579 channel = (SilcChannelEntry)id_cache->context;
4581 if (creation_time && channel->created < creation_time)
4586 SILC_LOG_DEBUG(("Announce Channel ID %s",
4587 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4589 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4590 name_len = strlen(channel->channel_name);
4593 len = 4 + name_len + id_len + 4;
4595 silc_buffer_realloc(*channels,
4597 silc_buffer_truelen((*channels)) +
4603 silc_buffer_pull_tail(*channels,
4604 ((*channels)->end - (*channels)->data));
4605 silc_buffer_format(*channels,
4606 SILC_STR_UI_SHORT(name_len),
4607 SILC_STR_UI_XNSTRING(channel->channel_name,
4609 SILC_STR_UI_SHORT(id_len),
4610 SILC_STR_UI_XNSTRING(cid, id_len),
4611 SILC_STR_UI_INT(channel->mode),
4613 silc_buffer_pull(*channels, len);
4616 if (creation_time && channel->updated < creation_time)
4622 /* Channel user modes */
4623 tmp = silc_realloc(*channel_users_modes,
4624 sizeof(**channel_users_modes) * (i + 1));
4627 *channel_users_modes = tmp;
4628 (*channel_users_modes)[i] = NULL;
4629 tmp = silc_realloc(*channel_modes,
4630 sizeof(**channel_modes) * (i + 1));
4633 *channel_modes = tmp;
4634 (*channel_modes)[i] = NULL;
4635 tmp = silc_realloc(*channel_ids,
4636 sizeof(**channel_ids) * (i + 1));
4640 (*channel_ids)[i] = NULL;
4641 silc_server_announce_get_channel_users(server, channel,
4642 &(*channel_modes)[i],
4644 &(*channel_users_modes)[i]);
4645 (*channel_ids)[i] = channel->id;
4647 /* Channel's topic */
4648 tmp = silc_realloc(*channel_topics,
4649 sizeof(**channel_topics) * (i + 1));
4652 *channel_topics = tmp;
4653 (*channel_topics)[i] = NULL;
4654 silc_server_announce_get_channel_topic(server, channel,
4655 &(*channel_topics)[i]);
4657 /* Channel's invite and ban list */
4658 tmp = silc_realloc(*channel_invites,
4659 sizeof(**channel_invites) * (i + 1));
4662 *channel_invites = tmp;
4663 (*channel_invites)[i] = NULL;
4664 tmp = silc_realloc(*channel_bans,
4665 sizeof(**channel_bans) * (i + 1));
4668 *channel_bans = tmp;
4669 (*channel_bans)[i] = NULL;
4670 silc_server_announce_get_inviteban(server, channel,
4671 &(*channel_invites)[i],
4672 &(*channel_bans)[i]);
4674 (*channel_users_modes_c)++;
4682 /* This function is used to announce our existing channels to our router
4683 when we've connected to it. This also announces the users on the
4684 channels to the router. If the `creation_time' is non-zero only the
4685 channels that was created after the `creation_time' are announced.
4686 Note that the channel users are still announced even if the `creation_time'
4689 void silc_server_announce_channels(SilcServer server,
4690 unsigned long creation_time,
4691 SilcPacketStream remote)
4693 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4694 SilcBuffer *channel_users_modes = NULL;
4695 SilcBuffer *channel_topics = NULL;
4696 SilcBuffer *channel_invites = NULL;
4697 SilcBuffer *channel_bans = NULL;
4698 SilcUInt32 channel_users_modes_c = 0;
4699 SilcChannelID **channel_ids = NULL;
4701 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4703 /* Get channels and channel users in local list */
4704 silc_server_announce_get_channels(server, server->local_list,
4705 &channels, &channel_modes,
4707 &channel_users_modes,
4708 &channel_users_modes_c,
4712 &channel_ids, creation_time);
4714 /* Get channels and channel users in global list */
4715 if (server->server_type != SILC_SERVER)
4716 silc_server_announce_get_channels(server, server->global_list,
4717 &channels, &channel_modes,
4719 &channel_users_modes,
4720 &channel_users_modes_c,
4724 &channel_ids, creation_time);
4727 silc_buffer_push(channels, channels->data - channels->head);
4728 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4730 /* Send the packet */
4731 silc_server_packet_send(server, remote,
4732 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4733 channels->data, silc_buffer_len(channels));
4735 silc_buffer_free(channels);
4738 if (channel_users) {
4739 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4740 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4741 silc_buffer_len(channel_users));
4743 /* Send the packet */
4744 silc_server_packet_send(server, remote,
4745 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4746 channel_users->data, silc_buffer_len(channel_users));
4748 silc_buffer_free(channel_users);
4751 if (channel_modes) {
4754 for (i = 0; i < channel_users_modes_c; i++) {
4755 if (!channel_modes[i])
4757 silc_buffer_push(channel_modes[i],
4758 channel_modes[i]->data -
4759 channel_modes[i]->head);
4760 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4761 silc_buffer_len(channel_modes[i]));
4762 silc_server_packet_send_dest(server, remote,
4763 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4764 channel_ids[i], SILC_ID_CHANNEL,
4765 channel_modes[i]->data,
4766 silc_buffer_len(channel_modes[i]));
4767 silc_buffer_free(channel_modes[i]);
4769 silc_free(channel_modes);
4772 if (channel_users_modes) {
4775 for (i = 0; i < channel_users_modes_c; i++) {
4776 if (!channel_users_modes[i])
4778 silc_buffer_push(channel_users_modes[i],
4779 channel_users_modes[i]->data -
4780 channel_users_modes[i]->head);
4781 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4782 silc_buffer_len(channel_users_modes[i]));
4783 silc_server_packet_send_dest(server, remote,
4784 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4785 channel_ids[i], SILC_ID_CHANNEL,
4786 channel_users_modes[i]->data,
4787 silc_buffer_len(channel_users_modes[i]));
4788 silc_buffer_free(channel_users_modes[i]);
4790 silc_free(channel_users_modes);
4793 if (channel_topics) {
4796 for (i = 0; i < channel_users_modes_c; i++) {
4797 if (!channel_topics[i])
4800 silc_buffer_push(channel_topics[i],
4801 channel_topics[i]->data -
4802 channel_topics[i]->head);
4803 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4804 silc_buffer_len(channel_topics[i]));
4805 silc_server_packet_send_dest(server, remote,
4806 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4807 channel_ids[i], SILC_ID_CHANNEL,
4808 channel_topics[i]->data,
4809 silc_buffer_len(channel_topics[i]));
4810 silc_buffer_free(channel_topics[i]);
4812 silc_free(channel_topics);
4815 if (channel_invites) {
4818 for (i = 0; i < channel_users_modes_c; i++) {
4819 if (!channel_invites[i])
4822 silc_buffer_push(channel_invites[i],
4823 channel_invites[i]->data -
4824 channel_invites[i]->head);
4825 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4826 silc_buffer_len(channel_invites[i]));
4827 silc_server_packet_send_dest(server, remote,
4828 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4829 channel_ids[i], SILC_ID_CHANNEL,
4830 channel_invites[i]->data,
4831 silc_buffer_len(channel_invites[i]));
4832 silc_buffer_free(channel_invites[i]);
4834 silc_free(channel_invites);
4840 for (i = 0; i < channel_users_modes_c; i++) {
4841 if (!channel_bans[i])
4844 silc_buffer_push(channel_bans[i],
4845 channel_bans[i]->data -
4846 channel_bans[i]->head);
4847 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4848 silc_buffer_len(channel_bans[i]));
4849 silc_server_packet_send_dest(server, remote,
4850 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4851 channel_ids[i], SILC_ID_CHANNEL,
4852 channel_bans[i]->data,
4853 silc_buffer_len(channel_bans[i]));
4854 silc_buffer_free(channel_bans[i]);
4856 silc_free(channel_bans);
4859 silc_free(channel_ids);
4862 /* Announces WATCH list. */
4864 void silc_server_announce_watches(SilcServer server,
4865 SilcPacketStream remote)
4867 SilcHashTableList htl;
4868 SilcBuffer buffer, idp, args, pkp;
4869 SilcClientEntry client;
4872 SILC_LOG_DEBUG(("Announcing watch list"));
4874 /* XXX because way we save the nicks (hash) we cannot announce them. */
4876 /* XXX we should send all public keys in one command if client is
4877 watching more than one key */
4878 silc_hash_table_list(server->watcher_list_pk, &htl);
4879 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4880 if (!client || !client->id)
4883 server->stat.commands_sent++;
4885 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4886 args = silc_buffer_alloc_size(2);
4887 silc_buffer_format(args,
4888 SILC_STR_UI_SHORT(1),
4890 pkp = silc_public_key_payload_encode(key);
4891 args = silc_argument_payload_encode_one(args, pkp->data,
4892 silc_buffer_len(pkp), 0x00);
4893 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4894 ++server->cmd_ident, 2,
4895 1, idp->data, silc_buffer_len(idp),
4897 silc_buffer_len(args));
4900 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4901 buffer->data, silc_buffer_len(buffer));
4903 silc_buffer_free(pkp);
4904 silc_buffer_free(args);
4905 silc_buffer_free(idp);
4906 silc_buffer_free(buffer);
4908 silc_hash_table_list_reset(&htl);
4911 /* Assembles user list and users mode list from the `channel'. */
4913 SilcBool silc_server_get_users_on_channel(SilcServer server,
4914 SilcChannelEntry channel,
4915 SilcBuffer *user_list,
4916 SilcBuffer *mode_list,
4917 SilcUInt32 *user_count)
4919 SilcChannelClientEntry chl;
4920 SilcHashTableList htl;
4921 SilcBuffer client_id_list;
4922 SilcBuffer client_mode_list;
4924 SilcUInt32 list_count = 0, len = 0;
4926 if (!silc_hash_table_count(channel->user_list))
4929 silc_hash_table_list(channel->user_list, &htl);
4930 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4931 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4932 silc_hash_table_list_reset(&htl);
4934 client_id_list = silc_buffer_alloc(len);
4936 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4937 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4938 silc_buffer_pull_tail(client_mode_list,
4939 silc_buffer_truelen(client_mode_list));
4941 silc_hash_table_list(channel->user_list, &htl);
4942 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4944 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4945 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4946 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4947 silc_buffer_free(idp);
4949 /* Client's mode on channel */
4950 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4951 silc_buffer_pull(client_mode_list, 4);
4955 silc_hash_table_list_reset(&htl);
4956 silc_buffer_push(client_id_list,
4957 client_id_list->data - client_id_list->head);
4958 silc_buffer_push(client_mode_list,
4959 client_mode_list->data - client_mode_list->head);
4961 *user_list = client_id_list;
4962 *mode_list = client_mode_list;
4963 *user_count = list_count;
4967 /* Saves users and their modes to the `channel'. */
4969 void silc_server_save_users_on_channel(SilcServer server,
4970 SilcPacketStream sock,
4971 SilcChannelEntry channel,
4972 SilcClientID *noadd,
4973 SilcBuffer user_list,
4974 SilcBuffer mode_list,
4975 SilcUInt32 user_count)
4981 SilcClientEntry client;
4982 SilcIDCacheEntry cache;
4983 SilcChannelClientEntry chl;
4985 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4986 channel->channel_name));
4988 for (i = 0; i < user_count; i++) {
4990 SILC_GET16_MSB(idp_len, user_list->data + 2);
4992 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4994 silc_buffer_pull(user_list, idp_len);
4997 SILC_GET32_MSB(mode, mode_list->data);
4998 silc_buffer_pull(mode_list, 4);
5000 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5005 /* Check if we have this client cached already. */
5006 client = silc_idlist_find_client_by_id(server->local_list,
5008 server->server_type, &cache);
5010 client = silc_idlist_find_client_by_id(server->global_list,
5012 server->server_type, &cache);
5014 /* If router did not find such Client ID in its lists then this must
5015 be bogus client or some router in the net is buggy. */
5016 if (server->server_type != SILC_SERVER)
5019 /* We don't have that client anywhere, add it. The client is added
5020 to global list since server didn't have it in the lists so it must be
5022 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5023 silc_id_dup(&id.u.client_id,
5025 silc_packet_get_context(sock),
5028 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5032 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5035 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5036 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5037 "%s", channel->channel_name));
5041 if (!silc_server_client_on_channel(client, channel, &chl)) {
5042 /* Client was not on the channel, add it. */
5043 chl = silc_calloc(1, sizeof(*chl));
5044 chl->client = client;
5046 chl->channel = channel;
5047 silc_hash_table_add(channel->user_list, chl->client, chl);
5048 silc_hash_table_add(client->channels, chl->channel, chl);
5049 channel->user_count++;
5057 /* Saves channels and channels user modes to the `client'. Removes
5058 the client from those channels that are not sent in the list but
5061 void silc_server_save_user_channels(SilcServer server,
5062 SilcPacketStream sock,
5063 SilcClientEntry client,
5064 SilcBuffer channels,
5065 SilcBuffer channels_user_modes)
5068 SilcUInt32 *chumodes;
5069 SilcChannelPayload entry;
5070 SilcChannelEntry channel;
5071 SilcChannelID channel_id;
5072 SilcChannelClientEntry chl;
5073 SilcHashTable ht = NULL;
5074 SilcHashTableList htl;
5078 if (!channels || !channels_user_modes ||
5079 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5082 ch = silc_channel_payload_parse_list(channels->data,
5083 silc_buffer_len(channels));
5084 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5086 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5087 NULL, NULL, NULL, TRUE);
5088 silc_dlist_start(ch);
5089 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5090 /* Check if we have this channel, and add it if we don't have it.
5091 Also add the client on the channel unless it is there already. */
5092 if (!silc_channel_get_id_parse(entry, &channel_id))
5094 channel = silc_idlist_find_channel_by_id(server->local_list,
5097 channel = silc_idlist_find_channel_by_id(server->global_list,
5100 if (server->server_type != SILC_SERVER) {
5105 /* We don't have that channel anywhere, add it. */
5106 name = silc_channel_get_name(entry, NULL);
5107 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5108 silc_id_dup(&channel_id,
5110 server->router, NULL, NULL, 0);
5117 channel->mode = silc_channel_get_mode(entry);
5119 /* Add the client on the channel */
5120 if (!silc_server_client_on_channel(client, channel, &chl)) {
5121 chl = silc_calloc(1, sizeof(*chl));
5122 chl->client = client;
5123 chl->mode = chumodes[i++];
5124 chl->channel = channel;
5125 silc_hash_table_add(channel->user_list, chl->client, chl);
5126 silc_hash_table_add(client->channels, chl->channel, chl);
5127 channel->user_count++;
5130 chl->mode = chumodes[i++];
5133 silc_hash_table_add(ht, channel, channel);
5135 silc_channel_payload_list_free(ch);
5136 silc_free(chumodes);
5140 /* Go through the list again and remove client from channels that
5141 are no part of the list. */
5143 silc_hash_table_list(client->channels, &htl);
5144 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5145 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5146 silc_hash_table_del(chl->channel->user_list, chl->client);
5147 silc_hash_table_del(chl->client->channels, chl->channel);
5151 silc_hash_table_list_reset(&htl);
5152 silc_hash_table_free(ht);
5154 silc_hash_table_list(client->channels, &htl);
5155 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5156 silc_hash_table_del(chl->channel->user_list, chl->client);
5157 silc_hash_table_del(chl->client->channels, chl->channel);
5160 silc_hash_table_list_reset(&htl);
5164 /* Lookups route to the client indicated by the `id_data'. The connection
5165 object and internal data object is returned. Returns NULL if route
5166 could not be found to the client. If the `client_id' is specified then
5167 it is used and the `id_data' is ignored. */
5170 silc_server_get_client_route(SilcServer server,
5171 unsigned char *id_data,
5173 SilcClientID *client_id,
5174 SilcIDListData *idata,
5175 SilcClientEntry *client_entry)
5177 SilcClientID *id, clid;
5178 SilcClientEntry client;
5180 SILC_LOG_DEBUG(("Start"));
5183 *client_entry = NULL;
5185 /* Decode destination Client ID */
5187 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5189 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5191 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5194 /* If the destination belongs to our server we don't have to route
5195 the packet anywhere but to send it to the local destination. */
5196 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5200 /* If we are router and the client has router then the client is in
5201 our cell but not directly connected to us. */
5202 if (server->server_type == SILC_ROUTER && client->router) {
5203 /* We are of course in this case the client's router thus the route
5204 to the client is the server who owns the client. So, we will send
5205 the packet to that server. */
5207 *idata = (SilcIDListData)client->router;
5208 return client->router->connection;
5211 /* Seems that client really is directly connected to us */
5213 *idata = (SilcIDListData)client;
5215 *client_entry = client;
5216 return client->connection;
5219 /* Destination belongs to someone not in this server. If we are normal
5220 server our action is to send the packet to our router. */
5221 if (server->server_type != SILC_ROUTER && !server->standalone) {
5224 *idata = (SilcIDListData)server->router;
5225 return SILC_PRIMARY_ROUTE(server);
5228 /* We are router and we will perform route lookup for the destination
5229 and send the packet to fastest route. */
5230 if (server->server_type == SILC_ROUTER && !server->standalone) {
5231 /* Check first that the ID is valid */
5232 client = silc_idlist_find_client_by_id(server->global_list, id,
5235 SilcPacketStream dst_sock;
5237 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5240 if (idata && dst_sock)
5241 *idata = silc_packet_get_context(dst_sock);
5250 /* Encodes and returns channel list of channels the `client' has joined.
5251 Secret channels are not put to the list. */
5253 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5254 SilcClientEntry client,
5255 SilcBool get_private,
5256 SilcBool get_secret,
5257 SilcBuffer *user_mode_list)
5259 SilcBuffer buffer = NULL;
5260 SilcChannelEntry channel;
5261 SilcChannelClientEntry chl;
5262 SilcHashTableList htl;
5263 unsigned char cid[32];
5265 SilcUInt16 name_len;
5269 *user_mode_list = NULL;
5271 silc_hash_table_list(client->channels, &htl);
5272 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5273 channel = chl->channel;
5275 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5277 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5280 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5281 name_len = strlen(channel->channel_name);
5283 len = 4 + name_len + id_len + 4;
5284 buffer = silc_buffer_realloc(buffer,
5286 silc_buffer_truelen(buffer) + len : len));
5287 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5288 silc_buffer_format(buffer,
5289 SILC_STR_UI_SHORT(name_len),
5290 SILC_STR_DATA(channel->channel_name, name_len),
5291 SILC_STR_UI_SHORT(id_len),
5292 SILC_STR_DATA(cid, id_len),
5293 SILC_STR_UI_INT(chl->channel->mode),
5295 silc_buffer_pull(buffer, len);
5297 if (user_mode_list) {
5299 silc_buffer_realloc(*user_mode_list,
5301 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5302 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5303 (*user_mode_list)->data));
5304 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5305 silc_buffer_pull(*user_mode_list, 4);
5308 silc_hash_table_list_reset(&htl);
5311 silc_buffer_push(buffer, buffer->data - buffer->head);
5312 if (user_mode_list && *user_mode_list)
5313 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5314 (*user_mode_list)->head));
5319 /* Task callback used to retrieve network statistical information from
5320 router server once in a while. */
5322 SILC_TASK_CALLBACK(silc_server_get_stats)
5324 SilcServer server = (SilcServer)context;
5325 SilcBuffer idp, packet;
5327 if (!server->standalone) {
5328 SILC_LOG_DEBUG(("Retrieving stats from router"));
5329 server->stat.commands_sent++;
5330 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5332 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5333 ++server->cmd_ident, 1,
5335 silc_buffer_len(idp));
5336 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5337 SILC_PACKET_COMMAND, 0, packet->data,
5338 silc_buffer_len(packet));
5339 silc_buffer_free(packet);
5340 silc_buffer_free(idp);
5344 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,