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 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
2349 server->stat.clients + 1));
2350 server->stat.my_clients++;
2351 server->stat.clients++;
2352 server->stat.cell_clients++;
2354 /* Get connection parameters */
2356 param = conn->param;
2358 if (!param->keepalive_secs)
2359 param->keepalive_secs = server->config->param.keepalive_secs;
2361 if (!param->qos && server->config->param.qos) {
2362 param->qos = server->config->param.qos;
2363 param->qos_rate_limit = server->config->param.qos_rate_limit;
2364 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2365 param->qos_limit_sec = server->config->param.qos_limit_sec;
2366 param->qos_limit_usec = server->config->param.qos_limit_usec;
2369 /* Check if to be anonymous connection */
2370 if (param->anonymous)
2371 client->mode |= SILC_UMODE_ANONYMOUS;
2374 /* Add public key to repository */
2375 SILC_LOG_DEBUG(("Add client public key to repository"));
2376 if (!silc_server_get_public_key_by_client(server, client, NULL))
2377 silc_skr_add_public_key_simple(server->repository,
2378 entry->data.public_key,
2379 SILC_SKR_USAGE_IDENTIFICATION, client,
2382 id_entry = (void *)client;
2386 case SILC_CONN_SERVER:
2387 case SILC_CONN_ROUTER:
2389 SilcServerEntry new_server;
2390 SilcBool initiator = FALSE;
2391 SilcBool backup_local = FALSE;
2392 SilcBool backup_router = FALSE;
2393 char *backup_replace_ip = NULL;
2394 SilcUInt16 backup_replace_port = 0;
2395 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2396 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2398 /* If we are backup router and this is incoming server connection
2399 and we do not have connection to primary router, do not allow
2401 if (server->server_type == SILC_BACKUP_ROUTER &&
2402 entry->conn_type == SILC_CONN_SERVER &&
2403 !SILC_PRIMARY_ROUTE(server)) {
2404 SILC_LOG_INFO(("Will not accept server connection because we do "
2405 "not have primary router connection established"));
2406 silc_server_disconnect_remote(server, sock,
2407 SILC_STATUS_ERR_PERM_DENIED,
2408 "We do not have connection to primary "
2409 "router established, try later");
2410 silc_server_config_unref(&entry->cconfig);
2411 silc_server_config_unref(&entry->sconfig);
2412 silc_server_config_unref(&entry->rconfig);
2413 silc_server_free_sock_user_data(server, sock, NULL);
2414 server->stat.auth_failures++;
2418 if (entry->conn_type == SILC_CONN_ROUTER) {
2419 /* Verify whether this connection is after all allowed to connect */
2420 if (!silc_server_connection_allowed(server, sock,
2422 &server->config->param,
2423 rconn ? rconn->param : NULL,
2424 silc_connauth_get_ske(connauth))) {
2425 silc_server_config_unref(&entry->cconfig);
2426 silc_server_config_unref(&entry->sconfig);
2427 silc_server_config_unref(&entry->rconfig);
2428 server->stat.auth_failures++;
2434 param = rconn->param;
2436 if (!param->keepalive_secs)
2437 param->keepalive_secs = server->config->param.keepalive_secs;
2439 if (!param->qos && server->config->param.qos) {
2440 param->qos = server->config->param.qos;
2441 param->qos_rate_limit = server->config->param.qos_rate_limit;
2442 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2443 param->qos_limit_sec = server->config->param.qos_limit_sec;
2444 param->qos_limit_usec = server->config->param.qos_limit_usec;
2448 initiator = rconn->initiator;
2449 backup_local = rconn->backup_local;
2450 backup_router = rconn->backup_router;
2451 backup_replace_ip = rconn->backup_replace_ip;
2452 backup_replace_port = rconn->backup_replace_port;
2456 if (entry->conn_type == SILC_CONN_SERVER) {
2457 /* Verify whether this connection is after all allowed to connect */
2458 if (!silc_server_connection_allowed(server, sock,
2460 &server->config->param,
2461 srvconn ? srvconn->param : NULL,
2462 silc_connauth_get_ske(connauth))) {
2463 server->stat.auth_failures++;
2467 if (srvconn->param) {
2468 param = srvconn->param;
2470 if (!param->keepalive_secs)
2471 param->keepalive_secs = server->config->param.keepalive_secs;
2473 if (!param->qos && server->config->param.qos) {
2474 param->qos = server->config->param.qos;
2475 param->qos_rate_limit = server->config->param.qos_rate_limit;
2476 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2477 param->qos_limit_sec = server->config->param.qos_limit_sec;
2478 param->qos_limit_usec = server->config->param.qos_limit_usec;
2482 backup_router = srvconn->backup_router;
2486 /* If we are primary router and we have backup router configured
2487 but it has not connected to use yet, do not accept any other
2489 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2490 !server->backup_router && !backup_router) {
2491 SilcServerConfigRouter *router;
2492 router = silc_server_config_get_backup_router(server);
2493 if (router && strcmp(server->config->server_info->primary->server_ip,
2495 silc_server_find_socket_by_host(server,
2497 router->backup_replace_ip, 0)) {
2498 SILC_LOG_INFO(("Will not accept connections because we do "
2499 "not have backup router connection established"));
2500 silc_server_disconnect_remote(server, sock,
2501 SILC_STATUS_ERR_PERM_DENIED,
2502 "We do not have connection to backup "
2503 "router established, try later");
2504 silc_server_config_unref(&entry->cconfig);
2505 silc_server_config_unref(&entry->sconfig);
2506 silc_server_config_unref(&entry->rconfig);
2507 silc_server_free_sock_user_data(server, sock, NULL);
2508 server->stat.auth_failures++;
2510 /* From here on, wait 20 seconds for the backup router to appear. */
2511 silc_schedule_task_add_timeout(server->schedule,
2512 silc_server_backup_router_wait,
2513 (void *)server, 20, 0);
2518 SILC_LOG_DEBUG(("Remote host is %s",
2519 entry->conn_type == SILC_CONN_SERVER ?
2520 "server" : (backup_router ?
2521 "backup router" : "router")));
2522 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2523 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2524 "server" : (backup_router ?
2525 "backup router" : "router")));
2527 /* Add the server into server cache. The server name and Server ID
2528 is updated after we have received NEW_SERVER packet from the
2529 server. We mark ourselves as router for this server if we really
2532 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2533 server->local_list : (backup_router ?
2534 server->local_list :
2535 server->global_list)),
2537 (entry->conn_type == SILC_CONN_SERVER ?
2538 SILC_SERVER : SILC_ROUTER),
2540 (entry->conn_type == SILC_CONN_SERVER ?
2541 server->id_entry : (backup_router ?
2542 server->id_entry : NULL)),
2545 SILC_LOG_ERROR(("Could not add new server to cache"));
2546 silc_server_disconnect_remote(server, sock,
2547 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2548 silc_server_config_unref(&entry->cconfig);
2549 silc_server_config_unref(&entry->sconfig);
2550 silc_server_config_unref(&entry->rconfig);
2551 silc_server_free_sock_user_data(server, sock, NULL);
2552 server->stat.auth_failures++;
2555 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2556 entry->data.conn_type = entry->conn_type;
2558 id_entry = (void *)new_server;
2560 /* If the incoming connection is router and marked as backup router
2561 then add it to be one of our backups */
2562 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2563 /* Change it back to SERVER type since that's what it really is. */
2565 entry->data.conn_type = SILC_CONN_SERVER;
2566 new_server->server_type = SILC_BACKUP_ROUTER;
2568 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2569 ("Backup router %s is now online",
2572 /* Remove the backup waiting with timeout */
2573 silc_schedule_task_add_timeout(server->schedule,
2574 silc_server_backup_router_wait,
2575 (void *)server, 10, 0);
2579 if (entry->data.conn_type == SILC_CONN_SERVER) {
2580 server->stat.my_servers++;
2581 server->stat.servers++;
2582 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2584 server->stat.my_routers++;
2585 server->stat.routers++;
2586 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2589 /* Check whether this connection is to be our primary router connection
2590 if we do not already have the primary route. */
2591 if (!backup_router &&
2592 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2593 if (silc_server_config_is_primary_route(server) && !initiator)
2596 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2597 server->standalone = FALSE;
2598 if (!server->id_entry->router) {
2599 server->id_entry->router = id_entry;
2600 server->router = id_entry;
2612 /* Add connection to server->conns so that we know we have connection
2614 sconn = silc_calloc(1, sizeof(*sconn));
2615 sconn->server = server;
2617 sconn->remote_host = strdup(hostname);
2618 sconn->remote_port = port;
2619 silc_dlist_add(server->conns, sconn);
2620 idata->sconn = sconn;
2621 idata->sconn->callback = NULL;
2622 idata->last_receive = time(NULL);
2624 /* Add the common data structure to the ID entry. */
2625 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2626 silc_packet_set_context(sock, id_entry);
2628 /* Connection has been fully established now. Everything is ok. */
2629 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2631 /* Perform Quality of Service */
2633 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2634 param->qos_rate_limit, param->qos_bytes_limit,
2635 param->qos_limit_sec, param->qos_limit_usec);
2637 silc_server_config_unref(&entry->cconfig);
2638 silc_server_config_unref(&entry->sconfig);
2639 silc_server_config_unref(&entry->rconfig);
2643 silc_ske_free(silc_connauth_get_ske(connauth));
2644 silc_connauth_free(connauth);
2647 /* SKE completion callback. We set the new keys into use here. */
2650 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2651 SilcSKESecurityProperties prop,
2652 SilcSKEKeyMaterial keymat,
2653 SilcSKERekeyMaterial rekey,
2656 SilcPacketStream sock = context;
2657 SilcUnknownEntry entry = silc_packet_get_context(sock);
2658 SilcIDListData idata = (SilcIDListData)entry;
2659 SilcServer server = entry->server;
2660 SilcConnAuth connauth;
2661 SilcCipher send_key, receive_key;
2662 SilcHmac hmac_send, hmac_receive;
2669 if (status != SILC_SKE_STATUS_OK) {
2671 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2672 silc_ske_map_status(status), entry->hostname, entry->ip));
2674 silc_server_disconnect_remote(server, sock,
2675 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2676 silc_server_config_unref(&entry->cconfig);
2677 silc_server_config_unref(&entry->sconfig);
2678 silc_server_config_unref(&entry->rconfig);
2679 silc_server_free_sock_user_data(server, sock, NULL);
2683 SILC_LOG_DEBUG(("Setting keys into use"));
2685 /* Set the keys into use. The data will be encrypted after this. */
2686 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2687 &hmac_send, &hmac_receive, &hash)) {
2688 /* Error setting keys */
2690 silc_server_disconnect_remote(server, sock,
2691 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2692 silc_server_free_sock_user_data(server, sock, NULL);
2695 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2696 hmac_receive, FALSE);
2698 idata->rekey = rekey;
2699 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2700 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2702 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2707 SILC_LOG_DEBUG(("Starting connection authentication"));
2708 server->stat.auth_attempts++;
2710 connauth = silc_connauth_alloc(server->schedule, ske,
2711 server->config->conn_auth_timeout);
2713 /** Error allocating auth protocol */
2715 silc_server_disconnect_remote(server, sock,
2716 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2717 silc_server_config_unref(&entry->cconfig);
2718 silc_server_config_unref(&entry->sconfig);
2719 silc_server_config_unref(&entry->rconfig);
2720 silc_server_free_sock_user_data(server, sock, NULL);
2724 /* Start connection authentication */
2726 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2727 silc_server_accept_auth_compl, sock);
2730 /* Accept new TCP connection */
2732 static void silc_server_accept_new_connection(SilcNetStatus status,
2736 SilcServer server = context;
2737 SilcPacketStream packet_stream;
2738 SilcServerConfigClient *cconfig = NULL;
2739 SilcServerConfigServer *sconfig = NULL;
2740 SilcServerConfigRouter *rconfig = NULL;
2741 SilcServerConfigDeny *deny;
2742 SilcUnknownEntry entry;
2744 SilcSKEParamsStruct params;
2745 char *hostname, *ip;
2748 SILC_LOG_DEBUG(("Accepting new connection"));
2750 /* Check for maximum allowed connections */
2751 server->stat.conn_attempts++;
2752 if (silc_dlist_count(server->conns) >
2753 server->config->param.connections_max) {
2754 SILC_LOG_ERROR(("Refusing connection, server is full"));
2755 server->stat.conn_failures++;
2756 silc_stream_destroy(stream);
2760 /* Get hostname, IP and port */
2761 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2762 (const char **)&ip, &port)) {
2763 /* Bad socket stream */
2764 server->stat.conn_failures++;
2765 silc_stream_destroy(stream);
2769 /* Create packet stream */
2770 packet_stream = silc_packet_stream_create(server->packet_engine,
2771 server->schedule, stream);
2772 if (!packet_stream) {
2773 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2774 server->stat.conn_failures++;
2775 silc_stream_destroy(stream);
2778 server->stat.conn_num++;
2780 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2782 /* Set source ID to packet stream */
2783 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2786 server->stat.conn_failures++;
2787 silc_packet_stream_destroy(packet_stream);
2791 /* Check whether this connection is denied to connect to us. */
2792 deny = silc_server_config_find_denied(server, ip);
2794 deny = silc_server_config_find_denied(server, hostname);
2796 /* The connection is denied */
2797 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2798 silc_server_disconnect_remote(server, packet_stream,
2799 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2801 silc_server_free_sock_user_data(server, packet_stream, NULL);
2805 /* Check whether we have configured this sort of connection at all. We
2806 have to check all configurations since we don't know what type of
2807 connection this is. */
2808 if (!(cconfig = silc_server_config_find_client(server, ip)))
2809 cconfig = silc_server_config_find_client(server, hostname);
2810 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2811 sconfig = silc_server_config_find_server_conn(server, hostname);
2812 if (server->server_type == SILC_ROUTER)
2813 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2814 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2815 if (!cconfig && !sconfig && !rconfig) {
2816 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2817 server->stat.conn_failures++;
2818 silc_server_disconnect_remote(server, packet_stream,
2819 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2820 silc_server_free_sock_user_data(server, packet_stream, NULL);
2824 /* The connection is allowed */
2825 entry = silc_calloc(1, sizeof(*entry));
2827 server->stat.conn_failures++;
2828 silc_server_disconnect_remote(server, packet_stream,
2829 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2830 silc_server_free_sock_user_data(server, packet_stream, NULL);
2833 entry->hostname = hostname;
2836 entry->server = server;
2837 entry->data.conn_type = SILC_CONN_UNKNOWN;
2838 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2839 silc_packet_set_context(packet_stream, entry);
2841 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2843 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2844 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2845 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2847 /* Take flags for key exchange. Since we do not know what type of connection
2848 this is, we go through all found configurations and use the global ones
2849 as well. This will result always into strictest key exchange flags. */
2850 memset(¶ms, 0, sizeof(params));
2851 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2852 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2853 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2854 if (server->config->param.key_exchange_pfs)
2855 params.flags |= SILC_SKE_SP_FLAG_PFS;
2857 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2858 server->stat.conn_attempts++;
2860 /* Start SILC Key Exchange protocol */
2861 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2862 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2863 server->public_key, server->private_key,
2866 server->stat.conn_failures++;
2867 silc_server_disconnect_remote(server, packet_stream,
2868 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2869 silc_server_free_sock_user_data(server, packet_stream, NULL);
2872 silc_ske_set_callbacks(ske, silc_server_verify_key,
2873 silc_server_accept_completed, packet_stream);
2875 /* Start key exchange protocol */
2876 params.version = silc_version_string;
2877 params.timeout_secs = server->config->key_exchange_timeout;
2878 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2882 /********************************** Rekey ***********************************/
2884 /* Initiator rekey completion callback */
2886 static void silc_server_rekey_completion(SilcSKE ske,
2887 SilcSKEStatus status,
2888 const SilcSKESecurityProperties prop,
2889 const SilcSKEKeyMaterial keymat,
2890 SilcSKERekeyMaterial rekey,
2893 SilcPacketStream sock = context;
2894 SilcIDListData idata = silc_packet_get_context(sock);
2895 SilcServer server = idata->sconn->server;
2897 idata->sconn->op = NULL;
2898 if (status != SILC_SKE_STATUS_OK) {
2899 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2900 idata->sconn->remote_host));
2904 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2905 idata->sconn->remote_host, idata->sconn->remote_port,
2906 SILC_CONNTYPE_STRING(idata->conn_type)));
2908 /* Save rekey data for next rekey */
2909 idata->rekey = rekey;
2911 /* Register new rekey timeout */
2912 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2913 sock, idata->sconn->rekey_timeout, 0);
2916 /* Helper to stop future rekeys on a link. */
2917 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2919 if (!client->connection)
2922 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2924 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2925 client->connection);
2928 /* Rekey callback. Start rekey as initiator */
2930 SILC_TASK_CALLBACK(silc_server_do_rekey)
2932 SilcServer server = app_context;
2933 SilcPacketStream sock = context;
2934 SilcIDListData idata = silc_packet_get_context(sock);
2937 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2939 /* Do not execute rekey with disabled connections */
2940 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2943 /* If another protocol is active do not start rekey */
2944 if (idata->sconn->op) {
2945 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2946 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2951 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2952 idata->sconn->remote_host, idata->sconn->remote_port,
2953 SILC_CONNTYPE_STRING(idata->conn_type)));
2956 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2957 server->public_key, NULL, sock);
2961 /* Set SKE callbacks */
2962 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2965 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2968 /* Responder rekey completion callback */
2971 silc_server_rekey_resp_completion(SilcSKE ske,
2972 SilcSKEStatus status,
2973 const SilcSKESecurityProperties prop,
2974 const SilcSKEKeyMaterial keymat,
2975 SilcSKERekeyMaterial rekey,
2978 SilcPacketStream sock = context;
2979 SilcIDListData idata = silc_packet_get_context(sock);
2981 idata->sconn->op = NULL;
2982 if (status != SILC_SKE_STATUS_OK) {
2983 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2984 idata->sconn->remote_host));
2988 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2989 idata->sconn->remote_host, idata->sconn->remote_port,
2990 SILC_CONNTYPE_STRING(idata->conn_type)));
2992 /* Save rekey data for next rekey */
2993 idata->rekey = rekey;
2996 /* Start rekey as responder */
2998 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
3001 SilcIDListData idata = silc_packet_get_context(sock);
3004 if (!idata->rekey) {
3005 silc_packet_free(packet);
3009 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3010 idata->sconn->remote_host, idata->sconn->remote_port,
3011 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3014 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3015 server->public_key, NULL, sock);
3017 silc_packet_free(packet);
3021 /* Set SKE callbacks */
3022 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3025 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3030 /****************************** Disconnection *******************************/
3032 /* Destroys packet stream. */
3034 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3036 silc_packet_stream_unref(context);
3039 /* Closes connection to socket connection */
3041 void silc_server_close_connection(SilcServer server,
3042 SilcPacketStream sock)
3044 SilcIDListData idata = silc_packet_get_context(sock);
3046 const char *hostname;
3049 if (!silc_packet_stream_is_valid(sock))
3052 memset(tmp, 0, sizeof(tmp));
3053 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3054 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3055 NULL, &hostname, NULL, &port);
3056 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3057 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3058 tmp[0] ? tmp : ""));
3060 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3062 if (idata && idata->sconn) {
3063 silc_server_connection_free(idata->sconn);
3064 idata->sconn = NULL;
3067 /* Take a reference and then destroy the stream. The last reference
3068 is released later in a timeout callback. */
3069 silc_packet_stream_ref(sock);
3070 silc_packet_stream_destroy(sock);
3072 /* Close connection with timeout */
3073 server->stat.conn_num--;
3074 silc_schedule_task_del_by_all(server->schedule, 0,
3075 silc_server_close_connection_final, sock);
3076 silc_schedule_task_add_timeout(server->schedule,
3077 silc_server_close_connection_final,
3081 /* Sends disconnect message to remote connection and disconnects the
3084 void silc_server_disconnect_remote(SilcServer server,
3085 SilcPacketStream sock,
3086 SilcStatus status, ...)
3088 unsigned char buf[512];
3095 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock));
3097 va_start(ap, status);
3098 cp = va_arg(ap, char *);
3100 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3103 /* Send SILC_PACKET_DISCONNECT */
3104 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3105 SILC_STR_UI_CHAR(status),
3106 SILC_STR_UI8_STRING(cp ? buf : NULL),
3109 /* Close connection */
3110 silc_server_close_connection(server, sock);
3113 /* Frees client data and notifies about client's signoff. */
3115 void silc_server_free_client_data(SilcServer server,
3116 SilcPacketStream sock,
3117 SilcClientEntry client,
3119 const char *signoff)
3121 SILC_LOG_DEBUG(("Freeing client %p data", client));
3124 /* Check if anyone is watching this nickname */
3125 if (server->server_type == SILC_ROUTER)
3126 silc_server_check_watcher_list(server, client, NULL,
3127 SILC_NOTIFY_TYPE_SIGNOFF);
3129 /* Send SIGNOFF notify to routers. */
3131 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3132 SILC_BROADCAST(server), client->id,
3136 /* Remove client from all channels */
3138 silc_server_remove_from_channels(server, NULL, client,
3139 TRUE, (char *)signoff, TRUE, FALSE);
3141 silc_server_remove_from_channels(server, NULL, client,
3142 FALSE, NULL, FALSE, FALSE);
3144 /* Remove this client from watcher list if it is */
3145 silc_server_del_from_watcher_list(server, client);
3147 /* Remove client's public key from repository, this will free it too. */
3148 if (client->data.public_key) {
3149 silc_skr_del_public_key(server->repository, client->data.public_key,
3151 client->data.public_key = NULL;
3154 /* Update statistics */
3156 /* Local detached clients aren't counted. */
3157 if (!client->local_detached)
3158 server->stat.my_clients--;
3159 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3160 server->stat.clients - 1));
3161 SILC_VERIFY(server->stat.clients > 0);
3162 server->stat.clients--;
3163 if (server->stat.cell_clients)
3164 server->stat.cell_clients--;
3165 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3166 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3167 silc_schedule_task_del_by_context(server->schedule, client);
3169 if (client->data.sconn) {
3170 silc_server_connection_free(client->data.sconn);
3171 client->data.sconn = NULL;
3174 /* We will not delete the client entry right away. We will take it
3175 into history (for WHOWAS command) for 5 minutes, unless we're
3176 shutting down server. */
3177 if (!server->server_shutdown) {
3178 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3180 client->router = NULL;
3181 client->connection = NULL;
3182 client->data.created = silc_time();
3183 silc_dlist_del(server->expired_clients, client);
3184 silc_dlist_add(server->expired_clients, client);
3186 /* Delete directly since we're shutting down server */
3187 SILC_LOG_DEBUG(("Delete client directly"));
3188 silc_idlist_del_data(client);
3189 silc_idlist_del_client(server->local_list, client);
3193 /* Frees user_data pointer from socket connection object. This also sends
3194 appropriate notify packets to the network to inform about leaving
3197 void silc_server_free_sock_user_data(SilcServer server,
3198 SilcPacketStream sock,
3199 const char *signoff_message)
3201 SilcIDListData idata;
3208 SILC_LOG_DEBUG(("Start, sock %p", sock));
3210 idata = silc_packet_get_context(sock);
3214 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3217 /* Cancel active protocols */
3219 if (idata->sconn && idata->sconn->op) {
3220 SILC_LOG_DEBUG(("Abort active protocol"));
3221 silc_async_abort(idata->sconn->op, NULL, NULL);
3222 idata->sconn->op = NULL;
3224 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3225 ((SilcUnknownEntry)idata)->op) {
3226 SILC_LOG_DEBUG(("Abort active protocol"));
3227 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3228 idata->sconn->op = NULL;
3232 switch (idata->conn_type) {
3233 case SILC_CONN_CLIENT:
3235 SilcClientEntry client_entry = (SilcClientEntry)idata;
3236 silc_server_free_client_data(server, sock, client_entry, TRUE,
3238 silc_packet_set_context(sock, NULL);
3242 case SILC_CONN_SERVER:
3243 case SILC_CONN_ROUTER:
3245 SilcServerEntry user_data = (SilcServerEntry)idata;
3246 SilcServerEntry backup_router = NULL;
3248 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3251 backup_router = silc_server_backup_get(server, user_data->id);
3253 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3254 backup_router == server->id_entry &&
3255 idata->conn_type != SILC_CONN_ROUTER)
3256 backup_router = NULL;
3258 if (server->server_shutdown || server->backup_noswitch)
3259 backup_router = NULL;
3261 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3262 NULL, NULL, &ip, &port);
3264 /* If this was our primary router connection then we're lost to
3265 the outside world. */
3266 if (server->router == user_data) {
3267 /* Check whether we have a backup router connection */
3268 if (!backup_router || backup_router == user_data) {
3269 if (!server->no_reconnect)
3270 silc_server_create_connections(server);
3271 server->id_entry->router = NULL;
3272 server->router = NULL;
3273 server->standalone = TRUE;
3274 server->backup_primary = FALSE;
3275 backup_router = NULL;
3277 if (server->id_entry != backup_router) {
3278 SILC_LOG_INFO(("New primary router is backup router %s",
3279 backup_router->server_name));
3280 server->id_entry->router = backup_router;
3281 server->router = backup_router;
3282 server->router_connect = time(0);
3283 server->backup_primary = TRUE;
3284 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3286 /* Send START_USE to backup router to indicate we have switched */
3287 silc_server_backup_send_start_use(server,
3288 backup_router->connection,
3291 SILC_LOG_INFO(("We are now new primary router in this cell"));
3292 server->id_entry->router = NULL;
3293 server->router = NULL;
3294 server->standalone = TRUE;
3297 /* We stop here to take a breath */
3300 if (server->backup_router) {
3301 server->server_type = SILC_ROUTER;
3303 /* We'll need to constantly try to reconnect to the primary
3304 router so that we'll see when it comes back online. */
3305 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3306 silc_server_backup_connected,
3310 /* Mark this connection as replaced */
3311 silc_server_backup_replaced_add(server, user_data->id,
3314 } else if (backup_router) {
3315 SILC_LOG_INFO(("Enabling the use of backup router %s",
3316 backup_router->server_name));
3318 /* Mark this connection as replaced */
3319 silc_server_backup_replaced_add(server, user_data->id,
3321 } else if (server->server_type == SILC_SERVER &&
3322 idata->conn_type == SILC_CONN_ROUTER) {
3323 /* Reconnect to the router (backup) */
3324 if (!server->no_reconnect)
3325 silc_server_create_connections(server);
3328 if (user_data->server_name)
3329 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3330 ("Server %s signoff", user_data->server_name));
3332 if (!backup_router) {
3333 /* Remove all servers that are originated from this server, and
3334 remove the clients of those servers too. */
3335 silc_server_remove_servers_by_server(server, user_data, TRUE);
3338 /* Remove the clients that this server owns as they will become
3339 invalid now too. For backup router the server is actually
3340 coming from the primary router, so mark that as the owner
3342 if (server->server_type == SILC_BACKUP_ROUTER &&
3343 sock->type == SILC_CONN_SERVER)
3344 silc_server_remove_clients_by_server(server, server->router,
3348 silc_server_remove_clients_by_server(server, user_data,
3351 /* Remove channels owned by this server */
3352 if (server->server_type == SILC_SERVER)
3353 silc_server_remove_channels_by_server(server, user_data);
3355 /* Enable local server connections that may be disabled */
3356 silc_server_local_servers_toggle_enabled(server, TRUE);
3358 /* Update the client entries of this server to the new backup
3359 router. If we are the backup router we also resolve the real
3360 servers for the clients. After updating is over this also
3361 removes the clients that this server explicitly owns. */
3362 silc_server_update_clients_by_server(server, user_data,
3363 backup_router, TRUE);
3365 /* If we are router and just lost our primary router (now standlaone)
3366 we remove everything that was behind it, since we don't know
3368 if (server->server_type == SILC_ROUTER && server->standalone)
3369 /* Remove all servers that are originated from this server, and
3370 remove the clients of those servers too. */
3371 silc_server_remove_servers_by_server(server, user_data, TRUE);
3373 /* Finally remove the clients that are explicitly owned by this
3374 server. They go down with the server. */
3375 silc_server_remove_clients_by_server(server, user_data,
3378 /* Update our server cache to use the new backup router too. */
3379 silc_server_update_servers_by_server(server, user_data, backup_router);
3380 if (server->server_type == SILC_SERVER)
3381 silc_server_update_channels_by_server(server, user_data,
3384 /* Send notify about primary router going down to local operators */
3385 if (server->backup_router)
3386 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3387 SILC_NOTIFY_TYPE_NONE,
3388 ("%s switched to backup router %s "
3389 "(we are primary router now)",
3390 server->server_name, server->server_name));
3391 else if (server->router)
3392 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3393 SILC_NOTIFY_TYPE_NONE,
3394 ("%s switched to backup router %s",
3395 server->server_name,
3396 server->router->server_name));
3398 server->backup_noswitch = FALSE;
3401 silc_server_connection_free(idata->sconn);
3402 idata->sconn = NULL;
3406 if (idata->conn_type == SILC_CONN_SERVER) {
3407 server->stat.my_servers--;
3408 server->stat.servers--;
3409 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3410 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3411 server->stat.my_routers--;
3412 server->stat.routers--;
3413 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3415 if (server->server_type == SILC_ROUTER)
3416 server->stat.cell_servers--;
3418 /* Free the server entry */
3419 silc_server_backup_del(server, user_data);
3420 silc_server_backup_replaced_del(server, user_data);
3421 silc_idlist_del_data(user_data);
3422 if (!silc_idlist_del_server(server->local_list, user_data))
3423 silc_idlist_del_server(server->global_list, user_data);
3425 if (backup_router && backup_router != server->id_entry) {
3426 /* Announce all of our stuff that was created about 5 minutes ago.
3427 The backup router knows all the other stuff already. */
3428 if (server->server_type == SILC_ROUTER)
3429 silc_server_announce_servers(server, FALSE, time(0) - 300,
3430 backup_router->connection);
3432 /* Announce our clients and channels to the router */
3433 silc_server_announce_clients(server, time(0) - 300,
3434 backup_router->connection);
3435 silc_server_announce_channels(server, time(0) - 300,
3436 backup_router->connection);
3439 silc_packet_set_context(sock, NULL);
3445 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3447 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3450 if (server->router_conn == idata->sconn) {
3451 if (!server->no_reconnect)
3452 silc_server_create_connections(server);
3453 server->router_conn = NULL;
3456 silc_server_connection_free(idata->sconn);
3457 idata->sconn = NULL;
3459 silc_idlist_del_data(idata);
3461 silc_packet_set_context(sock, NULL);
3467 /* Removes client from all channels it has joined. This is used when client
3468 connection is disconnected. If the client on a channel is last, the
3469 channel is removed as well. This sends the SIGNOFF notify types. */
3471 void silc_server_remove_from_channels(SilcServer server,
3472 SilcPacketStream sock,
3473 SilcClientEntry client,
3475 const char *signoff_message,
3479 SilcChannelEntry channel;
3480 SilcChannelClientEntry chl;
3481 SilcHashTableList htl;
3482 SilcBuffer clidp = NULL;
3487 if (notify && !client->id)
3490 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3491 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3494 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3499 /* Remove the client from all channels. The client is removed from
3500 the channels' user list. */
3501 silc_hash_table_list(client->channels, &htl);
3502 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3503 channel = chl->channel;
3505 /* Remove channel if this is last client leaving the channel, unless
3506 the channel is permanent. */
3507 if (server->server_type != SILC_SERVER &&
3508 silc_hash_table_count(channel->user_list) < 2) {
3509 silc_server_channel_delete(server, channel);
3513 silc_hash_table_del(client->channels, channel);
3514 silc_hash_table_del(channel->user_list, client);
3515 channel->user_count--;
3517 /* If there is no global users on the channel anymore mark the channel
3518 as local channel. Do not check if the removed client is local client. */
3519 if (server->server_type == SILC_SERVER && channel->global_users &&
3520 chl->client->router && !silc_server_channel_has_global(channel))
3521 channel->global_users = FALSE;
3523 memset(chl, 'A', sizeof(*chl));
3526 /* Update statistics */
3527 if (SILC_IS_LOCAL(client))
3528 server->stat.my_chanclients--;
3529 if (server->server_type == SILC_ROUTER) {
3530 server->stat.cell_chanclients--;
3531 server->stat.chanclients--;
3534 /* If there is not at least one local user on the channel then we don't
3535 need the channel entry anymore, we can remove it safely, unless the
3536 channel is permanent channel */
3537 if (server->server_type == SILC_SERVER &&
3538 !silc_server_channel_has_local(channel)) {
3539 /* Notify about leaving client if this channel has global users. */
3540 if (notify && channel->global_users)
3541 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3542 SILC_NOTIFY_TYPE_SIGNOFF,
3543 signoff_message ? 2 : 1,
3544 clidp->data, silc_buffer_len(clidp),
3545 signoff_message, signoff_message ?
3546 strlen(signoff_message) : 0);
3548 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3549 silc_server_channel_delete(server, channel);
3553 /* Send notify to channel about client leaving SILC and channel too */
3555 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3556 SILC_NOTIFY_TYPE_SIGNOFF,
3557 signoff_message ? 2 : 1,
3558 clidp->data, silc_buffer_len(clidp),
3559 signoff_message, signoff_message ?
3560 strlen(signoff_message) : 0);
3562 if (killed && clidp) {
3563 /* Remove the client from channel's invite list */
3564 if (channel->invite_list &&
3565 silc_hash_table_count(channel->invite_list)) {
3567 SilcArgumentPayload iargs;
3568 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3569 silc_buffer_len(clidp), 3);
3570 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3571 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3572 silc_buffer_free(ab);
3573 silc_argument_payload_free(iargs);
3577 /* Don't create keys if we are shutting down */
3578 if (server->server_shutdown)
3581 /* Re-generate channel key if needed */
3582 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3583 if (!silc_server_create_channel_key(server, channel, 0))
3586 /* Send the channel key to the channel. The key of course is not sent
3587 to the client who was removed from the channel. */
3588 silc_server_send_channel_key(server, client->connection, channel,
3589 server->server_type == SILC_ROUTER ?
3590 FALSE : !server->standalone);
3594 silc_hash_table_list_reset(&htl);
3596 silc_buffer_free(clidp);
3599 /* Removes client from one channel. This is used for example when client
3600 calls LEAVE command to remove itself from the channel. Returns TRUE
3601 if channel still exists and FALSE if the channel is removed when
3602 last client leaves the channel. If `notify' is FALSE notify messages
3605 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3606 SilcPacketStream sock,
3607 SilcChannelEntry channel,
3608 SilcClientEntry client,
3611 SilcChannelClientEntry chl;
3614 SILC_LOG_DEBUG(("Removing %s from channel %s",
3615 silc_id_render(client->id, SILC_ID_CLIENT),
3616 channel->channel_name));
3618 /* Get the entry to the channel, if this client is not on the channel
3620 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3623 /* Remove channel if this is last client leaving the channel, unless
3624 the channel is permanent. */
3625 if (server->server_type != SILC_SERVER &&
3626 silc_hash_table_count(channel->user_list) < 2) {
3627 silc_server_channel_delete(server, channel);
3631 silc_hash_table_del(client->channels, channel);
3632 silc_hash_table_del(channel->user_list, client);
3633 channel->user_count--;
3635 /* If there is no global users on the channel anymore mark the channel
3636 as local channel. Do not check if the client is local client. */
3637 if (server->server_type == SILC_SERVER && channel->global_users &&
3638 chl->client->router && !silc_server_channel_has_global(channel))
3639 channel->global_users = FALSE;
3641 memset(chl, 'O', sizeof(*chl));
3644 /* Update statistics */
3645 if (SILC_IS_LOCAL(client))
3646 server->stat.my_chanclients--;
3647 if (server->server_type == SILC_ROUTER) {
3648 server->stat.cell_chanclients--;
3649 server->stat.chanclients--;
3652 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3656 /* If there is not at least one local user on the channel then we don't
3657 need the channel entry anymore, we can remove it safely, unless the
3658 channel is permanent channel */
3659 if (server->server_type == SILC_SERVER &&
3660 !silc_server_channel_has_local(channel)) {
3661 /* Notify about leaving client if this channel has global users. */
3662 if (notify && channel->global_users)
3663 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3664 SILC_NOTIFY_TYPE_LEAVE, 1,
3665 clidp->data, silc_buffer_len(clidp));
3667 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3668 silc_server_channel_delete(server, channel);
3669 silc_buffer_free(clidp);
3673 /* Send notify to channel about client leaving the channel */
3675 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3676 SILC_NOTIFY_TYPE_LEAVE, 1,
3677 clidp->data, silc_buffer_len(clidp));
3679 silc_buffer_free(clidp);
3683 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3684 function may be used only by router. In real SILC network all channels
3685 are created by routers thus this function is never used by normal
3688 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3689 SilcServerID *router_id,
3695 SilcChannelID *channel_id;
3696 SilcChannelEntry entry;
3697 SilcCipher send_key, receive_key;
3700 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3703 cipher = SILC_DEFAULT_CIPHER;
3705 hmac = SILC_DEFAULT_HMAC;
3707 /* Allocate cipher */
3708 if (!silc_cipher_alloc(cipher, &send_key))
3710 if (!silc_cipher_alloc(cipher, &receive_key)) {
3711 silc_cipher_free(send_key);
3716 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3717 silc_cipher_free(send_key);
3718 silc_cipher_free(receive_key);
3722 channel_name = strdup(channel_name);
3724 /* Create the channel ID */
3725 if (!silc_id_create_channel_id(server, router_id, server->rng,
3727 silc_free(channel_name);
3728 silc_cipher_free(send_key);
3729 silc_cipher_free(receive_key);
3730 silc_hmac_free(newhmac);
3734 /* Create the channel */
3735 entry = silc_idlist_add_channel(server->local_list, channel_name,
3736 SILC_CHANNEL_MODE_NONE, channel_id,
3737 NULL, send_key, receive_key, newhmac);
3739 silc_free(channel_name);
3740 silc_cipher_free(send_key);
3741 silc_cipher_free(receive_key);
3742 silc_hmac_free(newhmac);
3743 silc_free(channel_id);
3747 entry->cipher = strdup(cipher);
3748 entry->hmac_name = strdup(hmac);
3750 /* Now create the actual key material */
3751 if (!silc_server_create_channel_key(server, entry,
3752 silc_cipher_get_key_len(send_key) / 8)) {
3753 silc_idlist_del_channel(server->local_list, entry);
3757 /* Notify other routers about the new channel. We send the packet
3758 to our primary route. */
3760 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3761 channel_name, entry->id,
3762 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3765 /* Distribute to backup routers */
3766 if (broadcast && server->server_type == SILC_ROUTER) {
3768 unsigned char cid[32];
3769 SilcUInt32 name_len = strlen(channel_name);
3772 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3773 packet = silc_channel_payload_encode(channel_name, name_len,
3774 cid, id_len, entry->mode);
3775 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3776 packet->data, silc_buffer_len(packet), FALSE,
3778 silc_buffer_free(packet);
3781 server->stat.my_channels++;
3782 if (server->server_type == SILC_ROUTER) {
3783 server->stat.channels++;
3784 server->stat.cell_channels++;
3785 entry->users_resolved = TRUE;
3791 /* Same as above but creates the channel with Channel ID `channel_id. */
3794 silc_server_create_new_channel_with_id(SilcServer server,
3798 SilcChannelID *channel_id,
3801 SilcChannelEntry entry;
3802 SilcCipher send_key, receive_key;
3805 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3808 cipher = SILC_DEFAULT_CIPHER;
3810 hmac = SILC_DEFAULT_HMAC;
3812 /* Allocate cipher */
3813 if (!silc_cipher_alloc(cipher, &send_key))
3815 if (!silc_cipher_alloc(cipher, &receive_key)) {
3816 silc_cipher_free(send_key);
3821 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3822 silc_cipher_free(send_key);
3823 silc_cipher_free(receive_key);
3827 channel_name = strdup(channel_name);
3829 /* Create the channel */
3830 entry = silc_idlist_add_channel(server->local_list, channel_name,
3831 SILC_CHANNEL_MODE_NONE, channel_id,
3832 NULL, send_key, receive_key, newhmac);
3834 silc_cipher_free(send_key);
3835 silc_cipher_free(receive_key);
3836 silc_hmac_free(newhmac);
3837 silc_free(channel_name);
3841 /* Now create the actual key material */
3842 if (!silc_server_create_channel_key(server, entry,
3843 silc_cipher_get_key_len(send_key) / 8)) {
3844 silc_idlist_del_channel(server->local_list, entry);
3848 /* Notify other routers about the new channel. We send the packet
3849 to our primary route. */
3851 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3852 channel_name, entry->id,
3853 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3856 /* Distribute to backup routers */
3857 if (broadcast && server->server_type == SILC_ROUTER) {
3859 unsigned char cid[32];
3860 SilcUInt32 name_len = strlen(channel_name);
3863 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3864 packet = silc_channel_payload_encode(channel_name, name_len,
3865 cid, id_len, entry->mode);
3866 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3867 packet->data, silc_buffer_len(packet), FALSE,
3869 silc_buffer_free(packet);
3872 server->stat.my_channels++;
3873 if (server->server_type == SILC_ROUTER) {
3874 server->stat.channels++;
3875 server->stat.cell_channels++;
3876 entry->users_resolved = TRUE;
3882 /* Channel's key re-key timeout callback. */
3884 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3886 SilcServer server = app_context;
3887 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3891 /* Return now if we are shutting down */
3892 if (server->server_shutdown)
3895 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3898 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3901 /* Generates new channel key. This is used to create the initial channel key
3902 but also to re-generate new key for channel. If `key_len' is provided
3903 it is the bytes of the key length. */
3905 SilcBool silc_server_create_channel_key(SilcServer server,
3906 SilcChannelEntry channel,
3910 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3913 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3914 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3918 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3920 if (!channel->send_key)
3921 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3922 channel->send_key = NULL;
3925 if (!channel->receive_key)
3926 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3927 silc_cipher_free(channel->send_key);
3928 channel->send_key = channel->receive_key = NULL;
3934 else if (channel->key_len)
3935 len = channel->key_len / 8;
3937 len = silc_cipher_get_key_len(channel->send_key) / 8;
3939 /* Create channel key */
3940 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3943 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3944 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3946 /* Remove old key if exists */
3948 memset(channel->key, 0, channel->key_len / 8);
3949 silc_free(channel->key);
3953 channel->key_len = len * 8;
3954 channel->key = silc_memdup(channel_key, len);
3955 memset(channel_key, 0, sizeof(channel_key));
3957 /* Generate HMAC key from the channel key data and set it */
3959 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3960 memset(channel->key, 0, channel->key_len / 8);
3961 silc_free(channel->key);
3962 silc_cipher_free(channel->send_key);
3963 silc_cipher_free(channel->receive_key);
3964 channel->send_key = channel->receive_key = NULL;
3967 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3968 silc_hmac_set_key(channel->hmac, hash,
3969 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3970 memset(hash, 0, sizeof(hash));
3972 if (server->server_type == SILC_ROUTER) {
3973 if (!channel->rekey)
3974 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3975 channel->rekey->channel = channel;
3976 channel->rekey->key_len = key_len;
3977 if (channel->rekey->task)
3978 silc_schedule_task_del(server->schedule, channel->rekey->task);
3980 channel->rekey->task =
3981 silc_schedule_task_add_timeout(server->schedule,
3982 silc_server_channel_key_rekey,
3983 (void *)channel->rekey,
3984 server->config->channel_rekey_secs, 0);
3990 /* Saves the channel key found in the encoded `key_payload' buffer. This
3991 function is used when we receive Channel Key Payload and also when we're
3992 processing JOIN command reply. Returns entry to the channel. */
3994 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3995 SilcBuffer key_payload,
3996 SilcChannelEntry channel)
3998 SilcChannelKeyPayload payload = NULL;
4000 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4004 /* Decode channel key payload */
4005 payload = silc_channel_key_payload_parse(key_payload->data,
4006 silc_buffer_len(key_payload));
4008 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4013 /* Get the channel entry */
4016 /* Get channel ID */
4017 tmp = silc_channel_key_get_id(payload, &tmp_len);
4018 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4023 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4025 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4027 if (server->server_type == SILC_ROUTER)
4028 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4029 silc_id_render(&id, SILC_ID_CHANNEL)));
4035 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4037 tmp = silc_channel_key_get_key(payload, &tmp_len);
4043 cipher = silc_channel_key_get_cipher(payload, NULL);
4049 /* Remove old key if exists */
4051 memset(channel->key, 0, channel->key_len / 8);
4052 silc_free(channel->key);
4053 silc_cipher_free(channel->send_key);
4054 silc_cipher_free(channel->receive_key);
4057 /* Create new cipher */
4058 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4059 channel->send_key = NULL;
4063 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4064 silc_cipher_free(channel->send_key);
4065 channel->send_key = channel->receive_key = NULL;
4070 if (channel->cipher)
4071 silc_free(channel->cipher);
4072 channel->cipher = strdup(cipher);
4075 channel->key_len = tmp_len * 8;
4076 channel->key = silc_memdup(tmp, tmp_len);
4077 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4078 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4080 /* Generate HMAC key from the channel key data and set it */
4082 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4083 memset(channel->key, 0, channel->key_len / 8);
4084 silc_free(channel->key);
4085 silc_cipher_free(channel->send_key);
4086 silc_cipher_free(channel->receive_key);
4087 channel->send_key = channel->receive_key = NULL;
4090 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4091 silc_hmac_set_key(channel->hmac, hash,
4092 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4094 memset(hash, 0, sizeof(hash));
4095 memset(tmp, 0, tmp_len);
4097 if (server->server_type == SILC_ROUTER) {
4098 if (!channel->rekey)
4099 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4100 channel->rekey->channel = channel;
4101 if (channel->rekey->task)
4102 silc_schedule_task_del(server->schedule, channel->rekey->task);
4104 channel->rekey->task =
4105 silc_schedule_task_add_timeout(server->schedule,
4106 silc_server_channel_key_rekey,
4107 (void *)channel->rekey,
4108 server->config->channel_rekey_secs, 0);
4113 silc_channel_key_payload_free(payload);
4118 /* Returns assembled of all servers in the given ID list. The packet's
4119 form is dictated by the New ID payload. */
4121 static void silc_server_announce_get_servers(SilcServer server,
4122 SilcServerEntry remote,
4124 SilcBuffer *servers,
4125 unsigned long creation_time)
4128 SilcIDCacheEntry id_cache;
4129 SilcServerEntry entry;
4133 /* Go through all clients in the list */
4134 if (silc_idcache_get_all(id_list->servers, &list)) {
4135 silc_list_start(list);
4136 while ((id_cache = silc_list_get(list))) {
4137 entry = (SilcServerEntry)id_cache->context;
4139 /* Do not announce the one we've sending our announcements and
4140 do not announce ourself. Also check the creation time if it's
4142 if ((entry == remote) || (entry == server->id_entry) ||
4143 (creation_time && entry->data.created < creation_time))
4146 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4148 tmp = silc_buffer_realloc(*servers,
4150 silc_buffer_truelen((*servers)) +
4151 silc_buffer_len(idp) :
4152 silc_buffer_len(idp)));
4156 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4157 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4158 silc_buffer_pull(*servers, silc_buffer_len(idp));
4159 silc_buffer_free(idp);
4165 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4171 p = silc_notify_payload_encode(notify, argc, ap);
4177 /* This function is used by router to announce existing servers to our
4178 primary router when we've connected to it. If `creation_time' is non-zero
4179 then only the servers that has been created after the `creation_time'
4180 will be announced. */
4182 void silc_server_announce_servers(SilcServer server, SilcBool global,
4183 unsigned long creation_time,
4184 SilcPacketStream remote)
4186 SilcBuffer servers = NULL;
4188 SILC_LOG_DEBUG(("Announcing servers"));
4190 /* Get servers in local list */
4191 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4192 server->local_list, &servers,
4196 /* Get servers in global list */
4197 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4198 server->global_list, &servers,
4202 silc_buffer_push(servers, servers->data - servers->head);
4203 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4205 /* Send the packet */
4206 silc_server_packet_send(server, remote,
4207 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4208 servers->data, silc_buffer_len(servers));
4210 silc_buffer_free(servers);
4214 /* Returns assembled packet of all clients in the given ID list. The
4215 packet's form is dictated by the New ID Payload. */
4217 static void silc_server_announce_get_clients(SilcServer server,
4219 SilcBuffer *clients,
4221 unsigned long creation_time)
4224 SilcIDCacheEntry id_cache;
4225 SilcClientEntry client;
4228 unsigned char mode[4];
4231 /* Go through all clients in the list */
4232 if (silc_idcache_get_all(id_list->clients, &list)) {
4233 silc_list_start(list);
4234 while ((id_cache = silc_list_get(list))) {
4235 client = (SilcClientEntry)id_cache->context;
4237 if (creation_time && client->data.created < creation_time)
4239 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4241 if (!client->connection && !client->router)
4244 SILC_LOG_DEBUG(("Announce Client ID %s",
4245 silc_id_render(client->id, SILC_ID_CLIENT)));
4247 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4251 tmp2 = silc_buffer_realloc(*clients,
4253 silc_buffer_truelen((*clients)) +
4254 silc_buffer_len(idp) :
4255 silc_buffer_len(idp)));
4259 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4260 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4261 silc_buffer_pull(*clients, silc_buffer_len(idp));
4263 SILC_PUT32_MSB(client->mode, mode);
4265 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4266 2, idp->data, silc_buffer_len(idp),
4268 tmp2 = silc_buffer_realloc(*umodes,
4270 silc_buffer_truelen((*umodes)) +
4271 silc_buffer_len(tmp) :
4272 silc_buffer_len(tmp)));
4276 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4277 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4278 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4279 silc_buffer_free(tmp);
4281 silc_buffer_free(idp);
4286 /* This function is used to announce our existing clients to our router
4287 when we've connected to it. If `creation_time' is non-zero then only
4288 the clients that has been created after the `creation_time' will be
4291 void silc_server_announce_clients(SilcServer server,
4292 unsigned long creation_time,
4293 SilcPacketStream remote)
4295 SilcBuffer clients = NULL;
4296 SilcBuffer umodes = NULL;
4298 SILC_LOG_DEBUG(("Announcing clients"));
4300 /* Get clients in local list */
4301 silc_server_announce_get_clients(server, server->local_list,
4302 &clients, &umodes, creation_time);
4304 /* As router we announce our global list as well */
4305 if (server->server_type == SILC_ROUTER)
4306 silc_server_announce_get_clients(server, server->global_list,
4307 &clients, &umodes, creation_time);
4310 silc_buffer_push(clients, clients->data - clients->head);
4311 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4313 /* Send the packet */
4314 silc_server_packet_send(server, remote,
4315 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4316 clients->data, silc_buffer_len(clients));
4318 silc_buffer_free(clients);
4322 silc_buffer_push(umodes, umodes->data - umodes->head);
4323 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4325 /* Send the packet */
4326 silc_server_packet_send(server, remote,
4327 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4328 umodes->data, silc_buffer_len(umodes));
4330 silc_buffer_free(umodes);
4334 /* Returns channel's topic for announcing it */
4336 void silc_server_announce_get_channel_topic(SilcServer server,
4337 SilcChannelEntry channel,
4342 if (channel->topic) {
4343 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4344 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4346 silc_buffer_len(chidp),
4348 strlen(channel->topic));
4349 silc_buffer_free(chidp);
4353 /* Returns channel's invite and ban lists */
4355 void silc_server_announce_get_inviteban(SilcServer server,
4356 SilcChannelEntry channel,
4360 SilcBuffer list, idp, idp2, tmp2;
4363 SilcHashTableList htl;
4364 const unsigned char a[1] = { 0x03 };
4366 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4368 /* Encode invite list */
4369 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4370 list = silc_buffer_alloc_size(2);
4371 type = silc_hash_table_count(channel->invite_list);
4372 SILC_PUT16_MSB(type, list->data);
4373 silc_hash_table_list(channel->invite_list, &htl);
4374 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4375 list = silc_argument_payload_encode_one(list, tmp2->data,
4376 silc_buffer_len(tmp2),
4377 SILC_PTR_TO_32(ptype));
4378 silc_hash_table_list_reset(&htl);
4380 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4382 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4383 idp->data, silc_buffer_len(idp),
4384 channel->channel_name,
4385 strlen(channel->channel_name),
4386 idp2->data, silc_buffer_len(idp2),
4388 list->data, silc_buffer_len(list));
4389 silc_buffer_free(idp2);
4390 silc_buffer_free(list);
4393 /* Encode ban list */
4394 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4395 list = silc_buffer_alloc_size(2);
4396 type = silc_hash_table_count(channel->ban_list);
4397 SILC_PUT16_MSB(type, list->data);
4398 silc_hash_table_list(channel->ban_list, &htl);
4399 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4400 list = silc_argument_payload_encode_one(list, tmp2->data,
4401 silc_buffer_len(tmp2),
4402 SILC_PTR_TO_32(ptype));
4403 silc_hash_table_list_reset(&htl);
4406 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4407 idp->data, silc_buffer_len(idp),
4409 list->data, silc_buffer_len(list));
4410 silc_buffer_free(list);
4413 silc_buffer_free(idp);
4416 /* Returns assembled packets for channel users of the `channel'. */
4418 void silc_server_announce_get_channel_users(SilcServer server,
4419 SilcChannelEntry channel,
4420 SilcBuffer *channel_modes,
4421 SilcBuffer *channel_users,
4422 SilcBuffer *channel_users_modes)
4424 SilcChannelClientEntry chl;
4425 SilcHashTableList htl;
4426 SilcBuffer chidp, clidp, csidp;
4427 SilcBuffer tmp, fkey = NULL, chpklist;
4429 unsigned char mode[4], ulimit[4];
4433 SILC_LOG_DEBUG(("Start"));
4435 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4436 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4437 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4440 SILC_PUT32_MSB(channel->mode, mode);
4441 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4442 SILC_PUT32_MSB(channel->user_limit, ulimit);
4443 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4444 if (channel->founder_key)
4445 fkey = silc_public_key_payload_encode(channel->founder_key);
4447 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4449 silc_buffer_len(csidp),
4452 hmac, hmac ? strlen(hmac) : 0,
4453 channel->passphrase,
4454 channel->passphrase ?
4455 strlen(channel->passphrase) : 0,
4456 fkey ? fkey->data : NULL,
4457 fkey ? silc_buffer_len(fkey) : 0,
4458 chpklist ? chpklist->data : NULL,
4460 silc_buffer_len(chpklist) : 0,
4462 SILC_CHANNEL_MODE_ULIMIT ?
4465 SILC_CHANNEL_MODE_ULIMIT ?
4466 sizeof(ulimit) : 0));
4467 len = silc_buffer_len(tmp);
4469 silc_buffer_realloc(*channel_modes,
4471 silc_buffer_truelen((*channel_modes)) + len : len));
4474 *channel_modes = tmp2;
4475 silc_buffer_pull_tail(*channel_modes,
4476 ((*channel_modes)->end -
4477 (*channel_modes)->data));
4478 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4479 silc_buffer_pull(*channel_modes, len);
4480 silc_buffer_free(tmp);
4481 silc_buffer_free(fkey);
4484 /* Now find all users on the channel */
4485 silc_hash_table_list(channel->user_list, &htl);
4486 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4487 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4489 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4493 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4495 silc_buffer_len(clidp),
4497 silc_buffer_len(chidp));
4498 len = silc_buffer_len(tmp);
4500 silc_buffer_realloc(*channel_users,
4502 silc_buffer_truelen((*channel_users)) + len : len));
4505 *channel_users = tmp2;
4506 silc_buffer_pull_tail(*channel_users,
4507 ((*channel_users)->end -
4508 (*channel_users)->data));
4510 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4511 silc_buffer_pull(*channel_users, len);
4512 silc_buffer_free(tmp);
4514 /* CUMODE notify for mode change on the channel */
4515 SILC_PUT32_MSB(chl->mode, mode);
4516 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4517 fkey = silc_public_key_payload_encode(channel->founder_key);
4518 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4520 silc_buffer_len(csidp),
4523 silc_buffer_len(clidp),
4524 fkey ? fkey->data : NULL,
4525 fkey ? silc_buffer_len(fkey) : 0);
4526 len = silc_buffer_len(tmp);
4528 silc_buffer_realloc(*channel_users_modes,
4529 (*channel_users_modes ?
4530 silc_buffer_truelen((*channel_users_modes)) +
4534 *channel_users_modes = tmp2;
4535 silc_buffer_pull_tail(*channel_users_modes,
4536 ((*channel_users_modes)->end -
4537 (*channel_users_modes)->data));
4539 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4540 silc_buffer_pull(*channel_users_modes, len);
4541 silc_buffer_free(tmp);
4542 silc_buffer_free(fkey);
4544 silc_buffer_free(clidp);
4546 silc_hash_table_list_reset(&htl);
4547 silc_buffer_free(chidp);
4548 silc_buffer_free(csidp);
4551 /* Returns assembled packets for all channels and users on those channels
4552 from the given ID List. The packets are in the form dictated by the
4553 New Channel and New Channel User payloads. */
4555 void silc_server_announce_get_channels(SilcServer server,
4557 SilcBuffer *channels,
4558 SilcBuffer **channel_modes,
4559 SilcBuffer *channel_users,
4560 SilcBuffer **channel_users_modes,
4561 SilcUInt32 *channel_users_modes_c,
4562 SilcBuffer **channel_topics,
4563 SilcBuffer **channel_invites,
4564 SilcBuffer **channel_bans,
4565 SilcChannelID ***channel_ids,
4566 unsigned long creation_time)
4569 SilcIDCacheEntry id_cache;
4570 SilcChannelEntry channel;
4571 unsigned char cid[32];
4573 SilcUInt16 name_len;
4575 int i = *channel_users_modes_c;
4579 SILC_LOG_DEBUG(("Start"));
4581 /* Go through all channels in the list */
4582 if (silc_idcache_get_all(id_list->channels, &list)) {
4583 silc_list_start(list);
4584 while ((id_cache = silc_list_get(list))) {
4585 channel = (SilcChannelEntry)id_cache->context;
4587 if (creation_time && channel->created < creation_time)
4592 SILC_LOG_DEBUG(("Announce Channel ID %s",
4593 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4595 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4596 name_len = strlen(channel->channel_name);
4599 len = 4 + name_len + id_len + 4;
4601 silc_buffer_realloc(*channels,
4603 silc_buffer_truelen((*channels)) +
4609 silc_buffer_pull_tail(*channels,
4610 ((*channels)->end - (*channels)->data));
4611 silc_buffer_format(*channels,
4612 SILC_STR_UI_SHORT(name_len),
4613 SILC_STR_UI_XNSTRING(channel->channel_name,
4615 SILC_STR_UI_SHORT(id_len),
4616 SILC_STR_UI_XNSTRING(cid, id_len),
4617 SILC_STR_UI_INT(channel->mode),
4619 silc_buffer_pull(*channels, len);
4622 if (creation_time && channel->updated < creation_time)
4628 /* Channel user modes */
4629 tmp = silc_realloc(*channel_users_modes,
4630 sizeof(**channel_users_modes) * (i + 1));
4633 *channel_users_modes = tmp;
4634 (*channel_users_modes)[i] = NULL;
4635 tmp = silc_realloc(*channel_modes,
4636 sizeof(**channel_modes) * (i + 1));
4639 *channel_modes = tmp;
4640 (*channel_modes)[i] = NULL;
4641 tmp = silc_realloc(*channel_ids,
4642 sizeof(**channel_ids) * (i + 1));
4646 (*channel_ids)[i] = NULL;
4647 silc_server_announce_get_channel_users(server, channel,
4648 &(*channel_modes)[i],
4650 &(*channel_users_modes)[i]);
4651 (*channel_ids)[i] = channel->id;
4653 /* Channel's topic */
4654 tmp = silc_realloc(*channel_topics,
4655 sizeof(**channel_topics) * (i + 1));
4658 *channel_topics = tmp;
4659 (*channel_topics)[i] = NULL;
4660 silc_server_announce_get_channel_topic(server, channel,
4661 &(*channel_topics)[i]);
4663 /* Channel's invite and ban list */
4664 tmp = silc_realloc(*channel_invites,
4665 sizeof(**channel_invites) * (i + 1));
4668 *channel_invites = tmp;
4669 (*channel_invites)[i] = NULL;
4670 tmp = silc_realloc(*channel_bans,
4671 sizeof(**channel_bans) * (i + 1));
4674 *channel_bans = tmp;
4675 (*channel_bans)[i] = NULL;
4676 silc_server_announce_get_inviteban(server, channel,
4677 &(*channel_invites)[i],
4678 &(*channel_bans)[i]);
4680 (*channel_users_modes_c)++;
4688 /* This function is used to announce our existing channels to our router
4689 when we've connected to it. This also announces the users on the
4690 channels to the router. If the `creation_time' is non-zero only the
4691 channels that was created after the `creation_time' are announced.
4692 Note that the channel users are still announced even if the `creation_time'
4695 void silc_server_announce_channels(SilcServer server,
4696 unsigned long creation_time,
4697 SilcPacketStream remote)
4699 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4700 SilcBuffer *channel_users_modes = NULL;
4701 SilcBuffer *channel_topics = NULL;
4702 SilcBuffer *channel_invites = NULL;
4703 SilcBuffer *channel_bans = NULL;
4704 SilcUInt32 channel_users_modes_c = 0;
4705 SilcChannelID **channel_ids = NULL;
4707 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4709 /* Get channels and channel users in local list */
4710 silc_server_announce_get_channels(server, server->local_list,
4711 &channels, &channel_modes,
4713 &channel_users_modes,
4714 &channel_users_modes_c,
4718 &channel_ids, creation_time);
4720 /* Get channels and channel users in global list */
4721 if (server->server_type != SILC_SERVER)
4722 silc_server_announce_get_channels(server, server->global_list,
4723 &channels, &channel_modes,
4725 &channel_users_modes,
4726 &channel_users_modes_c,
4730 &channel_ids, creation_time);
4733 silc_buffer_push(channels, channels->data - channels->head);
4734 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4736 /* Send the packet */
4737 silc_server_packet_send(server, remote,
4738 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4739 channels->data, silc_buffer_len(channels));
4741 silc_buffer_free(channels);
4744 if (channel_users) {
4745 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4746 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4747 silc_buffer_len(channel_users));
4749 /* Send the packet */
4750 silc_server_packet_send(server, remote,
4751 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4752 channel_users->data, silc_buffer_len(channel_users));
4754 silc_buffer_free(channel_users);
4757 if (channel_modes) {
4760 for (i = 0; i < channel_users_modes_c; i++) {
4761 if (!channel_modes[i])
4763 silc_buffer_push(channel_modes[i],
4764 channel_modes[i]->data -
4765 channel_modes[i]->head);
4766 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4767 silc_buffer_len(channel_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_modes[i]->data,
4772 silc_buffer_len(channel_modes[i]));
4773 silc_buffer_free(channel_modes[i]);
4775 silc_free(channel_modes);
4778 if (channel_users_modes) {
4781 for (i = 0; i < channel_users_modes_c; i++) {
4782 if (!channel_users_modes[i])
4784 silc_buffer_push(channel_users_modes[i],
4785 channel_users_modes[i]->data -
4786 channel_users_modes[i]->head);
4787 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4788 silc_buffer_len(channel_users_modes[i]));
4789 silc_server_packet_send_dest(server, remote,
4790 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4791 channel_ids[i], SILC_ID_CHANNEL,
4792 channel_users_modes[i]->data,
4793 silc_buffer_len(channel_users_modes[i]));
4794 silc_buffer_free(channel_users_modes[i]);
4796 silc_free(channel_users_modes);
4799 if (channel_topics) {
4802 for (i = 0; i < channel_users_modes_c; i++) {
4803 if (!channel_topics[i])
4806 silc_buffer_push(channel_topics[i],
4807 channel_topics[i]->data -
4808 channel_topics[i]->head);
4809 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4810 silc_buffer_len(channel_topics[i]));
4811 silc_server_packet_send_dest(server, remote,
4812 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4813 channel_ids[i], SILC_ID_CHANNEL,
4814 channel_topics[i]->data,
4815 silc_buffer_len(channel_topics[i]));
4816 silc_buffer_free(channel_topics[i]);
4818 silc_free(channel_topics);
4821 if (channel_invites) {
4824 for (i = 0; i < channel_users_modes_c; i++) {
4825 if (!channel_invites[i])
4828 silc_buffer_push(channel_invites[i],
4829 channel_invites[i]->data -
4830 channel_invites[i]->head);
4831 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4832 silc_buffer_len(channel_invites[i]));
4833 silc_server_packet_send_dest(server, remote,
4834 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4835 channel_ids[i], SILC_ID_CHANNEL,
4836 channel_invites[i]->data,
4837 silc_buffer_len(channel_invites[i]));
4838 silc_buffer_free(channel_invites[i]);
4840 silc_free(channel_invites);
4846 for (i = 0; i < channel_users_modes_c; i++) {
4847 if (!channel_bans[i])
4850 silc_buffer_push(channel_bans[i],
4851 channel_bans[i]->data -
4852 channel_bans[i]->head);
4853 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4854 silc_buffer_len(channel_bans[i]));
4855 silc_server_packet_send_dest(server, remote,
4856 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4857 channel_ids[i], SILC_ID_CHANNEL,
4858 channel_bans[i]->data,
4859 silc_buffer_len(channel_bans[i]));
4860 silc_buffer_free(channel_bans[i]);
4862 silc_free(channel_bans);
4865 silc_free(channel_ids);
4868 /* Announces WATCH list. */
4870 void silc_server_announce_watches(SilcServer server,
4871 SilcPacketStream remote)
4873 SilcHashTableList htl;
4874 SilcBuffer buffer, idp, args, pkp;
4875 SilcClientEntry client;
4878 SILC_LOG_DEBUG(("Announcing watch list"));
4880 /* XXX because way we save the nicks (hash) we cannot announce them. */
4882 /* XXX we should send all public keys in one command if client is
4883 watching more than one key */
4884 silc_hash_table_list(server->watcher_list_pk, &htl);
4885 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4886 if (!client || !client->id)
4889 server->stat.commands_sent++;
4891 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4892 args = silc_buffer_alloc_size(2);
4893 silc_buffer_format(args,
4894 SILC_STR_UI_SHORT(1),
4896 pkp = silc_public_key_payload_encode(key);
4897 args = silc_argument_payload_encode_one(args, pkp->data,
4898 silc_buffer_len(pkp), 0x00);
4899 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4900 ++server->cmd_ident, 2,
4901 1, idp->data, silc_buffer_len(idp),
4903 silc_buffer_len(args));
4906 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4907 buffer->data, silc_buffer_len(buffer));
4909 silc_buffer_free(pkp);
4910 silc_buffer_free(args);
4911 silc_buffer_free(idp);
4912 silc_buffer_free(buffer);
4914 silc_hash_table_list_reset(&htl);
4917 /* Assembles user list and users mode list from the `channel'. */
4919 SilcBool silc_server_get_users_on_channel(SilcServer server,
4920 SilcChannelEntry channel,
4921 SilcBuffer *user_list,
4922 SilcBuffer *mode_list,
4923 SilcUInt32 *user_count)
4925 SilcChannelClientEntry chl;
4926 SilcHashTableList htl;
4927 SilcBuffer client_id_list;
4928 SilcBuffer client_mode_list;
4930 SilcUInt32 list_count = 0, len = 0;
4932 if (!silc_hash_table_count(channel->user_list))
4935 silc_hash_table_list(channel->user_list, &htl);
4936 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4937 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4938 silc_hash_table_list_reset(&htl);
4940 client_id_list = silc_buffer_alloc(len);
4942 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4943 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4944 silc_buffer_pull_tail(client_mode_list,
4945 silc_buffer_truelen(client_mode_list));
4947 silc_hash_table_list(channel->user_list, &htl);
4948 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4950 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4951 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4952 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4953 silc_buffer_free(idp);
4955 /* Client's mode on channel */
4956 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4957 silc_buffer_pull(client_mode_list, 4);
4961 silc_hash_table_list_reset(&htl);
4962 silc_buffer_push(client_id_list,
4963 client_id_list->data - client_id_list->head);
4964 silc_buffer_push(client_mode_list,
4965 client_mode_list->data - client_mode_list->head);
4967 *user_list = client_id_list;
4968 *mode_list = client_mode_list;
4969 *user_count = list_count;
4973 /* Saves users and their modes to the `channel'. */
4975 void silc_server_save_users_on_channel(SilcServer server,
4976 SilcPacketStream sock,
4977 SilcChannelEntry channel,
4978 SilcClientID *noadd,
4979 SilcBuffer user_list,
4980 SilcBuffer mode_list,
4981 SilcUInt32 user_count)
4987 SilcClientEntry client;
4988 SilcIDCacheEntry cache;
4989 SilcChannelClientEntry chl;
4991 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4992 channel->channel_name));
4994 for (i = 0; i < user_count; i++) {
4996 SILC_GET16_MSB(idp_len, user_list->data + 2);
4998 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5000 silc_buffer_pull(user_list, idp_len);
5003 SILC_GET32_MSB(mode, mode_list->data);
5004 silc_buffer_pull(mode_list, 4);
5006 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5011 /* Check if we have this client cached already. */
5012 client = silc_idlist_find_client_by_id(server->local_list,
5014 server->server_type, &cache);
5016 client = silc_idlist_find_client_by_id(server->global_list,
5018 server->server_type, &cache);
5020 /* If router did not find such Client ID in its lists then this must
5021 be bogus client or some router in the net is buggy. */
5022 if (server->server_type != SILC_SERVER)
5025 /* We don't have that client anywhere, add it. The client is added
5026 to global list since server didn't have it in the lists so it must be
5028 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5029 silc_id_dup(&id.u.client_id,
5031 silc_packet_get_context(sock),
5034 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5038 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5041 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5042 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5043 "%s", channel->channel_name));
5047 if (!silc_server_client_on_channel(client, channel, &chl)) {
5048 /* Client was not on the channel, add it. */
5049 chl = silc_calloc(1, sizeof(*chl));
5050 chl->client = client;
5052 chl->channel = channel;
5053 silc_hash_table_add(channel->user_list, chl->client, chl);
5054 silc_hash_table_add(client->channels, chl->channel, chl);
5055 channel->user_count++;
5063 /* Saves channels and channels user modes to the `client'. Removes
5064 the client from those channels that are not sent in the list but
5067 void silc_server_save_user_channels(SilcServer server,
5068 SilcPacketStream sock,
5069 SilcClientEntry client,
5070 SilcBuffer channels,
5071 SilcBuffer channels_user_modes)
5074 SilcUInt32 *chumodes;
5075 SilcChannelPayload entry;
5076 SilcChannelEntry channel;
5077 SilcChannelID channel_id;
5078 SilcChannelClientEntry chl;
5079 SilcHashTable ht = NULL;
5080 SilcHashTableList htl;
5084 if (!channels || !channels_user_modes ||
5085 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5088 ch = silc_channel_payload_parse_list(channels->data,
5089 silc_buffer_len(channels));
5090 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5092 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5093 NULL, NULL, NULL, TRUE);
5094 silc_dlist_start(ch);
5095 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5096 /* Check if we have this channel, and add it if we don't have it.
5097 Also add the client on the channel unless it is there already. */
5098 if (!silc_channel_get_id_parse(entry, &channel_id))
5100 channel = silc_idlist_find_channel_by_id(server->local_list,
5103 channel = silc_idlist_find_channel_by_id(server->global_list,
5106 if (server->server_type != SILC_SERVER) {
5111 /* We don't have that channel anywhere, add it. */
5112 name = silc_channel_get_name(entry, NULL);
5113 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5114 silc_id_dup(&channel_id,
5116 server->router, NULL, NULL, 0);
5123 channel->mode = silc_channel_get_mode(entry);
5125 /* Add the client on the channel */
5126 if (!silc_server_client_on_channel(client, channel, &chl)) {
5127 chl = silc_calloc(1, sizeof(*chl));
5128 chl->client = client;
5129 chl->mode = chumodes[i++];
5130 chl->channel = channel;
5131 silc_hash_table_add(channel->user_list, chl->client, chl);
5132 silc_hash_table_add(client->channels, chl->channel, chl);
5133 channel->user_count++;
5136 chl->mode = chumodes[i++];
5139 silc_hash_table_add(ht, channel, channel);
5141 silc_channel_payload_list_free(ch);
5142 silc_free(chumodes);
5146 /* Go through the list again and remove client from channels that
5147 are no part of the list. */
5149 silc_hash_table_list(client->channels, &htl);
5150 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5151 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5152 silc_hash_table_del(chl->channel->user_list, chl->client);
5153 silc_hash_table_del(chl->client->channels, chl->channel);
5157 silc_hash_table_list_reset(&htl);
5158 silc_hash_table_free(ht);
5160 silc_hash_table_list(client->channels, &htl);
5161 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5162 silc_hash_table_del(chl->channel->user_list, chl->client);
5163 silc_hash_table_del(chl->client->channels, chl->channel);
5166 silc_hash_table_list_reset(&htl);
5170 /* Lookups route to the client indicated by the `id_data'. The connection
5171 object and internal data object is returned. Returns NULL if route
5172 could not be found to the client. If the `client_id' is specified then
5173 it is used and the `id_data' is ignored. */
5176 silc_server_get_client_route(SilcServer server,
5177 unsigned char *id_data,
5179 SilcClientID *client_id,
5180 SilcIDListData *idata,
5181 SilcClientEntry *client_entry)
5183 SilcClientID *id, clid;
5184 SilcClientEntry client;
5186 SILC_LOG_DEBUG(("Start"));
5189 *client_entry = NULL;
5191 /* Decode destination Client ID */
5193 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5195 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5197 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5200 /* If the destination belongs to our server we don't have to route
5201 the packet anywhere but to send it to the local destination. */
5202 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5206 /* If we are router and the client has router then the client is in
5207 our cell but not directly connected to us. */
5208 if (server->server_type == SILC_ROUTER && client->router) {
5209 /* We are of course in this case the client's router thus the route
5210 to the client is the server who owns the client. So, we will send
5211 the packet to that server. */
5213 *idata = (SilcIDListData)client->router;
5214 return client->router->connection;
5217 /* Seems that client really is directly connected to us */
5219 *idata = (SilcIDListData)client;
5221 *client_entry = client;
5222 return client->connection;
5225 /* Destination belongs to someone not in this server. If we are normal
5226 server our action is to send the packet to our router. */
5227 if (server->server_type != SILC_ROUTER && !server->standalone) {
5230 *idata = (SilcIDListData)server->router;
5231 return SILC_PRIMARY_ROUTE(server);
5234 /* We are router and we will perform route lookup for the destination
5235 and send the packet to fastest route. */
5236 if (server->server_type == SILC_ROUTER && !server->standalone) {
5237 /* Check first that the ID is valid */
5238 client = silc_idlist_find_client_by_id(server->global_list, id,
5241 SilcPacketStream dst_sock;
5243 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5246 if (idata && dst_sock)
5247 *idata = silc_packet_get_context(dst_sock);
5256 /* Encodes and returns channel list of channels the `client' has joined.
5257 Secret channels are not put to the list. */
5259 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5260 SilcClientEntry client,
5261 SilcBool get_private,
5262 SilcBool get_secret,
5263 SilcBuffer *user_mode_list)
5265 SilcBuffer buffer = NULL;
5266 SilcChannelEntry channel;
5267 SilcChannelClientEntry chl;
5268 SilcHashTableList htl;
5269 unsigned char cid[32];
5271 SilcUInt16 name_len;
5275 *user_mode_list = NULL;
5277 silc_hash_table_list(client->channels, &htl);
5278 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5279 channel = chl->channel;
5281 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5283 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5286 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5287 name_len = strlen(channel->channel_name);
5289 len = 4 + name_len + id_len + 4;
5290 buffer = silc_buffer_realloc(buffer,
5292 silc_buffer_truelen(buffer) + len : len));
5293 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5294 silc_buffer_format(buffer,
5295 SILC_STR_UI_SHORT(name_len),
5296 SILC_STR_DATA(channel->channel_name, name_len),
5297 SILC_STR_UI_SHORT(id_len),
5298 SILC_STR_DATA(cid, id_len),
5299 SILC_STR_UI_INT(chl->channel->mode),
5301 silc_buffer_pull(buffer, len);
5303 if (user_mode_list) {
5305 silc_buffer_realloc(*user_mode_list,
5307 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5308 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5309 (*user_mode_list)->data));
5310 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5311 silc_buffer_pull(*user_mode_list, 4);
5314 silc_hash_table_list_reset(&htl);
5317 silc_buffer_push(buffer, buffer->data - buffer->head);
5318 if (user_mode_list && *user_mode_list)
5319 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5320 (*user_mode_list)->head));
5325 /* Task callback used to retrieve network statistical information from
5326 router server once in a while. */
5328 SILC_TASK_CALLBACK(silc_server_get_stats)
5330 SilcServer server = (SilcServer)context;
5331 SilcBuffer idp, packet;
5333 if (!server->standalone) {
5334 SILC_LOG_DEBUG(("Retrieving stats from router"));
5335 server->stat.commands_sent++;
5336 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5338 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5339 ++server->cmd_ident, 1,
5341 silc_buffer_len(idp));
5342 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5343 SILC_PACKET_COMMAND, 0, packet->data,
5344 silc_buffer_len(packet));
5345 silc_buffer_free(packet);
5346 silc_buffer_free(idp);
5350 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,