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 /* Rekey callback. Start rekey as initiator */
2916 SILC_TASK_CALLBACK(silc_server_do_rekey)
2918 SilcServer server = app_context;
2919 SilcPacketStream sock = context;
2920 SilcIDListData idata = silc_packet_get_context(sock);
2923 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2925 /* Do not execute rekey with disabled connections */
2926 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2929 /* If another protocol is active do not start rekey */
2930 if (idata->sconn->op) {
2931 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2932 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2937 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2938 idata->sconn->remote_host, idata->sconn->remote_port,
2939 SILC_CONNTYPE_STRING(idata->conn_type)));
2942 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2943 server->public_key, NULL, sock);
2947 /* Set SKE callbacks */
2948 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2951 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2954 /* Responder rekey completion callback */
2957 silc_server_rekey_resp_completion(SilcSKE ske,
2958 SilcSKEStatus status,
2959 const SilcSKESecurityProperties prop,
2960 const SilcSKEKeyMaterial keymat,
2961 SilcSKERekeyMaterial rekey,
2964 SilcPacketStream sock = context;
2965 SilcIDListData idata = silc_packet_get_context(sock);
2967 idata->sconn->op = NULL;
2968 if (status != SILC_SKE_STATUS_OK) {
2969 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2970 idata->sconn->remote_host));
2974 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2975 idata->sconn->remote_host, idata->sconn->remote_port,
2976 SILC_CONNTYPE_STRING(idata->conn_type)));
2978 /* Save rekey data for next rekey */
2979 idata->rekey = rekey;
2982 /* Start rekey as responder */
2984 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2987 SilcIDListData idata = silc_packet_get_context(sock);
2990 if (!idata->rekey) {
2991 silc_packet_free(packet);
2995 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
2996 idata->sconn->remote_host, idata->sconn->remote_port,
2997 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3000 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3001 server->public_key, NULL, sock);
3003 silc_packet_free(packet);
3007 /* Set SKE callbacks */
3008 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3011 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3016 /****************************** Disconnection *******************************/
3018 /* Destroys packet stream. */
3020 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3022 silc_packet_stream_unref(context);
3025 /* Closes connection to socket connection */
3027 void silc_server_close_connection(SilcServer server,
3028 SilcPacketStream sock)
3030 SilcIDListData idata = silc_packet_get_context(sock);
3032 const char *hostname;
3035 if (!silc_packet_stream_is_valid(sock))
3038 memset(tmp, 0, sizeof(tmp));
3039 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3040 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3041 NULL, &hostname, NULL, &port);
3042 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3043 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3044 tmp[0] ? tmp : ""));
3046 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3048 if (idata && idata->sconn) {
3049 silc_server_connection_free(idata->sconn);
3050 idata->sconn = NULL;
3053 /* Take a reference and then destroy the stream. The last reference
3054 is released later in a timeout callback. */
3055 silc_packet_stream_ref(sock);
3056 silc_packet_stream_destroy(sock);
3058 /* Close connection with timeout */
3059 server->stat.conn_num--;
3060 silc_schedule_task_del_by_all(server->schedule, 0,
3061 silc_server_close_connection_final, sock);
3062 silc_schedule_task_add_timeout(server->schedule,
3063 silc_server_close_connection_final,
3067 /* Sends disconnect message to remote connection and disconnects the
3070 void silc_server_disconnect_remote(SilcServer server,
3071 SilcPacketStream sock,
3072 SilcStatus status, ...)
3074 unsigned char buf[512];
3081 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock));
3083 va_start(ap, status);
3084 cp = va_arg(ap, char *);
3086 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3089 /* Send SILC_PACKET_DISCONNECT */
3090 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3091 SILC_STR_UI_CHAR(status),
3092 SILC_STR_UI8_STRING(cp ? buf : NULL),
3095 /* Close connection */
3096 silc_server_close_connection(server, sock);
3099 /* Frees client data and notifies about client's signoff. */
3101 void silc_server_free_client_data(SilcServer server,
3102 SilcPacketStream sock,
3103 SilcClientEntry client,
3105 const char *signoff)
3107 SILC_LOG_DEBUG(("Freeing client %p data", client));
3110 /* Check if anyone is watching this nickname */
3111 if (server->server_type == SILC_ROUTER)
3112 silc_server_check_watcher_list(server, client, NULL,
3113 SILC_NOTIFY_TYPE_SIGNOFF);
3115 /* Send SIGNOFF notify to routers. */
3117 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3118 SILC_BROADCAST(server), client->id,
3122 /* Remove client from all channels */
3124 silc_server_remove_from_channels(server, NULL, client,
3125 TRUE, (char *)signoff, TRUE, FALSE);
3127 silc_server_remove_from_channels(server, NULL, client,
3128 FALSE, NULL, FALSE, FALSE);
3130 /* Remove this client from watcher list if it is */
3131 silc_server_del_from_watcher_list(server, client);
3133 /* Remove client's public key from repository, this will free it too. */
3134 if (client->data.public_key) {
3135 silc_skr_del_public_key(server->repository, client->data.public_key,
3137 client->data.public_key = NULL;
3140 /* Update statistics */
3141 server->stat.my_clients--;
3142 SILC_VERIFY(server->stat.clients > 0);
3143 server->stat.clients--;
3144 if (server->stat.cell_clients)
3145 server->stat.cell_clients--;
3146 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3147 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3148 silc_schedule_task_del_by_context(server->schedule, client);
3150 if (client->data.sconn) {
3151 silc_server_connection_free(client->data.sconn);
3152 client->data.sconn = NULL;
3155 /* We will not delete the client entry right away. We will take it
3156 into history (for WHOWAS command) for 5 minutes, unless we're
3157 shutting down server. */
3158 if (!server->server_shutdown) {
3159 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3161 client->router = NULL;
3162 client->connection = NULL;
3163 client->data.created = silc_time();
3164 silc_dlist_del(server->expired_clients, client);
3165 silc_dlist_add(server->expired_clients, client);
3167 /* Delete directly since we're shutting down server */
3168 SILC_LOG_DEBUG(("Delete client directly"));
3169 silc_idlist_del_data(client);
3170 silc_idlist_del_client(server->local_list, client);
3174 /* Frees user_data pointer from socket connection object. This also sends
3175 appropriate notify packets to the network to inform about leaving
3178 void silc_server_free_sock_user_data(SilcServer server,
3179 SilcPacketStream sock,
3180 const char *signoff_message)
3182 SilcIDListData idata;
3189 SILC_LOG_DEBUG(("Start, sock %p", sock));
3191 idata = silc_packet_get_context(sock);
3195 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3198 /* Cancel active protocols */
3200 if (idata->sconn && idata->sconn->op) {
3201 SILC_LOG_DEBUG(("Abort active protocol"));
3202 silc_async_abort(idata->sconn->op, NULL, NULL);
3204 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3205 ((SilcUnknownEntry)idata)->op) {
3206 SILC_LOG_DEBUG(("Abort active protocol"));
3207 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3211 switch (idata->conn_type) {
3212 case SILC_CONN_CLIENT:
3214 SilcClientEntry client_entry = (SilcClientEntry)idata;
3215 silc_server_free_client_data(server, sock, client_entry, TRUE,
3217 silc_packet_set_context(sock, NULL);
3221 case SILC_CONN_SERVER:
3222 case SILC_CONN_ROUTER:
3224 SilcServerEntry user_data = (SilcServerEntry)idata;
3225 SilcServerEntry backup_router = NULL;
3227 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3230 backup_router = silc_server_backup_get(server, user_data->id);
3232 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3233 backup_router == server->id_entry &&
3234 idata->conn_type != SILC_CONN_ROUTER)
3235 backup_router = NULL;
3237 if (server->server_shutdown || server->backup_noswitch)
3238 backup_router = NULL;
3240 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3241 NULL, NULL, &ip, &port);
3243 /* If this was our primary router connection then we're lost to
3244 the outside world. */
3245 if (server->router == user_data) {
3246 /* Check whether we have a backup router connection */
3247 if (!backup_router || backup_router == user_data) {
3248 if (!server->no_reconnect)
3249 silc_server_create_connections(server);
3250 server->id_entry->router = NULL;
3251 server->router = NULL;
3252 server->standalone = TRUE;
3253 server->backup_primary = FALSE;
3254 backup_router = NULL;
3256 if (server->id_entry != backup_router) {
3257 SILC_LOG_INFO(("New primary router is backup router %s",
3258 backup_router->server_name));
3259 server->id_entry->router = backup_router;
3260 server->router = backup_router;
3261 server->router_connect = time(0);
3262 server->backup_primary = TRUE;
3263 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3265 /* Send START_USE to backup router to indicate we have switched */
3266 silc_server_backup_send_start_use(server,
3267 backup_router->connection,
3270 SILC_LOG_INFO(("We are now new primary router in this cell"));
3271 server->id_entry->router = NULL;
3272 server->router = NULL;
3273 server->standalone = TRUE;
3276 /* We stop here to take a breath */
3279 if (server->backup_router) {
3280 server->server_type = SILC_ROUTER;
3282 /* We'll need to constantly try to reconnect to the primary
3283 router so that we'll see when it comes back online. */
3284 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3285 silc_server_backup_connected,
3289 /* Mark this connection as replaced */
3290 silc_server_backup_replaced_add(server, user_data->id,
3293 } else if (backup_router) {
3294 SILC_LOG_INFO(("Enabling the use of backup router %s",
3295 backup_router->server_name));
3297 /* Mark this connection as replaced */
3298 silc_server_backup_replaced_add(server, user_data->id,
3300 } else if (server->server_type == SILC_SERVER &&
3301 idata->conn_type == SILC_CONN_ROUTER) {
3302 /* Reconnect to the router (backup) */
3303 if (!server->no_reconnect)
3304 silc_server_create_connections(server);
3307 if (user_data->server_name)
3308 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3309 ("Server %s signoff", user_data->server_name));
3311 if (!backup_router) {
3312 /* Remove all servers that are originated from this server, and
3313 remove the clients of those servers too. */
3314 silc_server_remove_servers_by_server(server, user_data, TRUE);
3317 /* Remove the clients that this server owns as they will become
3318 invalid now too. For backup router the server is actually
3319 coming from the primary router, so mark that as the owner
3321 if (server->server_type == SILC_BACKUP_ROUTER &&
3322 sock->type == SILC_CONN_SERVER)
3323 silc_server_remove_clients_by_server(server, server->router,
3327 silc_server_remove_clients_by_server(server, user_data,
3330 /* Remove channels owned by this server */
3331 if (server->server_type == SILC_SERVER)
3332 silc_server_remove_channels_by_server(server, user_data);
3334 /* Enable local server connections that may be disabled */
3335 silc_server_local_servers_toggle_enabled(server, TRUE);
3337 /* Update the client entries of this server to the new backup
3338 router. If we are the backup router we also resolve the real
3339 servers for the clients. After updating is over this also
3340 removes the clients that this server explicitly owns. */
3341 silc_server_update_clients_by_server(server, user_data,
3342 backup_router, TRUE);
3344 /* If we are router and just lost our primary router (now standlaone)
3345 we remove everything that was behind it, since we don't know
3347 if (server->server_type == SILC_ROUTER && server->standalone)
3348 /* Remove all servers that are originated from this server, and
3349 remove the clients of those servers too. */
3350 silc_server_remove_servers_by_server(server, user_data, TRUE);
3352 /* Finally remove the clients that are explicitly owned by this
3353 server. They go down with the server. */
3354 silc_server_remove_clients_by_server(server, user_data,
3357 /* Update our server cache to use the new backup router too. */
3358 silc_server_update_servers_by_server(server, user_data, backup_router);
3359 if (server->server_type == SILC_SERVER)
3360 silc_server_update_channels_by_server(server, user_data,
3363 /* Send notify about primary router going down to local operators */
3364 if (server->backup_router)
3365 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3366 SILC_NOTIFY_TYPE_NONE,
3367 ("%s switched to backup router %s "
3368 "(we are primary router now)",
3369 server->server_name, server->server_name));
3370 else if (server->router)
3371 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3372 SILC_NOTIFY_TYPE_NONE,
3373 ("%s switched to backup router %s",
3374 server->server_name,
3375 server->router->server_name));
3377 server->backup_noswitch = FALSE;
3380 silc_server_connection_free(idata->sconn);
3381 idata->sconn = NULL;
3385 if (idata->conn_type == SILC_CONN_SERVER) {
3386 server->stat.my_servers--;
3387 server->stat.servers--;
3388 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3389 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3390 server->stat.my_routers--;
3391 server->stat.routers--;
3392 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3394 if (server->server_type == SILC_ROUTER)
3395 server->stat.cell_servers--;
3397 /* Free the server entry */
3398 silc_server_backup_del(server, user_data);
3399 silc_server_backup_replaced_del(server, user_data);
3400 silc_idlist_del_data(user_data);
3401 if (!silc_idlist_del_server(server->local_list, user_data))
3402 silc_idlist_del_server(server->global_list, user_data);
3404 if (backup_router && backup_router != server->id_entry) {
3405 /* Announce all of our stuff that was created about 5 minutes ago.
3406 The backup router knows all the other stuff already. */
3407 if (server->server_type == SILC_ROUTER)
3408 silc_server_announce_servers(server, FALSE, time(0) - 300,
3409 backup_router->connection);
3411 /* Announce our clients and channels to the router */
3412 silc_server_announce_clients(server, time(0) - 300,
3413 backup_router->connection);
3414 silc_server_announce_channels(server, time(0) - 300,
3415 backup_router->connection);
3418 silc_packet_set_context(sock, NULL);
3424 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3426 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3429 if (server->router_conn == idata->sconn) {
3430 if (!server->no_reconnect)
3431 silc_server_create_connections(server);
3432 server->router_conn = NULL;
3435 silc_server_connection_free(idata->sconn);
3436 idata->sconn = NULL;
3438 silc_idlist_del_data(idata);
3440 silc_packet_set_context(sock, NULL);
3446 /* Removes client from all channels it has joined. This is used when client
3447 connection is disconnected. If the client on a channel is last, the
3448 channel is removed as well. This sends the SIGNOFF notify types. */
3450 void silc_server_remove_from_channels(SilcServer server,
3451 SilcPacketStream sock,
3452 SilcClientEntry client,
3454 const char *signoff_message,
3458 SilcChannelEntry channel;
3459 SilcChannelClientEntry chl;
3460 SilcHashTableList htl;
3461 SilcBuffer clidp = NULL;
3466 if (notify && !client->id)
3469 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3470 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3473 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3478 /* Remove the client from all channels. The client is removed from
3479 the channels' user list. */
3480 silc_hash_table_list(client->channels, &htl);
3481 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3482 channel = chl->channel;
3484 /* Remove channel if this is last client leaving the channel, unless
3485 the channel is permanent. */
3486 if (server->server_type != SILC_SERVER &&
3487 silc_hash_table_count(channel->user_list) < 2) {
3488 silc_server_channel_delete(server, channel);
3492 silc_hash_table_del(client->channels, channel);
3493 silc_hash_table_del(channel->user_list, client);
3494 channel->user_count--;
3496 /* If there is no global users on the channel anymore mark the channel
3497 as local channel. Do not check if the removed client is local client. */
3498 if (server->server_type == SILC_SERVER && channel->global_users &&
3499 chl->client->router && !silc_server_channel_has_global(channel))
3500 channel->global_users = FALSE;
3502 memset(chl, 'A', sizeof(*chl));
3505 /* Update statistics */
3506 if (SILC_IS_LOCAL(client))
3507 server->stat.my_chanclients--;
3508 if (server->server_type == SILC_ROUTER) {
3509 server->stat.cell_chanclients--;
3510 server->stat.chanclients--;
3513 /* If there is not at least one local user on the channel then we don't
3514 need the channel entry anymore, we can remove it safely, unless the
3515 channel is permanent channel */
3516 if (server->server_type == SILC_SERVER &&
3517 !silc_server_channel_has_local(channel)) {
3518 /* Notify about leaving client if this channel has global users. */
3519 if (notify && channel->global_users)
3520 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3521 SILC_NOTIFY_TYPE_SIGNOFF,
3522 signoff_message ? 2 : 1,
3523 clidp->data, silc_buffer_len(clidp),
3524 signoff_message, signoff_message ?
3525 strlen(signoff_message) : 0);
3527 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3528 silc_server_channel_delete(server, channel);
3532 /* Send notify to channel about client leaving SILC and channel too */
3534 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3535 SILC_NOTIFY_TYPE_SIGNOFF,
3536 signoff_message ? 2 : 1,
3537 clidp->data, silc_buffer_len(clidp),
3538 signoff_message, signoff_message ?
3539 strlen(signoff_message) : 0);
3541 if (killed && clidp) {
3542 /* Remove the client from channel's invite list */
3543 if (channel->invite_list &&
3544 silc_hash_table_count(channel->invite_list)) {
3546 SilcArgumentPayload iargs;
3547 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3548 silc_buffer_len(clidp), 3);
3549 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3550 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3551 silc_buffer_free(ab);
3552 silc_argument_payload_free(iargs);
3556 /* Don't create keys if we are shutting down */
3557 if (server->server_shutdown)
3560 /* Re-generate channel key if needed */
3561 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3562 if (!silc_server_create_channel_key(server, channel, 0))
3565 /* Send the channel key to the channel. The key of course is not sent
3566 to the client who was removed from the channel. */
3567 silc_server_send_channel_key(server, client->connection, channel,
3568 server->server_type == SILC_ROUTER ?
3569 FALSE : !server->standalone);
3573 silc_hash_table_list_reset(&htl);
3575 silc_buffer_free(clidp);
3578 /* Removes client from one channel. This is used for example when client
3579 calls LEAVE command to remove itself from the channel. Returns TRUE
3580 if channel still exists and FALSE if the channel is removed when
3581 last client leaves the channel. If `notify' is FALSE notify messages
3584 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3585 SilcPacketStream sock,
3586 SilcChannelEntry channel,
3587 SilcClientEntry client,
3590 SilcChannelClientEntry chl;
3593 SILC_LOG_DEBUG(("Removing %s from channel %s",
3594 silc_id_render(client->id, SILC_ID_CLIENT),
3595 channel->channel_name));
3597 /* Get the entry to the channel, if this client is not on the channel
3599 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3602 /* Remove channel if this is last client leaving the channel, unless
3603 the channel is permanent. */
3604 if (server->server_type != SILC_SERVER &&
3605 silc_hash_table_count(channel->user_list) < 2) {
3606 silc_server_channel_delete(server, channel);
3610 silc_hash_table_del(client->channels, channel);
3611 silc_hash_table_del(channel->user_list, client);
3612 channel->user_count--;
3614 /* If there is no global users on the channel anymore mark the channel
3615 as local channel. Do not check if the client is local client. */
3616 if (server->server_type == SILC_SERVER && channel->global_users &&
3617 chl->client->router && !silc_server_channel_has_global(channel))
3618 channel->global_users = FALSE;
3620 memset(chl, 'O', sizeof(*chl));
3623 /* Update statistics */
3624 if (SILC_IS_LOCAL(client))
3625 server->stat.my_chanclients--;
3626 if (server->server_type == SILC_ROUTER) {
3627 server->stat.cell_chanclients--;
3628 server->stat.chanclients--;
3631 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3635 /* If there is not at least one local user on the channel then we don't
3636 need the channel entry anymore, we can remove it safely, unless the
3637 channel is permanent channel */
3638 if (server->server_type == SILC_SERVER &&
3639 !silc_server_channel_has_local(channel)) {
3640 /* Notify about leaving client if this channel has global users. */
3641 if (notify && channel->global_users)
3642 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3643 SILC_NOTIFY_TYPE_LEAVE, 1,
3644 clidp->data, silc_buffer_len(clidp));
3646 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3647 silc_server_channel_delete(server, channel);
3648 silc_buffer_free(clidp);
3652 /* Send notify to channel about client leaving the channel */
3654 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3655 SILC_NOTIFY_TYPE_LEAVE, 1,
3656 clidp->data, silc_buffer_len(clidp));
3658 silc_buffer_free(clidp);
3662 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3663 function may be used only by router. In real SILC network all channels
3664 are created by routers thus this function is never used by normal
3667 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3668 SilcServerID *router_id,
3674 SilcChannelID *channel_id;
3675 SilcChannelEntry entry;
3676 SilcCipher send_key, receive_key;
3679 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3682 cipher = SILC_DEFAULT_CIPHER;
3684 hmac = SILC_DEFAULT_HMAC;
3686 /* Allocate cipher */
3687 if (!silc_cipher_alloc(cipher, &send_key))
3689 if (!silc_cipher_alloc(cipher, &receive_key)) {
3690 silc_cipher_free(send_key);
3695 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3696 silc_cipher_free(send_key);
3697 silc_cipher_free(receive_key);
3701 channel_name = strdup(channel_name);
3703 /* Create the channel ID */
3704 if (!silc_id_create_channel_id(server, router_id, server->rng,
3706 silc_free(channel_name);
3707 silc_cipher_free(send_key);
3708 silc_cipher_free(receive_key);
3709 silc_hmac_free(newhmac);
3713 /* Create the channel */
3714 entry = silc_idlist_add_channel(server->local_list, channel_name,
3715 SILC_CHANNEL_MODE_NONE, channel_id,
3716 NULL, send_key, receive_key, newhmac);
3718 silc_free(channel_name);
3719 silc_cipher_free(send_key);
3720 silc_cipher_free(receive_key);
3721 silc_hmac_free(newhmac);
3722 silc_free(channel_id);
3726 entry->cipher = strdup(cipher);
3727 entry->hmac_name = strdup(hmac);
3729 /* Now create the actual key material */
3730 if (!silc_server_create_channel_key(server, entry,
3731 silc_cipher_get_key_len(send_key) / 8)) {
3732 silc_idlist_del_channel(server->local_list, entry);
3736 /* Notify other routers about the new channel. We send the packet
3737 to our primary route. */
3739 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3740 channel_name, entry->id,
3741 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3744 /* Distribute to backup routers */
3745 if (broadcast && server->server_type == SILC_ROUTER) {
3747 unsigned char cid[32];
3748 SilcUInt32 name_len = strlen(channel_name);
3751 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3752 packet = silc_channel_payload_encode(channel_name, name_len,
3753 cid, id_len, entry->mode);
3754 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3755 packet->data, silc_buffer_len(packet), FALSE,
3757 silc_buffer_free(packet);
3760 server->stat.my_channels++;
3761 if (server->server_type == SILC_ROUTER) {
3762 server->stat.channels++;
3763 server->stat.cell_channels++;
3764 entry->users_resolved = TRUE;
3770 /* Same as above but creates the channel with Channel ID `channel_id. */
3773 silc_server_create_new_channel_with_id(SilcServer server,
3777 SilcChannelID *channel_id,
3780 SilcChannelEntry entry;
3781 SilcCipher send_key, receive_key;
3784 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3787 cipher = SILC_DEFAULT_CIPHER;
3789 hmac = SILC_DEFAULT_HMAC;
3791 /* Allocate cipher */
3792 if (!silc_cipher_alloc(cipher, &send_key))
3794 if (!silc_cipher_alloc(cipher, &receive_key)) {
3795 silc_cipher_free(send_key);
3800 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3801 silc_cipher_free(send_key);
3802 silc_cipher_free(receive_key);
3806 channel_name = strdup(channel_name);
3808 /* Create the channel */
3809 entry = silc_idlist_add_channel(server->local_list, channel_name,
3810 SILC_CHANNEL_MODE_NONE, channel_id,
3811 NULL, send_key, receive_key, newhmac);
3813 silc_cipher_free(send_key);
3814 silc_cipher_free(receive_key);
3815 silc_hmac_free(newhmac);
3816 silc_free(channel_name);
3820 /* Now create the actual key material */
3821 if (!silc_server_create_channel_key(server, entry,
3822 silc_cipher_get_key_len(send_key) / 8)) {
3823 silc_idlist_del_channel(server->local_list, entry);
3827 /* Notify other routers about the new channel. We send the packet
3828 to our primary route. */
3830 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3831 channel_name, entry->id,
3832 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3835 /* Distribute to backup routers */
3836 if (broadcast && server->server_type == SILC_ROUTER) {
3838 unsigned char cid[32];
3839 SilcUInt32 name_len = strlen(channel_name);
3842 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3843 packet = silc_channel_payload_encode(channel_name, name_len,
3844 cid, id_len, entry->mode);
3845 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3846 packet->data, silc_buffer_len(packet), FALSE,
3848 silc_buffer_free(packet);
3851 server->stat.my_channels++;
3852 if (server->server_type == SILC_ROUTER) {
3853 server->stat.channels++;
3854 server->stat.cell_channels++;
3855 entry->users_resolved = TRUE;
3861 /* Channel's key re-key timeout callback. */
3863 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3865 SilcServer server = app_context;
3866 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3870 /* Return now if we are shutting down */
3871 if (server->server_shutdown)
3874 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3877 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3880 /* Generates new channel key. This is used to create the initial channel key
3881 but also to re-generate new key for channel. If `key_len' is provided
3882 it is the bytes of the key length. */
3884 SilcBool silc_server_create_channel_key(SilcServer server,
3885 SilcChannelEntry channel,
3889 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3892 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3893 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3897 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3899 if (!channel->send_key)
3900 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3901 channel->send_key = NULL;
3904 if (!channel->receive_key)
3905 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3906 silc_cipher_free(channel->send_key);
3907 channel->send_key = channel->receive_key = NULL;
3913 else if (channel->key_len)
3914 len = channel->key_len / 8;
3916 len = silc_cipher_get_key_len(channel->send_key) / 8;
3918 /* Create channel key */
3919 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3922 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3923 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3925 /* Remove old key if exists */
3927 memset(channel->key, 0, channel->key_len / 8);
3928 silc_free(channel->key);
3932 channel->key_len = len * 8;
3933 channel->key = silc_memdup(channel_key, len);
3934 memset(channel_key, 0, sizeof(channel_key));
3936 /* Generate HMAC key from the channel key data and set it */
3938 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3939 memset(channel->key, 0, channel->key_len / 8);
3940 silc_free(channel->key);
3941 silc_cipher_free(channel->send_key);
3942 silc_cipher_free(channel->receive_key);
3943 channel->send_key = channel->receive_key = NULL;
3946 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3947 silc_hmac_set_key(channel->hmac, hash,
3948 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3949 memset(hash, 0, sizeof(hash));
3951 if (server->server_type == SILC_ROUTER) {
3952 if (!channel->rekey)
3953 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3954 channel->rekey->channel = channel;
3955 channel->rekey->key_len = key_len;
3956 if (channel->rekey->task)
3957 silc_schedule_task_del(server->schedule, channel->rekey->task);
3959 channel->rekey->task =
3960 silc_schedule_task_add_timeout(server->schedule,
3961 silc_server_channel_key_rekey,
3962 (void *)channel->rekey,
3963 server->config->channel_rekey_secs, 0);
3969 /* Saves the channel key found in the encoded `key_payload' buffer. This
3970 function is used when we receive Channel Key Payload and also when we're
3971 processing JOIN command reply. Returns entry to the channel. */
3973 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3974 SilcBuffer key_payload,
3975 SilcChannelEntry channel)
3977 SilcChannelKeyPayload payload = NULL;
3979 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3983 /* Decode channel key payload */
3984 payload = silc_channel_key_payload_parse(key_payload->data,
3985 silc_buffer_len(key_payload));
3987 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3992 /* Get the channel entry */
3995 /* Get channel ID */
3996 tmp = silc_channel_key_get_id(payload, &tmp_len);
3997 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4002 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4004 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4006 if (server->server_type == SILC_ROUTER)
4007 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4008 silc_id_render(&id, SILC_ID_CHANNEL)));
4014 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4016 tmp = silc_channel_key_get_key(payload, &tmp_len);
4022 cipher = silc_channel_key_get_cipher(payload, NULL);
4028 /* Remove old key if exists */
4030 memset(channel->key, 0, channel->key_len / 8);
4031 silc_free(channel->key);
4032 silc_cipher_free(channel->send_key);
4033 silc_cipher_free(channel->receive_key);
4036 /* Create new cipher */
4037 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4038 channel->send_key = NULL;
4042 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4043 silc_cipher_free(channel->send_key);
4044 channel->send_key = channel->receive_key = NULL;
4049 if (channel->cipher)
4050 silc_free(channel->cipher);
4051 channel->cipher = strdup(cipher);
4054 channel->key_len = tmp_len * 8;
4055 channel->key = silc_memdup(tmp, tmp_len);
4056 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4057 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4059 /* Generate HMAC key from the channel key data and set it */
4061 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4062 memset(channel->key, 0, channel->key_len / 8);
4063 silc_free(channel->key);
4064 silc_cipher_free(channel->send_key);
4065 silc_cipher_free(channel->receive_key);
4066 channel->send_key = channel->receive_key = NULL;
4069 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4070 silc_hmac_set_key(channel->hmac, hash,
4071 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4073 memset(hash, 0, sizeof(hash));
4074 memset(tmp, 0, tmp_len);
4076 if (server->server_type == SILC_ROUTER) {
4077 if (!channel->rekey)
4078 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4079 channel->rekey->channel = channel;
4080 if (channel->rekey->task)
4081 silc_schedule_task_del(server->schedule, channel->rekey->task);
4083 channel->rekey->task =
4084 silc_schedule_task_add_timeout(server->schedule,
4085 silc_server_channel_key_rekey,
4086 (void *)channel->rekey,
4087 server->config->channel_rekey_secs, 0);
4092 silc_channel_key_payload_free(payload);
4097 /* Returns assembled of all servers in the given ID list. The packet's
4098 form is dictated by the New ID payload. */
4100 static void silc_server_announce_get_servers(SilcServer server,
4101 SilcServerEntry remote,
4103 SilcBuffer *servers,
4104 unsigned long creation_time)
4107 SilcIDCacheEntry id_cache;
4108 SilcServerEntry entry;
4112 /* Go through all clients in the list */
4113 if (silc_idcache_get_all(id_list->servers, &list)) {
4114 silc_list_start(list);
4115 while ((id_cache = silc_list_get(list))) {
4116 entry = (SilcServerEntry)id_cache->context;
4118 /* Do not announce the one we've sending our announcements and
4119 do not announce ourself. Also check the creation time if it's
4121 if ((entry == remote) || (entry == server->id_entry) ||
4122 (creation_time && entry->data.created < creation_time))
4125 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4127 tmp = silc_buffer_realloc(*servers,
4129 silc_buffer_truelen((*servers)) +
4130 silc_buffer_len(idp) :
4131 silc_buffer_len(idp)));
4135 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4136 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4137 silc_buffer_pull(*servers, silc_buffer_len(idp));
4138 silc_buffer_free(idp);
4144 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4150 p = silc_notify_payload_encode(notify, argc, ap);
4156 /* This function is used by router to announce existing servers to our
4157 primary router when we've connected to it. If `creation_time' is non-zero
4158 then only the servers that has been created after the `creation_time'
4159 will be announced. */
4161 void silc_server_announce_servers(SilcServer server, SilcBool global,
4162 unsigned long creation_time,
4163 SilcPacketStream remote)
4165 SilcBuffer servers = NULL;
4167 SILC_LOG_DEBUG(("Announcing servers"));
4169 /* Get servers in local list */
4170 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4171 server->local_list, &servers,
4175 /* Get servers in global list */
4176 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4177 server->global_list, &servers,
4181 silc_buffer_push(servers, servers->data - servers->head);
4182 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4184 /* Send the packet */
4185 silc_server_packet_send(server, remote,
4186 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4187 servers->data, silc_buffer_len(servers));
4189 silc_buffer_free(servers);
4193 /* Returns assembled packet of all clients in the given ID list. The
4194 packet's form is dictated by the New ID Payload. */
4196 static void silc_server_announce_get_clients(SilcServer server,
4198 SilcBuffer *clients,
4200 unsigned long creation_time)
4203 SilcIDCacheEntry id_cache;
4204 SilcClientEntry client;
4207 unsigned char mode[4];
4210 /* Go through all clients in the list */
4211 if (silc_idcache_get_all(id_list->clients, &list)) {
4212 silc_list_start(list);
4213 while ((id_cache = silc_list_get(list))) {
4214 client = (SilcClientEntry)id_cache->context;
4216 if (creation_time && client->data.created < creation_time)
4218 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4220 if (!client->connection && !client->router)
4223 SILC_LOG_DEBUG(("Announce Client ID %s",
4224 silc_id_render(client->id, SILC_ID_CLIENT)));
4226 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4230 tmp2 = silc_buffer_realloc(*clients,
4232 silc_buffer_truelen((*clients)) +
4233 silc_buffer_len(idp) :
4234 silc_buffer_len(idp)));
4238 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4239 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4240 silc_buffer_pull(*clients, silc_buffer_len(idp));
4242 SILC_PUT32_MSB(client->mode, mode);
4244 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4245 2, idp->data, silc_buffer_len(idp),
4247 tmp2 = silc_buffer_realloc(*umodes,
4249 silc_buffer_truelen((*umodes)) +
4250 silc_buffer_len(tmp) :
4251 silc_buffer_len(tmp)));
4255 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4256 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4257 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4258 silc_buffer_free(tmp);
4260 silc_buffer_free(idp);
4265 /* This function is used to announce our existing clients to our router
4266 when we've connected to it. If `creation_time' is non-zero then only
4267 the clients that has been created after the `creation_time' will be
4270 void silc_server_announce_clients(SilcServer server,
4271 unsigned long creation_time,
4272 SilcPacketStream remote)
4274 SilcBuffer clients = NULL;
4275 SilcBuffer umodes = NULL;
4277 SILC_LOG_DEBUG(("Announcing clients"));
4279 /* Get clients in local list */
4280 silc_server_announce_get_clients(server, server->local_list,
4281 &clients, &umodes, creation_time);
4283 /* As router we announce our global list as well */
4284 if (server->server_type == SILC_ROUTER)
4285 silc_server_announce_get_clients(server, server->global_list,
4286 &clients, &umodes, creation_time);
4289 silc_buffer_push(clients, clients->data - clients->head);
4290 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4292 /* Send the packet */
4293 silc_server_packet_send(server, remote,
4294 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4295 clients->data, silc_buffer_len(clients));
4297 silc_buffer_free(clients);
4301 silc_buffer_push(umodes, umodes->data - umodes->head);
4302 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4304 /* Send the packet */
4305 silc_server_packet_send(server, remote,
4306 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4307 umodes->data, silc_buffer_len(umodes));
4309 silc_buffer_free(umodes);
4313 /* Returns channel's topic for announcing it */
4315 void silc_server_announce_get_channel_topic(SilcServer server,
4316 SilcChannelEntry channel,
4321 if (channel->topic) {
4322 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4323 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4325 silc_buffer_len(chidp),
4327 strlen(channel->topic));
4328 silc_buffer_free(chidp);
4332 /* Returns channel's invite and ban lists */
4334 void silc_server_announce_get_inviteban(SilcServer server,
4335 SilcChannelEntry channel,
4339 SilcBuffer list, idp, idp2, tmp2;
4342 SilcHashTableList htl;
4343 const unsigned char a[1] = { 0x03 };
4345 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4347 /* Encode invite list */
4348 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4349 list = silc_buffer_alloc_size(2);
4350 type = silc_hash_table_count(channel->invite_list);
4351 SILC_PUT16_MSB(type, list->data);
4352 silc_hash_table_list(channel->invite_list, &htl);
4353 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4354 list = silc_argument_payload_encode_one(list, tmp2->data,
4355 silc_buffer_len(tmp2),
4356 SILC_PTR_TO_32(ptype));
4357 silc_hash_table_list_reset(&htl);
4359 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4361 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4362 idp->data, silc_buffer_len(idp),
4363 channel->channel_name,
4364 strlen(channel->channel_name),
4365 idp2->data, silc_buffer_len(idp2),
4367 list->data, silc_buffer_len(list));
4368 silc_buffer_free(idp2);
4369 silc_buffer_free(list);
4372 /* Encode ban list */
4373 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4374 list = silc_buffer_alloc_size(2);
4375 type = silc_hash_table_count(channel->ban_list);
4376 SILC_PUT16_MSB(type, list->data);
4377 silc_hash_table_list(channel->ban_list, &htl);
4378 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4379 list = silc_argument_payload_encode_one(list, tmp2->data,
4380 silc_buffer_len(tmp2),
4381 SILC_PTR_TO_32(ptype));
4382 silc_hash_table_list_reset(&htl);
4385 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4386 idp->data, silc_buffer_len(idp),
4388 list->data, silc_buffer_len(list));
4389 silc_buffer_free(list);
4392 silc_buffer_free(idp);
4395 /* Returns assembled packets for channel users of the `channel'. */
4397 void silc_server_announce_get_channel_users(SilcServer server,
4398 SilcChannelEntry channel,
4399 SilcBuffer *channel_modes,
4400 SilcBuffer *channel_users,
4401 SilcBuffer *channel_users_modes)
4403 SilcChannelClientEntry chl;
4404 SilcHashTableList htl;
4405 SilcBuffer chidp, clidp, csidp;
4406 SilcBuffer tmp, fkey = NULL, chpklist;
4408 unsigned char mode[4], ulimit[4];
4412 SILC_LOG_DEBUG(("Start"));
4414 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4415 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4416 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4419 SILC_PUT32_MSB(channel->mode, mode);
4420 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4421 SILC_PUT32_MSB(channel->user_limit, ulimit);
4422 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4423 if (channel->founder_key)
4424 fkey = silc_public_key_payload_encode(channel->founder_key);
4426 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4428 silc_buffer_len(csidp),
4431 hmac, hmac ? strlen(hmac) : 0,
4432 channel->passphrase,
4433 channel->passphrase ?
4434 strlen(channel->passphrase) : 0,
4435 fkey ? fkey->data : NULL,
4436 fkey ? silc_buffer_len(fkey) : 0,
4437 chpklist ? chpklist->data : NULL,
4439 silc_buffer_len(chpklist) : 0,
4441 SILC_CHANNEL_MODE_ULIMIT ?
4444 SILC_CHANNEL_MODE_ULIMIT ?
4445 sizeof(ulimit) : 0));
4446 len = silc_buffer_len(tmp);
4448 silc_buffer_realloc(*channel_modes,
4450 silc_buffer_truelen((*channel_modes)) + len : len));
4453 *channel_modes = tmp2;
4454 silc_buffer_pull_tail(*channel_modes,
4455 ((*channel_modes)->end -
4456 (*channel_modes)->data));
4457 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4458 silc_buffer_pull(*channel_modes, len);
4459 silc_buffer_free(tmp);
4460 silc_buffer_free(fkey);
4463 /* Now find all users on the channel */
4464 silc_hash_table_list(channel->user_list, &htl);
4465 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4466 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4468 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4472 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4474 silc_buffer_len(clidp),
4476 silc_buffer_len(chidp));
4477 len = silc_buffer_len(tmp);
4479 silc_buffer_realloc(*channel_users,
4481 silc_buffer_truelen((*channel_users)) + len : len));
4484 *channel_users = tmp2;
4485 silc_buffer_pull_tail(*channel_users,
4486 ((*channel_users)->end -
4487 (*channel_users)->data));
4489 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4490 silc_buffer_pull(*channel_users, len);
4491 silc_buffer_free(tmp);
4493 /* CUMODE notify for mode change on the channel */
4494 SILC_PUT32_MSB(chl->mode, mode);
4495 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4496 fkey = silc_public_key_payload_encode(channel->founder_key);
4497 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4499 silc_buffer_len(csidp),
4502 silc_buffer_len(clidp),
4503 fkey ? fkey->data : NULL,
4504 fkey ? silc_buffer_len(fkey) : 0);
4505 len = silc_buffer_len(tmp);
4507 silc_buffer_realloc(*channel_users_modes,
4508 (*channel_users_modes ?
4509 silc_buffer_truelen((*channel_users_modes)) +
4513 *channel_users_modes = tmp2;
4514 silc_buffer_pull_tail(*channel_users_modes,
4515 ((*channel_users_modes)->end -
4516 (*channel_users_modes)->data));
4518 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4519 silc_buffer_pull(*channel_users_modes, len);
4520 silc_buffer_free(tmp);
4521 silc_buffer_free(fkey);
4523 silc_buffer_free(clidp);
4525 silc_hash_table_list_reset(&htl);
4526 silc_buffer_free(chidp);
4527 silc_buffer_free(csidp);
4530 /* Returns assembled packets for all channels and users on those channels
4531 from the given ID List. The packets are in the form dictated by the
4532 New Channel and New Channel User payloads. */
4534 void silc_server_announce_get_channels(SilcServer server,
4536 SilcBuffer *channels,
4537 SilcBuffer **channel_modes,
4538 SilcBuffer *channel_users,
4539 SilcBuffer **channel_users_modes,
4540 SilcUInt32 *channel_users_modes_c,
4541 SilcBuffer **channel_topics,
4542 SilcBuffer **channel_invites,
4543 SilcBuffer **channel_bans,
4544 SilcChannelID ***channel_ids,
4545 unsigned long creation_time)
4548 SilcIDCacheEntry id_cache;
4549 SilcChannelEntry channel;
4550 unsigned char cid[32];
4552 SilcUInt16 name_len;
4554 int i = *channel_users_modes_c;
4558 SILC_LOG_DEBUG(("Start"));
4560 /* Go through all channels in the list */
4561 if (silc_idcache_get_all(id_list->channels, &list)) {
4562 silc_list_start(list);
4563 while ((id_cache = silc_list_get(list))) {
4564 channel = (SilcChannelEntry)id_cache->context;
4566 if (creation_time && channel->created < creation_time)
4571 SILC_LOG_DEBUG(("Announce Channel ID %s",
4572 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4574 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4575 name_len = strlen(channel->channel_name);
4578 len = 4 + name_len + id_len + 4;
4580 silc_buffer_realloc(*channels,
4582 silc_buffer_truelen((*channels)) +
4588 silc_buffer_pull_tail(*channels,
4589 ((*channels)->end - (*channels)->data));
4590 silc_buffer_format(*channels,
4591 SILC_STR_UI_SHORT(name_len),
4592 SILC_STR_UI_XNSTRING(channel->channel_name,
4594 SILC_STR_UI_SHORT(id_len),
4595 SILC_STR_UI_XNSTRING(cid, id_len),
4596 SILC_STR_UI_INT(channel->mode),
4598 silc_buffer_pull(*channels, len);
4601 if (creation_time && channel->updated < creation_time)
4607 /* Channel user modes */
4608 tmp = silc_realloc(*channel_users_modes,
4609 sizeof(**channel_users_modes) * (i + 1));
4612 *channel_users_modes = tmp;
4613 (*channel_users_modes)[i] = NULL;
4614 tmp = silc_realloc(*channel_modes,
4615 sizeof(**channel_modes) * (i + 1));
4618 *channel_modes = tmp;
4619 (*channel_modes)[i] = NULL;
4620 tmp = silc_realloc(*channel_ids,
4621 sizeof(**channel_ids) * (i + 1));
4625 (*channel_ids)[i] = NULL;
4626 silc_server_announce_get_channel_users(server, channel,
4627 &(*channel_modes)[i],
4629 &(*channel_users_modes)[i]);
4630 (*channel_ids)[i] = channel->id;
4632 /* Channel's topic */
4633 tmp = silc_realloc(*channel_topics,
4634 sizeof(**channel_topics) * (i + 1));
4637 *channel_topics = tmp;
4638 (*channel_topics)[i] = NULL;
4639 silc_server_announce_get_channel_topic(server, channel,
4640 &(*channel_topics)[i]);
4642 /* Channel's invite and ban list */
4643 tmp = silc_realloc(*channel_invites,
4644 sizeof(**channel_invites) * (i + 1));
4647 *channel_invites = tmp;
4648 (*channel_invites)[i] = NULL;
4649 tmp = silc_realloc(*channel_bans,
4650 sizeof(**channel_bans) * (i + 1));
4653 *channel_bans = tmp;
4654 (*channel_bans)[i] = NULL;
4655 silc_server_announce_get_inviteban(server, channel,
4656 &(*channel_invites)[i],
4657 &(*channel_bans)[i]);
4659 (*channel_users_modes_c)++;
4667 /* This function is used to announce our existing channels to our router
4668 when we've connected to it. This also announces the users on the
4669 channels to the router. If the `creation_time' is non-zero only the
4670 channels that was created after the `creation_time' are announced.
4671 Note that the channel users are still announced even if the `creation_time'
4674 void silc_server_announce_channels(SilcServer server,
4675 unsigned long creation_time,
4676 SilcPacketStream remote)
4678 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4679 SilcBuffer *channel_users_modes = NULL;
4680 SilcBuffer *channel_topics = NULL;
4681 SilcBuffer *channel_invites = NULL;
4682 SilcBuffer *channel_bans = NULL;
4683 SilcUInt32 channel_users_modes_c = 0;
4684 SilcChannelID **channel_ids = NULL;
4686 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4688 /* Get channels and channel users in local list */
4689 silc_server_announce_get_channels(server, server->local_list,
4690 &channels, &channel_modes,
4692 &channel_users_modes,
4693 &channel_users_modes_c,
4697 &channel_ids, creation_time);
4699 /* Get channels and channel users in global list */
4700 if (server->server_type != SILC_SERVER)
4701 silc_server_announce_get_channels(server, server->global_list,
4702 &channels, &channel_modes,
4704 &channel_users_modes,
4705 &channel_users_modes_c,
4709 &channel_ids, creation_time);
4712 silc_buffer_push(channels, channels->data - channels->head);
4713 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4715 /* Send the packet */
4716 silc_server_packet_send(server, remote,
4717 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4718 channels->data, silc_buffer_len(channels));
4720 silc_buffer_free(channels);
4723 if (channel_users) {
4724 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4725 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4726 silc_buffer_len(channel_users));
4728 /* Send the packet */
4729 silc_server_packet_send(server, remote,
4730 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4731 channel_users->data, silc_buffer_len(channel_users));
4733 silc_buffer_free(channel_users);
4736 if (channel_modes) {
4739 for (i = 0; i < channel_users_modes_c; i++) {
4740 if (!channel_modes[i])
4742 silc_buffer_push(channel_modes[i],
4743 channel_modes[i]->data -
4744 channel_modes[i]->head);
4745 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4746 silc_buffer_len(channel_modes[i]));
4747 silc_server_packet_send_dest(server, remote,
4748 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4749 channel_ids[i], SILC_ID_CHANNEL,
4750 channel_modes[i]->data,
4751 silc_buffer_len(channel_modes[i]));
4752 silc_buffer_free(channel_modes[i]);
4754 silc_free(channel_modes);
4757 if (channel_users_modes) {
4760 for (i = 0; i < channel_users_modes_c; i++) {
4761 if (!channel_users_modes[i])
4763 silc_buffer_push(channel_users_modes[i],
4764 channel_users_modes[i]->data -
4765 channel_users_modes[i]->head);
4766 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4767 silc_buffer_len(channel_users_modes[i]));
4768 silc_server_packet_send_dest(server, remote,
4769 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4770 channel_ids[i], SILC_ID_CHANNEL,
4771 channel_users_modes[i]->data,
4772 silc_buffer_len(channel_users_modes[i]));
4773 silc_buffer_free(channel_users_modes[i]);
4775 silc_free(channel_users_modes);
4778 if (channel_topics) {
4781 for (i = 0; i < channel_users_modes_c; i++) {
4782 if (!channel_topics[i])
4785 silc_buffer_push(channel_topics[i],
4786 channel_topics[i]->data -
4787 channel_topics[i]->head);
4788 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4789 silc_buffer_len(channel_topics[i]));
4790 silc_server_packet_send_dest(server, remote,
4791 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4792 channel_ids[i], SILC_ID_CHANNEL,
4793 channel_topics[i]->data,
4794 silc_buffer_len(channel_topics[i]));
4795 silc_buffer_free(channel_topics[i]);
4797 silc_free(channel_topics);
4800 if (channel_invites) {
4803 for (i = 0; i < channel_users_modes_c; i++) {
4804 if (!channel_invites[i])
4807 silc_buffer_push(channel_invites[i],
4808 channel_invites[i]->data -
4809 channel_invites[i]->head);
4810 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4811 silc_buffer_len(channel_invites[i]));
4812 silc_server_packet_send_dest(server, remote,
4813 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4814 channel_ids[i], SILC_ID_CHANNEL,
4815 channel_invites[i]->data,
4816 silc_buffer_len(channel_invites[i]));
4817 silc_buffer_free(channel_invites[i]);
4819 silc_free(channel_invites);
4825 for (i = 0; i < channel_users_modes_c; i++) {
4826 if (!channel_bans[i])
4829 silc_buffer_push(channel_bans[i],
4830 channel_bans[i]->data -
4831 channel_bans[i]->head);
4832 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4833 silc_buffer_len(channel_bans[i]));
4834 silc_server_packet_send_dest(server, remote,
4835 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4836 channel_ids[i], SILC_ID_CHANNEL,
4837 channel_bans[i]->data,
4838 silc_buffer_len(channel_bans[i]));
4839 silc_buffer_free(channel_bans[i]);
4841 silc_free(channel_bans);
4844 silc_free(channel_ids);
4847 /* Announces WATCH list. */
4849 void silc_server_announce_watches(SilcServer server,
4850 SilcPacketStream remote)
4852 SilcHashTableList htl;
4853 SilcBuffer buffer, idp, args, pkp;
4854 SilcClientEntry client;
4857 SILC_LOG_DEBUG(("Announcing watch list"));
4859 /* XXX because way we save the nicks (hash) we cannot announce them. */
4861 /* XXX we should send all public keys in one command if client is
4862 watching more than one key */
4863 silc_hash_table_list(server->watcher_list_pk, &htl);
4864 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4865 if (!client || !client->id)
4868 server->stat.commands_sent++;
4870 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4871 args = silc_buffer_alloc_size(2);
4872 silc_buffer_format(args,
4873 SILC_STR_UI_SHORT(1),
4875 pkp = silc_public_key_payload_encode(key);
4876 args = silc_argument_payload_encode_one(args, pkp->data,
4877 silc_buffer_len(pkp), 0x00);
4878 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4879 ++server->cmd_ident, 2,
4880 1, idp->data, silc_buffer_len(idp),
4882 silc_buffer_len(args));
4885 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4886 buffer->data, silc_buffer_len(buffer));
4888 silc_buffer_free(pkp);
4889 silc_buffer_free(args);
4890 silc_buffer_free(idp);
4891 silc_buffer_free(buffer);
4893 silc_hash_table_list_reset(&htl);
4896 /* Assembles user list and users mode list from the `channel'. */
4898 SilcBool silc_server_get_users_on_channel(SilcServer server,
4899 SilcChannelEntry channel,
4900 SilcBuffer *user_list,
4901 SilcBuffer *mode_list,
4902 SilcUInt32 *user_count)
4904 SilcChannelClientEntry chl;
4905 SilcHashTableList htl;
4906 SilcBuffer client_id_list;
4907 SilcBuffer client_mode_list;
4909 SilcUInt32 list_count = 0, len = 0;
4911 if (!silc_hash_table_count(channel->user_list))
4914 silc_hash_table_list(channel->user_list, &htl);
4915 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4916 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4917 silc_hash_table_list_reset(&htl);
4919 client_id_list = silc_buffer_alloc(len);
4921 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4922 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4923 silc_buffer_pull_tail(client_mode_list,
4924 silc_buffer_truelen(client_mode_list));
4926 silc_hash_table_list(channel->user_list, &htl);
4927 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4929 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4930 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4931 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4932 silc_buffer_free(idp);
4934 /* Client's mode on channel */
4935 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4936 silc_buffer_pull(client_mode_list, 4);
4940 silc_hash_table_list_reset(&htl);
4941 silc_buffer_push(client_id_list,
4942 client_id_list->data - client_id_list->head);
4943 silc_buffer_push(client_mode_list,
4944 client_mode_list->data - client_mode_list->head);
4946 *user_list = client_id_list;
4947 *mode_list = client_mode_list;
4948 *user_count = list_count;
4952 /* Saves users and their modes to the `channel'. */
4954 void silc_server_save_users_on_channel(SilcServer server,
4955 SilcPacketStream sock,
4956 SilcChannelEntry channel,
4957 SilcClientID *noadd,
4958 SilcBuffer user_list,
4959 SilcBuffer mode_list,
4960 SilcUInt32 user_count)
4966 SilcClientEntry client;
4967 SilcIDCacheEntry cache;
4968 SilcChannelClientEntry chl;
4970 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4971 channel->channel_name));
4973 for (i = 0; i < user_count; i++) {
4975 SILC_GET16_MSB(idp_len, user_list->data + 2);
4977 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4979 silc_buffer_pull(user_list, idp_len);
4982 SILC_GET32_MSB(mode, mode_list->data);
4983 silc_buffer_pull(mode_list, 4);
4985 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4990 /* Check if we have this client cached already. */
4991 client = silc_idlist_find_client_by_id(server->local_list,
4993 server->server_type, &cache);
4995 client = silc_idlist_find_client_by_id(server->global_list,
4997 server->server_type, &cache);
4999 /* If router did not find such Client ID in its lists then this must
5000 be bogus client or some router in the net is buggy. */
5001 if (server->server_type != SILC_SERVER)
5004 /* We don't have that client anywhere, add it. The client is added
5005 to global list since server didn't have it in the lists so it must be
5007 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5008 silc_id_dup(&id.u.client_id,
5010 silc_packet_get_context(sock),
5013 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5017 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5020 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5021 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5022 "%s", channel->channel_name));
5026 if (!silc_server_client_on_channel(client, channel, &chl)) {
5027 /* Client was not on the channel, add it. */
5028 chl = silc_calloc(1, sizeof(*chl));
5029 chl->client = client;
5031 chl->channel = channel;
5032 silc_hash_table_add(channel->user_list, chl->client, chl);
5033 silc_hash_table_add(client->channels, chl->channel, chl);
5034 channel->user_count++;
5042 /* Saves channels and channels user modes to the `client'. Removes
5043 the client from those channels that are not sent in the list but
5046 void silc_server_save_user_channels(SilcServer server,
5047 SilcPacketStream sock,
5048 SilcClientEntry client,
5049 SilcBuffer channels,
5050 SilcBuffer channels_user_modes)
5053 SilcUInt32 *chumodes;
5054 SilcChannelPayload entry;
5055 SilcChannelEntry channel;
5056 SilcChannelID channel_id;
5057 SilcChannelClientEntry chl;
5058 SilcHashTable ht = NULL;
5059 SilcHashTableList htl;
5063 if (!channels || !channels_user_modes ||
5064 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5067 ch = silc_channel_payload_parse_list(channels->data,
5068 silc_buffer_len(channels));
5069 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5071 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5072 NULL, NULL, NULL, TRUE);
5073 silc_dlist_start(ch);
5074 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5075 /* Check if we have this channel, and add it if we don't have it.
5076 Also add the client on the channel unless it is there already. */
5077 if (!silc_channel_get_id_parse(entry, &channel_id))
5079 channel = silc_idlist_find_channel_by_id(server->local_list,
5082 channel = silc_idlist_find_channel_by_id(server->global_list,
5085 if (server->server_type != SILC_SERVER) {
5090 /* We don't have that channel anywhere, add it. */
5091 name = silc_channel_get_name(entry, NULL);
5092 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5093 silc_id_dup(&channel_id,
5095 server->router, NULL, NULL, 0);
5102 channel->mode = silc_channel_get_mode(entry);
5104 /* Add the client on the channel */
5105 if (!silc_server_client_on_channel(client, channel, &chl)) {
5106 chl = silc_calloc(1, sizeof(*chl));
5107 chl->client = client;
5108 chl->mode = chumodes[i++];
5109 chl->channel = channel;
5110 silc_hash_table_add(channel->user_list, chl->client, chl);
5111 silc_hash_table_add(client->channels, chl->channel, chl);
5112 channel->user_count++;
5115 chl->mode = chumodes[i++];
5118 silc_hash_table_add(ht, channel, channel);
5120 silc_channel_payload_list_free(ch);
5121 silc_free(chumodes);
5125 /* Go through the list again and remove client from channels that
5126 are no part of the list. */
5128 silc_hash_table_list(client->channels, &htl);
5129 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5130 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5131 silc_hash_table_del(chl->channel->user_list, chl->client);
5132 silc_hash_table_del(chl->client->channels, chl->channel);
5136 silc_hash_table_list_reset(&htl);
5137 silc_hash_table_free(ht);
5139 silc_hash_table_list(client->channels, &htl);
5140 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5141 silc_hash_table_del(chl->channel->user_list, chl->client);
5142 silc_hash_table_del(chl->client->channels, chl->channel);
5145 silc_hash_table_list_reset(&htl);
5149 /* Lookups route to the client indicated by the `id_data'. The connection
5150 object and internal data object is returned. Returns NULL if route
5151 could not be found to the client. If the `client_id' is specified then
5152 it is used and the `id_data' is ignored. */
5155 silc_server_get_client_route(SilcServer server,
5156 unsigned char *id_data,
5158 SilcClientID *client_id,
5159 SilcIDListData *idata,
5160 SilcClientEntry *client_entry)
5162 SilcClientID *id, clid;
5163 SilcClientEntry client;
5165 SILC_LOG_DEBUG(("Start"));
5168 *client_entry = NULL;
5170 /* Decode destination Client ID */
5172 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5174 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5176 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5179 /* If the destination belongs to our server we don't have to route
5180 the packet anywhere but to send it to the local destination. */
5181 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5185 /* If we are router and the client has router then the client is in
5186 our cell but not directly connected to us. */
5187 if (server->server_type == SILC_ROUTER && client->router) {
5188 /* We are of course in this case the client's router thus the route
5189 to the client is the server who owns the client. So, we will send
5190 the packet to that server. */
5192 *idata = (SilcIDListData)client->router;
5193 return client->router->connection;
5196 /* Seems that client really is directly connected to us */
5198 *idata = (SilcIDListData)client;
5200 *client_entry = client;
5201 return client->connection;
5204 /* Destination belongs to someone not in this server. If we are normal
5205 server our action is to send the packet to our router. */
5206 if (server->server_type != SILC_ROUTER && !server->standalone) {
5209 *idata = (SilcIDListData)server->router;
5210 return SILC_PRIMARY_ROUTE(server);
5213 /* We are router and we will perform route lookup for the destination
5214 and send the packet to fastest route. */
5215 if (server->server_type == SILC_ROUTER && !server->standalone) {
5216 /* Check first that the ID is valid */
5217 client = silc_idlist_find_client_by_id(server->global_list, id,
5220 SilcPacketStream dst_sock;
5222 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5225 if (idata && dst_sock)
5226 *idata = silc_packet_get_context(dst_sock);
5235 /* Encodes and returns channel list of channels the `client' has joined.
5236 Secret channels are not put to the list. */
5238 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5239 SilcClientEntry client,
5240 SilcBool get_private,
5241 SilcBool get_secret,
5242 SilcBuffer *user_mode_list)
5244 SilcBuffer buffer = NULL;
5245 SilcChannelEntry channel;
5246 SilcChannelClientEntry chl;
5247 SilcHashTableList htl;
5248 unsigned char cid[32];
5250 SilcUInt16 name_len;
5254 *user_mode_list = NULL;
5256 silc_hash_table_list(client->channels, &htl);
5257 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5258 channel = chl->channel;
5260 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5262 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5265 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5266 name_len = strlen(channel->channel_name);
5268 len = 4 + name_len + id_len + 4;
5269 buffer = silc_buffer_realloc(buffer,
5271 silc_buffer_truelen(buffer) + len : len));
5272 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5273 silc_buffer_format(buffer,
5274 SILC_STR_UI_SHORT(name_len),
5275 SILC_STR_DATA(channel->channel_name, name_len),
5276 SILC_STR_UI_SHORT(id_len),
5277 SILC_STR_DATA(cid, id_len),
5278 SILC_STR_UI_INT(chl->channel->mode),
5280 silc_buffer_pull(buffer, len);
5282 if (user_mode_list) {
5284 silc_buffer_realloc(*user_mode_list,
5286 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5287 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5288 (*user_mode_list)->data));
5289 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5290 silc_buffer_pull(*user_mode_list, 4);
5293 silc_hash_table_list_reset(&htl);
5296 silc_buffer_push(buffer, buffer->data - buffer->head);
5297 if (user_mode_list && *user_mode_list)
5298 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5299 (*user_mode_list)->head));
5304 /* Task callback used to retrieve network statistical information from
5305 router server once in a while. */
5307 SILC_TASK_CALLBACK(silc_server_get_stats)
5309 SilcServer server = (SilcServer)context;
5310 SilcBuffer idp, packet;
5312 if (!server->standalone) {
5313 SILC_LOG_DEBUG(("Retrieving stats from router"));
5314 server->stat.commands_sent++;
5315 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5317 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5318 ++server->cmd_ident, 1,
5320 silc_buffer_len(idp));
5321 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5322 SILC_PACKET_COMMAND, 0, packet->data,
5323 silc_buffer_len(packet));
5324 silc_buffer_free(packet);
5325 silc_buffer_free(idp);
5329 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,