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 SILC_TASK_CALLBACK(silc_server_packet_error_timeout);
31 static void silc_server_accept_new_connection(SilcNetStatus status,
34 static void silc_server_packet_parse_type(SilcServer server,
35 SilcPacketStream sock,
37 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
41 /************************ Static utility functions **************************/
43 /* SKE public key verification callback */
46 silc_server_verify_key(SilcSKE ske,
47 SilcPublicKey public_key,
49 SilcSKEVerifyCbCompletion completion,
50 void *completion_context)
52 SilcPacketStream sock = context;
53 SilcUnknownEntry entry = silc_packet_get_context(sock);
55 SILC_LOG_DEBUG(("Verifying public key"));
57 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
58 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
59 entry->hostname, entry->ip, entry->port,
60 silc_pkcs_get_type(public_key)));
61 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
66 /* We accept all keys without explicit verification */
67 completion(ske, SILC_SKE_STATUS_OK, completion_context);
71 /************************ Packet engine callbacks ***************************/
73 /* Packet engine callback to receive a packet */
75 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
76 SilcPacketStream stream,
78 void *callback_context,
81 SilcServer server = callback_context;
82 SilcIDListData idata = stream_context;
87 /* Packets we do not handle */
88 switch (packet->type) {
89 case SILC_PACKET_HEARTBEAT:
90 case SILC_PACKET_SUCCESS:
91 case SILC_PACKET_FAILURE:
92 case SILC_PACKET_REJECT:
93 case SILC_PACKET_KEY_EXCHANGE:
94 case SILC_PACKET_KEY_EXCHANGE_1:
95 case SILC_PACKET_KEY_EXCHANGE_2:
96 case SILC_PACKET_REKEY_DONE:
97 case SILC_PACKET_CONNECTION_AUTH:
102 /* Only specific packets can come without source ID present. */
103 if ((!packet->src_id ||
104 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
105 packet->type != SILC_PACKET_NEW_CLIENT &&
106 packet->type != SILC_PACKET_NEW_SERVER &&
107 packet->type != SILC_PACKET_RESUME_CLIENT &&
108 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
109 packet->type != SILC_PACKET_DISCONNECT)
112 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and
113 for unregistered connection. */
114 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
115 packet->type == SILC_PACKET_NEW_SERVER) &&
116 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
119 /* Ignore packets from disabled connection */
120 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
121 packet->type != SILC_PACKET_HEARTBEAT &&
122 packet->type != SILC_PACKET_RESUME_ROUTER &&
123 packet->type != SILC_PACKET_REKEY)
126 /* Check that the the current client ID is same as in the client's packet. */
127 if (idata->conn_type == SILC_CONN_CLIENT) {
128 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
129 SilcClientID client_id;
131 if (client->id && packet->src_id &&
132 silc_id_str2id(packet->src_id, packet->src_id_len,
133 packet->src_id_type, &client_id, sizeof(client_id))) {
134 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
135 SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
136 silc_get_packet_name(packet->type)));
142 if (server->server_type == SILC_ROUTER) {
143 /* Route the packet if it is not destined to us. Other ID types but
144 server are handled separately after processing them. */
145 if (packet->dst_id &&
146 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
147 packet->dst_id_type == SILC_ID_SERVER &&
148 idata->conn_type != SILC_CONN_CLIENT &&
149 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
150 SilcPacketStream conn;
151 SilcServerID server_id;
153 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
154 &server_id, sizeof(server_id));
156 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
158 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
159 silc_id_render(&server_id, SILC_ID_SERVER)));
163 silc_server_packet_route(server, conn, packet);
164 silc_packet_free(packet);
169 /* Broadcast packet if it is marked as broadcast packet and it is
170 originated from router and we are router. */
171 if (server->server_type == SILC_ROUTER &&
172 idata->conn_type == SILC_CONN_ROUTER &&
173 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
174 /* Broadcast to our primary route */
175 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
177 /* If we have backup routers then we need to feed all broadcast
178 data to those servers. */
179 silc_server_backup_broadcast(server, stream, packet);
183 silc_server_packet_parse_type(server, stream, packet);
188 /* Packet engine callback to indicate end of stream */
190 static void silc_server_packet_eos(SilcPacketEngine engine,
191 SilcPacketStream stream,
192 void *callback_context,
193 void *stream_context)
195 SilcServer server = callback_context;
196 SilcIDListData idata = silc_packet_get_context(stream);
198 SILC_LOG_DEBUG(("End of stream received, sock %p", stream));
203 /* Remove any possible pending packet error timeout */
204 silc_schedule_task_del_by_all(server->schedule, 0,
205 silc_server_packet_error_timeout, stream);
207 if (server->router_conn && server->router_conn->sock == stream &&
208 !server->router && server->standalone) {
209 if (idata->sconn && idata->sconn->callback)
210 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
211 silc_server_create_connections(server);
212 silc_server_free_sock_user_data(server, stream, NULL);
214 /* If backup disconnected then mark that resuming will not be allowed */
215 if (server->server_type == SILC_ROUTER && !server->backup_router &&
216 idata->conn_type == SILC_CONN_SERVER) {
217 SilcServerEntry server_entry = (SilcServerEntry)idata;
218 if (server_entry->server_type == SILC_BACKUP_ROUTER)
219 server->backup_closed = TRUE;
222 if (idata->sconn && idata->sconn->callback)
223 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
224 silc_server_free_sock_user_data(server, stream, NULL);
227 silc_server_close_connection(server, stream);
230 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
232 SilcServer server = app_context;
233 SilcPacketStream stream = context;
234 SilcIDListData idata = silc_packet_get_context(stream);
239 if (server->router_conn && server->router_conn->sock == stream &&
240 !server->router && server->standalone) {
241 if (idata->sconn && idata->sconn->callback)
242 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
243 silc_server_create_connections(server);
244 silc_server_free_sock_user_data(server, stream, NULL);
246 /* If backup disconnected then mark that resuming will not be allowed */
247 if (server->server_type == SILC_ROUTER && !server->backup_router &&
248 idata->conn_type == SILC_CONN_SERVER) {
249 SilcServerEntry server_entry = (SilcServerEntry)idata;
250 if (server_entry->server_type == SILC_BACKUP_ROUTER)
251 server->backup_closed = TRUE;
254 if (idata->sconn && idata->sconn->callback)
255 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
256 silc_server_free_sock_user_data(server, stream, NULL);
259 silc_server_close_connection(server, stream);
262 /* Packet engine callback to indicate error */
264 static void silc_server_packet_error(SilcPacketEngine engine,
265 SilcPacketStream stream,
266 SilcPacketError error,
267 void *callback_context,
268 void *stream_context)
270 SilcServer server = callback_context;
271 SilcIDListData idata = silc_packet_get_context(stream);
272 SilcStream sock = silc_packet_stream_get_stream(stream);
276 SILC_LOG_DEBUG(("Packet error, sock %p", stream));
281 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
284 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
285 SILC_CONNTYPE_STRING(idata->conn_type),
286 silc_packet_error_string(error)));
288 if (!silc_packet_stream_is_valid(stream))
291 /* In case we get here many times, register only one timeout */
292 silc_schedule_task_del_by_all(server->schedule, 0,
293 silc_server_packet_error_timeout, stream);
295 /* Close connection with random timeout */
296 silc_schedule_task_add_timeout(server->schedule,
297 silc_server_packet_error_timeout, stream,
298 silc_rng_get_byte(server->rng) % 10, 0);
301 /* Packet stream callbacks */
302 static SilcPacketCallbacks silc_server_stream_cbs =
304 silc_server_packet_receive,
305 silc_server_packet_eos,
306 silc_server_packet_error
309 /* Parses the packet type and calls what ever routines the packet type
310 requires. This is done for all incoming packets. */
312 static void silc_server_packet_parse_type(SilcServer server,
313 SilcPacketStream sock,
316 SilcPacketType type = packet->type;
317 SilcIDListData idata = silc_packet_get_context(sock);
319 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
320 silc_get_packet_name(type), packet->flags));
322 /* Parse the packet type */
324 case SILC_PACKET_NOTIFY:
326 * Received notify packet. Server can receive notify packets from
327 * router. Server then relays the notify messages to clients if needed.
329 if (packet->flags & SILC_PACKET_FLAG_LIST)
330 silc_server_notify_list(server, sock, packet);
332 silc_server_notify(server, sock, packet);
336 * Private Message packets
338 case SILC_PACKET_PRIVATE_MESSAGE:
340 * Received private message packet. The packet is coming from either
343 if (packet->flags & SILC_PACKET_FLAG_LIST)
345 idata->last_receive = time(NULL);
346 silc_server_private_message(server, sock, packet);
352 case SILC_PACKET_CHANNEL_MESSAGE:
354 * Received channel message. Channel messages are special packets
355 * (although probably most common ones) thus they are handled
358 if (packet->flags & SILC_PACKET_FLAG_LIST)
360 idata->last_receive = time(NULL);
361 silc_server_channel_message(server, sock, packet);
367 case SILC_PACKET_COMMAND:
369 * Recived command. Processes the command request and allocates the
370 * command context and calls the command.
372 if (packet->flags & SILC_PACKET_FLAG_LIST)
374 server->stat.commands_received++;
375 silc_server_command_process(server, sock, packet);
378 case SILC_PACKET_COMMAND_REPLY:
380 * Received command reply packet. Received command reply to command. It
381 * may be reply to command sent by us or reply to command sent by client
382 * that we've routed further.
384 if (packet->flags & SILC_PACKET_FLAG_LIST)
386 server->stat.commands_received++;
387 silc_server_command_reply(server, sock, packet);
390 case SILC_PACKET_DISCONNECT:
393 char *message = NULL;
394 const char *hostname, *ip;
396 if (packet->flags & SILC_PACKET_FLAG_LIST)
398 if (silc_buffer_len(&packet->buffer) < 1)
401 status = (SilcStatus)packet->buffer.data[0];
402 if (silc_buffer_len(&packet->buffer) > 1 &&
403 silc_utf8_valid(packet->buffer.data + 1,
404 silc_buffer_len(&packet->buffer) - 1))
405 message = silc_memdup(packet->buffer.data + 1,
406 silc_buffer_len(&packet->buffer) - 1);
408 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
409 NULL, &hostname, &ip, NULL))
412 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
413 silc_get_status_message(status), status,
414 message ? message : ""));
418 /* Do not switch to backup in case of error */
419 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
421 /* If backup disconnected then mark that resuming will not be allowed */
422 if (server->server_type == SILC_ROUTER && !server->backup_router &&
423 idata->conn_type == SILC_CONN_SERVER) {
424 SilcServerEntry server_entry = (SilcServerEntry)idata;
425 if (server_entry->server_type == SILC_BACKUP_ROUTER)
426 server->backup_closed = TRUE;
429 /* Handle the disconnection from our end too */
430 if (SILC_IS_LOCAL(idata))
431 silc_server_free_sock_user_data(server, sock, NULL);
432 silc_server_close_connection(server, sock);
433 server->backup_noswitch = FALSE;
437 case SILC_PACKET_CHANNEL_KEY:
439 * Received key for channel. As channels are created by the router
440 * the keys are as well. We will distribute the key to all of our
441 * locally connected clients on the particular channel. Router
442 * never receives this channel and thus is ignored.
444 if (packet->flags & SILC_PACKET_FLAG_LIST)
446 silc_server_channel_key(server, sock, packet);
449 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
451 * Private message key packet.
453 if (packet->flags & SILC_PACKET_FLAG_LIST)
455 silc_server_private_message_key(server, sock, packet);
458 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
460 * Connection authentication request packet. When we receive this packet
461 * we will send to the other end information about our mandatory
462 * authentication method for the connection. This packet maybe received
465 if (packet->flags & SILC_PACKET_FLAG_LIST)
467 silc_server_connection_auth_request(server, sock, packet);
470 case SILC_PACKET_NEW_ID:
472 * Received New ID packet. This includes some new ID that has been
473 * created. It may be for client, server or channel. This is the way
474 * to distribute information about new registered entities in the
477 if (packet->flags & SILC_PACKET_FLAG_LIST)
478 silc_server_new_id_list(server, sock, packet);
480 silc_server_new_id(server, sock, packet);
483 case SILC_PACKET_NEW_CLIENT:
485 * Received new client packet. This includes client information that
486 * we will use to create initial client ID. After creating new
487 * ID we will send it to the client.
489 if (packet->flags & SILC_PACKET_FLAG_LIST)
491 silc_server_new_client(server, sock, packet);
494 case SILC_PACKET_NEW_SERVER:
496 * Received new server packet. This includes Server ID and some other
497 * information that we may save. This is received after server has
500 if (packet->flags & SILC_PACKET_FLAG_LIST)
502 silc_server_new_server(server, sock, packet);
505 case SILC_PACKET_NEW_CHANNEL:
507 * Received new channel packet. Information about new channel in the
508 * network are distributed using this packet.
510 if (packet->flags & SILC_PACKET_FLAG_LIST)
511 silc_server_new_channel_list(server, sock, packet);
513 silc_server_new_channel(server, sock, packet);
516 case SILC_PACKET_HEARTBEAT:
518 * Received heartbeat.
520 if (packet->flags & SILC_PACKET_FLAG_LIST)
524 case SILC_PACKET_KEY_AGREEMENT:
526 * Received heartbeat.
528 if (packet->flags & SILC_PACKET_FLAG_LIST)
530 silc_server_key_agreement(server, sock, packet);
533 case SILC_PACKET_REKEY:
535 * Received re-key packet. The sender wants to regenerate the session
538 if (packet->flags & SILC_PACKET_FLAG_LIST)
540 silc_server_rekey(server, sock, packet);
543 case SILC_PACKET_FTP:
545 if (packet->flags & SILC_PACKET_FLAG_LIST)
547 silc_server_ftp(server, sock, packet);
550 case SILC_PACKET_RESUME_CLIENT:
552 if (packet->flags & SILC_PACKET_FLAG_LIST)
554 silc_server_resume_client(server, sock, packet);
557 case SILC_PACKET_RESUME_ROUTER:
558 /* Resume router packet received. This packet is received for backup
559 router resuming protocol. */
560 if (packet->flags & SILC_PACKET_FLAG_LIST)
562 silc_server_backup_resume_router(server, sock, packet);
566 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
571 /****************************** Server API **********************************/
573 /* Allocates a new SILC server object. This has to be done before the server
574 can be used. After allocation one must call silc_server_init to initialize
575 the server. The new allocated server object is returned to the new_server
578 SilcBool silc_server_alloc(SilcServer *new_server)
582 SILC_LOG_DEBUG(("Allocating new server object"));
584 server = silc_calloc(1, sizeof(*server));
587 server->server_type = SILC_SERVER;
588 server->standalone = TRUE;
589 server->local_list = silc_calloc(1, sizeof(*server->local_list));
590 if (!server->local_list)
592 server->global_list = silc_calloc(1, sizeof(*server->global_list));
593 if (!server->global_list)
595 server->pending_commands = silc_dlist_init();
596 if (!server->pending_commands)
598 server->listeners = silc_dlist_init();
599 if (!server->listeners)
601 server->repository = silc_skr_alloc();
602 if (!server->repository)
604 server->conns = silc_dlist_init();
607 server->expired_clients = silc_dlist_init();
608 if (!server->expired_clients)
611 *new_server = server;
616 /* Free's the SILC server object. This is called at the very end before
619 void silc_server_free(SilcServer server)
622 SilcIDCacheEntry cache;
623 SilcIDListData idata;
625 SILC_LOG_DEBUG(("Free server %p", server));
630 silc_server_backup_free(server);
631 silc_server_config_unref(&server->config_ref);
633 silc_rng_free(server->rng);
634 if (server->public_key)
635 silc_pkcs_public_key_free(server->public_key);
636 if (server->private_key)
637 silc_pkcs_private_key_free(server->private_key);
638 if (server->pending_commands)
639 silc_dlist_uninit(server->pending_commands);
640 if (server->id_entry) {
641 if (server->id_entry->data.sconn)
642 silc_schedule_task_del_by_context(server->schedule,
643 server->id_entry->data.sconn->sock);
644 silc_idlist_del_server(server->local_list, server->id_entry);
647 /* Delete all channels */
648 if (silc_idcache_get_all(server->local_list->channels, &list)) {
649 silc_list_start(list);
650 while ((cache = silc_list_get(list)))
651 silc_idlist_del_channel(server->local_list, cache->context);
653 if (silc_idcache_get_all(server->global_list->channels, &list)) {
654 silc_list_start(list);
655 while ((cache = silc_list_get(list)))
656 silc_idlist_del_channel(server->global_list, cache->context);
659 /* Delete all clients */
660 if (silc_idcache_get_all(server->local_list->clients, &list)) {
661 silc_list_start(list);
662 while ((cache = silc_list_get(list))) {
663 silc_schedule_task_del_by_context(server->schedule, cache->context);
664 silc_idlist_del_client(server->local_list, cache->context);
667 if (silc_idcache_get_all(server->global_list->clients, &list)) {
668 silc_list_start(list);
669 while ((cache = silc_list_get(list))) {
670 silc_schedule_task_del_by_context(server->schedule, cache->context);
671 silc_idlist_del_client(server->global_list, cache->context);
675 /* Delete all servers */
676 if (silc_idcache_get_all(server->local_list->servers, &list)) {
677 silc_list_start(list);
678 while ((cache = silc_list_get(list))) {
679 idata = (SilcIDListData)cache->context;
681 silc_schedule_task_del_by_context(server->schedule,
683 silc_idlist_del_server(server->local_list, cache->context);
686 if (silc_idcache_get_all(server->global_list->servers, &list)) {
687 while ((cache = silc_list_get(list))) {
688 idata = (SilcIDListData)cache->context;
690 silc_schedule_task_del_by_context(server->schedule,
692 silc_idlist_del_server(server->global_list, cache->context);
696 silc_schedule_task_del_by_context(server->schedule, server);
697 silc_schedule_uninit(server->schedule);
698 server->schedule = NULL;
700 silc_idcache_free(server->local_list->clients);
701 silc_idcache_free(server->local_list->servers);
702 silc_idcache_free(server->local_list->channels);
703 silc_idcache_free(server->global_list->clients);
704 silc_idcache_free(server->global_list->servers);
705 silc_idcache_free(server->global_list->channels);
706 silc_hash_table_free(server->watcher_list);
707 silc_hash_table_free(server->watcher_list_pk);
708 silc_hash_free(server->md5hash);
709 silc_hash_free(server->sha1hash);
711 silc_dlist_uninit(server->listeners);
712 silc_dlist_uninit(server->conns);
713 silc_dlist_uninit(server->expired_clients);
714 silc_skr_free(server->repository);
715 silc_packet_engine_stop(server->packet_engine);
717 silc_free(server->local_list);
718 silc_free(server->global_list);
719 silc_free(server->server_name);
720 silc_free(server->id);
723 silc_hmac_unregister_all();
724 silc_hash_unregister_all();
725 silc_cipher_unregister_all();
726 silc_pkcs_unregister_all();
729 /* Creates a new server listener. */
731 static SilcNetListener
732 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
734 SilcNetListener listener;
737 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
738 server->config->require_reverse_lookup,
740 silc_server_accept_new_connection, server);
742 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
750 /* Adds a secondary listener. */
752 SilcBool silc_server_init_secondary(SilcServer server)
754 SilcServerConfigServerInfoInterface *interface;
755 SilcNetListener listener;
757 for (interface = server->config->server_info->secondary; interface;
758 interface = interface->next) {
759 listener = silc_server_listen(server, interface->server_ip,
763 silc_dlist_add(server->listeners, listener);
769 /* Initializes the entire SILC server. This is called always before running
770 the server. This is called only once at the initialization of the program.
771 This binds the server to its listenning port. After this function returns
772 one should call silc_server_run to start the server. This returns TRUE
773 when everything is ok to run the server. Configuration file must be
774 read and parsed before calling this. */
776 SilcBool silc_server_init(SilcServer server)
779 SilcServerEntry id_entry;
780 SilcNetListener listener;
784 SILC_LOG_DEBUG(("Initializing server"));
786 server->starttime = time(NULL);
788 /* Take config object for us */
789 silc_server_config_ref(&server->config_ref, server->config,
793 /* Set debugging on if configured */
794 if (server->config->debug_string) {
795 silc_log_debug(TRUE);
796 silc_log_set_debug_string(server->config->debug_string);
798 #endif /* SILC_DEBUG */
800 /* Steal public and private key from the config object */
801 server->public_key = server->config->server_info->public_key;
802 server->private_key = server->config->server_info->private_key;
803 server->config->server_info->public_key = NULL;
804 server->config->server_info->private_key = NULL;
806 /* Register all configured ciphers, PKCS and hash functions. */
807 if (!silc_server_config_register_ciphers(server))
808 silc_cipher_register_default();
809 if (!silc_server_config_register_pkcs(server))
810 silc_pkcs_register_default();
811 if (!silc_server_config_register_hashfuncs(server))
812 silc_hash_register_default();
813 if (!silc_server_config_register_hmacs(server))
814 silc_hmac_register_default();
816 /* Initialize random number generator for the server. */
817 server->rng = silc_rng_alloc();
818 silc_rng_init(server->rng);
819 silc_rng_global_init(server->rng);
821 /* Initialize hash functions for server to use */
822 silc_hash_alloc("md5", &server->md5hash);
823 silc_hash_alloc("sha1", &server->sha1hash);
825 /* Initialize the scheduler */
826 server->schedule = silc_schedule_init(server->config->param.connections_max,
828 if (!server->schedule)
831 /* First, register log files configuration for error output */
832 silc_server_config_setlogfiles(server);
834 /* Initialize ID caches */
835 server->local_list->clients =
836 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
838 server->local_list->servers =
839 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
841 server->local_list->channels =
842 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
845 /* These are allocated for normal server as well as these hold some
846 global information that the server has fetched from its router. For
847 router these are used as they are supposed to be used on router. */
848 server->global_list->clients =
849 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
851 server->global_list->servers =
852 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
854 server->global_list->channels =
855 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
858 /* Init watcher lists */
859 server->watcher_list =
860 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
861 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
863 if (!server->watcher_list)
865 server->watcher_list_pk =
866 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
867 silc_hash_public_key_compare, NULL,
869 if (!server->watcher_list_pk)
872 /* Create TCP listener */
873 listener = silc_server_listen(
875 server->config->server_info->primary == NULL ? NULL :
876 server->config->server_info->primary->server_ip,
877 server->config->server_info->primary == NULL ? 0 :
878 server->config->server_info->primary->port);
881 silc_dlist_add(server->listeners, listener);
883 /* Create a Server ID for the server. */
884 port = silc_net_listener_get_port(listener, NULL);
885 ip = silc_net_listener_get_ip(listener, NULL);
886 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
887 server->config->server_info->primary->public_ip :
888 ip[0], port[0], server->rng, &id);
897 server->server_name = server->config->server_info->server_name;
898 server->config->server_info->server_name = NULL;
899 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
900 sizeof(server->id_string), &server->id_string_len);
902 /* Add ourselves to the server list. We don't have a router yet
903 beacuse we haven't established a route yet. It will be done later.
904 For now, NULL is sent as router. This allocates new entry to
907 silc_idlist_add_server(server->local_list, strdup(server->server_name),
909 silc_id_dup(server->id, SILC_ID_SERVER),
912 SILC_LOG_ERROR(("Could not add local server to cache"));
915 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
916 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
917 SILC_CONN_SERVER : SILC_CONN_ROUTER);
918 server->id_entry = id_entry;
920 /* Create secondary TCP listeners */
921 if (silc_server_init_secondary(server) == FALSE)
924 server->listenning = TRUE;
926 /* Create connections to configured routers. */
927 silc_server_create_connections(server);
929 /* If server connections has been configured then we must be router as
930 normal server cannot have server connections, only router connections. */
931 if (server->config->servers) {
932 SilcServerConfigServer *ptr = server->config->servers;
934 server->server_type = SILC_ROUTER;
936 if (ptr->backup_router) {
937 server->server_type = SILC_BACKUP_ROUTER;
938 server->backup_router = TRUE;
939 server->id_entry->server_type = SILC_BACKUP_ROUTER;
946 if (server->server_type != SILC_ROUTER) {
947 server->stat.servers = 1;
948 server->stat.cell_servers = 1;
950 server->stat.routers = 1;
953 /* If we are normal server we'll retrieve network statisticial information
954 once in a while from the router. */
955 if (server->server_type != SILC_ROUTER)
956 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
959 /* Start packet engine */
960 server->packet_engine =
961 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
962 &silc_server_stream_cbs, server);
963 if (!server->packet_engine)
966 /* Register client entry expiration timeout */
967 silc_schedule_task_add_timeout(server->schedule,
968 silc_server_purge_expired_clients, server,
971 /* Initialize HTTP server */
972 silc_server_http_init(server);
974 SILC_LOG_DEBUG(("Server initialized"));
976 /* We are done here, return succesfully */
980 silc_server_config_unref(&server->config_ref);
984 /* Task callback to close a socket connection after rehash */
986 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
988 SilcServer server = app_context;
989 SilcPacketStream sock = context;
990 SilcIDListData idata = silc_packet_get_context(sock);
991 const char *hostname;
994 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
995 NULL, &hostname, NULL, &port);
997 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
998 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
999 silc_schedule_task_del_by_context(server->schedule, sock);
1000 silc_server_disconnect_remote(server, sock,
1001 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1002 "This connection is removed from "
1004 silc_server_free_sock_user_data(server, sock, NULL);
1007 /* This function basically reads the config file again and switches the config
1008 object pointed by the server object. After that, we have to fix various
1009 things such as the server_name and the listening ports.
1010 Keep in mind that we no longer have the root privileges at this point. */
1012 SilcBool silc_server_rehash(SilcServer server)
1014 SilcServerConfig newconfig;
1016 SILC_LOG_INFO(("Rehashing server"));
1018 /* Reset the logging system */
1019 silc_log_quick(TRUE);
1020 silc_log_flush_all();
1022 /* Start the main rehash phase (read again the config file) */
1023 newconfig = silc_server_config_alloc(server->config_file, server);
1025 SILC_LOG_ERROR(("Rehash FAILED."));
1029 /* Fix the server_name field */
1030 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1031 silc_free(server->server_name);
1033 /* Check server name */
1034 server->server_name =
1035 silc_identifier_check(newconfig->server_info->server_name,
1036 strlen(newconfig->server_info->server_name),
1037 SILC_STRING_LOCALE, 256, NULL);
1038 if (!server->server_name) {
1039 SILC_LOG_ERROR(("Malformed server name string '%s'",
1040 server->config->server_info->server_name));
1044 /* Update the idcache list with a fresh pointer */
1045 silc_free(server->id_entry->server_name);
1046 server->id_entry->server_name = strdup(server->server_name);
1047 silc_idcache_update_by_context(server->local_list->servers,
1048 server->id_entry, NULL,
1049 strdup(server->id_entry->server_name),
1054 silc_server_config_setlogfiles(server);
1056 /* Change new key pair if necessary */
1057 if (newconfig->server_info->public_key &&
1058 !silc_pkcs_public_key_compare(server->public_key,
1059 newconfig->server_info->public_key)) {
1060 silc_pkcs_public_key_free(server->public_key);
1061 silc_pkcs_private_key_free(server->private_key);
1062 server->public_key = newconfig->server_info->public_key;
1063 server->private_key = newconfig->server_info->private_key;
1064 newconfig->server_info->public_key = NULL;
1065 newconfig->server_info->private_key = NULL;
1068 /* Check for unconfigured server and router connections and close
1069 connections that were unconfigured. */
1071 if (server->config->routers) {
1072 SilcServerConfigRouter *ptr;
1073 SilcServerConfigRouter *newptr;
1076 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1079 /* Check whether new config has this one too */
1080 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1081 if (silc_string_compare(newptr->host, ptr->host) &&
1082 newptr->port == ptr->port &&
1083 newptr->initiator == ptr->initiator) {
1089 if (!found && ptr->host) {
1090 /* Remove this connection */
1091 SilcPacketStream sock;
1092 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1093 ptr->host, ptr->port);
1095 silc_schedule_task_add_timeout(server->schedule,
1096 silc_server_rehash_close_connection,
1102 if (server->config->servers) {
1103 SilcServerConfigServer *ptr;
1104 SilcServerConfigServer *newptr;
1107 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1110 /* Check whether new config has this one too */
1111 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1112 if (silc_string_compare(newptr->host, ptr->host)) {
1118 if (!found && ptr->host) {
1119 /* Remove this connection */
1120 SilcPacketStream sock;
1121 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1124 silc_schedule_task_add_timeout(server->schedule,
1125 silc_server_rehash_close_connection,
1131 if (server->config->clients) {
1132 SilcServerConfigClient *ptr;
1133 SilcServerConfigClient *newptr;
1136 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1139 /* Check whether new config has this one too */
1140 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1141 if (silc_string_compare(newptr->host, ptr->host)) {
1147 if (!found && ptr->host) {
1148 /* Remove this connection */
1149 SilcPacketStream sock;
1150 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1153 silc_schedule_task_add_timeout(server->schedule,
1154 silc_server_rehash_close_connection,
1160 /* Create connections after rehash */
1161 silc_server_create_connections(server);
1163 /* Check whether our router status has changed */
1164 if (newconfig->servers) {
1165 SilcServerConfigServer *ptr = newconfig->servers;
1167 server->server_type = SILC_ROUTER;
1169 if (ptr->backup_router) {
1170 server->server_type = SILC_BACKUP_ROUTER;
1171 server->backup_router = TRUE;
1172 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1179 /* Our old config is gone now. We'll unreference our reference made in
1180 silc_server_init and then destroy it since we are destroying it
1181 underneath the application (layer which called silc_server_init). */
1182 silc_server_config_unref(&server->config_ref);
1183 silc_server_config_destroy(server->config);
1185 /* Take new config context */
1186 server->config = newconfig;
1187 silc_server_config_ref(&server->config_ref, server->config, server->config);
1190 /* Set debugging on if configured */
1191 if (server->config->debug_string) {
1192 silc_log_debug(TRUE);
1193 silc_log_set_debug_string(server->config->debug_string);
1195 #endif /* SILC_DEBUG */
1197 SILC_LOG_DEBUG(("Server rehashed"));
1202 /* The heart of the server. This runs the scheduler thus runs the server.
1203 When this returns the server has been stopped and the program will
1206 void silc_server_run(SilcServer server)
1208 SILC_LOG_INFO(("SILC Server started"));
1210 /* Start the scheduler, the heart of the SILC server. When this returns
1211 the program will be terminated. */
1212 silc_schedule(server->schedule);
1215 /* Stops the SILC server. This function is used to shutdown the server.
1216 This is usually called after the scheduler has returned. After stopping
1217 the server one should call silc_server_free. */
1219 void silc_server_stop(SilcServer server)
1222 SilcPacketStream ps;
1223 SilcNetListener listener;
1225 SILC_LOG_INFO(("SILC Server shutting down"));
1227 server->server_shutdown = TRUE;
1229 /* Close all connections */
1230 if (server->packet_engine) {
1231 list = silc_packet_engine_get_streams(server->packet_engine);
1233 silc_dlist_start(list);
1234 while ((ps = silc_dlist_get(list))) {
1235 SilcIDListData idata = silc_packet_get_context(ps);
1237 if (!silc_packet_stream_is_valid(ps))
1241 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1243 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1244 "Server is shutting down");
1245 silc_server_free_sock_user_data(server, ps,
1246 "Server is shutting down");
1248 silc_packet_engine_free_streams_list(list);
1251 /* We are not connected to network anymore */
1252 server->standalone = TRUE;
1254 silc_dlist_start(server->listeners);
1255 while ((listener = silc_dlist_get(server->listeners)))
1256 silc_net_close_listener(listener);
1258 silc_server_http_uninit(server);
1260 /* Cancel any possible retry timeouts */
1261 silc_schedule_task_del_by_callback(server->schedule,
1262 silc_server_connect_router);
1263 silc_schedule_task_del_by_callback(server->schedule,
1264 silc_server_connect_to_router_retry);
1265 silc_schedule_task_del_by_callback(server->schedule,
1266 silc_server_connect_to_router);
1268 silc_schedule_stop(server->schedule);
1270 SILC_LOG_DEBUG(("Server stopped"));
1273 /* Purge expired client entries from the server */
1275 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1277 SilcServer server = context;
1278 SilcClientEntry client;
1280 SilcUInt64 curtime = silc_time();
1282 SILC_LOG_DEBUG(("Expire timeout"));
1284 silc_dlist_start(server->expired_clients);
1285 while ((client = silc_dlist_get(server->expired_clients))) {
1286 /* For unregistered clients the created timestamp is actually
1287 unregistered timestamp. Make sure client remains in history
1288 at least 500 seconds. */
1289 if (client->data.created && curtime - client->data.created < 500)
1292 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1293 server->local_list : server->global_list);
1295 silc_idlist_del_data(client);
1296 silc_idlist_del_client(id_list, client);
1297 silc_dlist_del(server->expired_clients, client);
1300 silc_schedule_task_add_timeout(server->schedule,
1301 silc_server_purge_expired_clients, server,
1306 /******************************* Connecting *********************************/
1308 /* Free connection context */
1310 void silc_server_connection_free(SilcServerConnection sconn)
1314 SILC_LOG_DEBUG(("Free connection %p", sconn));
1315 silc_dlist_del(sconn->server->conns, sconn);
1316 silc_server_config_unref(&sconn->conn);
1317 silc_free(sconn->remote_host);
1318 silc_free(sconn->backup_replace_ip);
1322 /* Creates connection to a remote router. */
1324 void silc_server_create_connection(SilcServer server,
1327 const char *remote_host, SilcUInt32 port,
1328 SilcServerConnectCallback callback,
1331 SilcServerConnection sconn;
1333 /* Allocate connection object for hold connection specific stuff. */
1334 sconn = silc_calloc(1, sizeof(*sconn));
1337 sconn->remote_host = strdup(remote_host);
1338 sconn->remote_port = port;
1339 sconn->no_reconnect = reconnect == FALSE;
1340 sconn->callback = callback;
1341 sconn->callback_context = context;
1342 sconn->no_conf = dynamic;
1343 sconn->server = server;
1345 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1346 remote_host, port));
1348 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1352 /* Connection authentication completion callback */
1355 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1358 SilcServerConnection sconn = context;
1359 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1360 SilcServer server = entry->server;
1361 SilcServerConfigServer *conn;
1362 SilcServerConfigConnParams *param;
1363 SilcIDListData idata;
1364 SilcServerEntry id_entry = NULL;
1365 unsigned char id[32];
1370 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1375 if (success == FALSE) {
1376 /* Authentication failed */
1378 /* Try reconnecting if configuration wants it */
1379 if (!sconn->no_reconnect) {
1380 silc_schedule_task_add_timeout(server->schedule,
1381 silc_server_connect_to_router_retry,
1383 silc_dlist_del(server->conns, sconn);
1387 if (sconn->callback)
1388 (*sconn->callback)(server, NULL, sconn->callback_context);
1389 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1390 silc_server_disconnect_remote(server, sconn->sock,
1391 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1395 /* XXX For now remote is router always */
1396 entry->data.conn_type = SILC_CONN_ROUTER;
1398 SILC_LOG_INFO(("Connected to %s %s",
1399 SILC_CONNTYPE_STRING(entry->data.conn_type),
1400 sconn->remote_host));
1402 /* Create the actual entry for remote entity */
1403 switch (entry->data.conn_type) {
1404 case SILC_CONN_SERVER:
1405 SILC_LOG_DEBUG(("Remote is SILC server"));
1407 /* Add new server. The server must register itself to us before it
1408 becomes registered to SILC network. */
1409 id_entry = silc_idlist_add_server(server->local_list,
1410 strdup(sconn->remote_host),
1411 SILC_SERVER, NULL, NULL, sconn->sock);
1413 if (sconn->callback)
1414 (*sconn->callback)(server, NULL, sconn->callback_context);
1415 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1416 silc_server_disconnect_remote(server, sconn->sock,
1417 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1422 server->stat.my_servers++;
1423 if (server->server_type == SILC_ROUTER)
1424 server->stat.servers++;
1425 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1427 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1430 case SILC_CONN_ROUTER:
1431 SILC_LOG_DEBUG(("Remote is SILC router"));
1433 /* Register to network */
1434 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1435 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1436 SILC_STR_UI_SHORT(id_len),
1437 SILC_STR_DATA(id, id_len),
1438 SILC_STR_UI_SHORT(strlen(server->server_name)),
1439 SILC_STR_DATA(server->server_name,
1440 strlen(server->server_name)),
1442 if (sconn->callback)
1443 (*sconn->callback)(server, NULL, sconn->callback_context);
1444 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1445 silc_server_disconnect_remote(server, sconn->sock,
1446 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1451 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1453 /* Check that we do not have this ID already */
1454 id_entry = silc_idlist_find_server_by_id(server->local_list,
1455 &remote_id.u.server_id,
1458 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1460 id_entry = silc_idlist_find_server_by_id(server->global_list,
1461 &remote_id.u.server_id,
1464 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1468 SILC_LOG_DEBUG(("New server id(%s)",
1469 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1471 /* Add the connected router to global server list. Router is sent
1472 as NULL since it's local to us. */
1473 id_entry = silc_idlist_add_server(server->global_list,
1474 strdup(sconn->remote_host),
1476 silc_id_dup(&remote_id.u.server_id,
1480 /* Try reconnecting if configuration wants it */
1481 if (!sconn->no_reconnect) {
1482 silc_schedule_task_add_timeout(server->schedule,
1483 silc_server_connect_to_router_retry,
1485 silc_dlist_del(server->conns, sconn);
1489 if (sconn->callback)
1490 (*sconn->callback)(server, NULL, sconn->callback_context);
1491 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1492 silc_server_disconnect_remote(server, sconn->sock,
1493 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1498 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1499 idata = (SilcIDListData)id_entry;
1500 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1501 SILC_IDLIST_STATUS_LOCAL);
1502 idata->sconn = sconn;
1503 idata->sconn->callback = NULL;
1506 server->stat.my_routers++;
1507 if (server->server_type == SILC_ROUTER)
1508 server->stat.routers++;
1509 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1511 if (!sconn->backup) {
1512 /* Mark this router our primary router if we're still standalone */
1513 if (server->standalone) {
1514 SILC_LOG_DEBUG(("This connection is our primary router"));
1515 server->id_entry->router = id_entry;
1516 server->router = id_entry;
1517 server->router->server_type = SILC_ROUTER;
1518 server->standalone = FALSE;
1519 server->backup_primary = FALSE;
1521 /* Announce data if we are not backup router (unless not as primary
1522 currently). Backup router announces later at the end of
1523 resuming protocol. */
1524 if (server->backup_router && server->server_type == SILC_ROUTER) {
1525 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1527 /* If we are router then announce our possible servers. Backup
1528 router announces also global servers. */
1529 if (server->server_type == SILC_ROUTER)
1530 silc_server_announce_servers(server,
1531 server->backup_router ? TRUE : FALSE,
1532 0, SILC_PRIMARY_ROUTE(server));
1534 /* Announce our clients and channels to the router */
1535 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1536 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1539 /* If we are backup router then this primary router is whom we are
1541 if (server->server_type == SILC_BACKUP_ROUTER) {
1542 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1544 NULL, NULL, &ip, NULL);
1545 silc_server_backup_add(server, server->id_entry, ip,
1546 sconn->remote_port, TRUE);
1551 /* We already have primary router. Disconnect this connection */
1552 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1553 silc_idlist_del_server(server->global_list, id_entry);
1554 if (sconn->callback)
1555 (*sconn->callback)(server, NULL, sconn->callback_context);
1556 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1557 silc_server_disconnect_remote(server, sconn->sock,
1558 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1563 /* Add this server to be our backup router */
1564 id_entry->server_type = SILC_BACKUP_ROUTER;
1565 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1566 sconn->backup_replace_port, FALSE);
1572 if (sconn->callback)
1573 (*sconn->callback)(server, NULL, sconn->callback_context);
1574 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1575 silc_server_disconnect_remote(server, sconn->sock,
1576 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1580 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1582 conn = sconn->conn.ref_ptr;
1583 param = &server->config->param;
1584 if (conn && conn->param)
1585 param = conn->param;
1587 /* Register rekey timeout */
1588 sconn->rekey_timeout = param->key_exchange_rekey;
1589 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1590 sconn->sock, sconn->rekey_timeout, 0);
1592 /* Set the entry as packet stream context */
1593 silc_packet_set_context(sconn->sock, id_entry);
1595 /* Call the completion callback to indicate that we've connected to
1597 if (sconn && sconn->callback)
1598 (*sconn->callback)(server, id_entry, sconn->callback_context);
1600 if (sconn == server->router_conn)
1601 server->router_conn = NULL;
1606 /* SKE completion callback */
1608 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1609 SilcSKESecurityProperties prop,
1610 SilcSKEKeyMaterial keymat,
1611 SilcSKERekeyMaterial rekey,
1614 SilcPacketStream sock = context;
1615 SilcUnknownEntry entry = silc_packet_get_context(sock);
1616 SilcServerConnection sconn;
1618 SilcServerConfigRouter *conn;
1619 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1620 void *auth_data = NULL;
1621 SilcUInt32 auth_data_len = 0;
1622 SilcConnAuth connauth;
1623 SilcCipher send_key, receive_key;
1624 SilcHmac hmac_send, hmac_receive;
1626 server = entry->server;
1627 sconn = entry->data.sconn;
1628 conn = sconn->conn.ref_ptr;
1631 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1633 if (status != SILC_SKE_STATUS_OK) {
1635 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1636 silc_ske_map_status(status), entry->hostname, entry->ip));
1639 /* Try reconnecting if configuration wants it */
1640 if (!sconn->no_reconnect) {
1641 silc_schedule_task_add_timeout(server->schedule,
1642 silc_server_connect_to_router_retry,
1644 silc_dlist_del(server->conns, sconn);
1648 if (sconn->callback)
1649 (*sconn->callback)(server, NULL, sconn->callback_context);
1650 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1651 silc_server_disconnect_remote(server, sconn->sock,
1652 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1656 SILC_LOG_DEBUG(("Setting keys into use"));
1658 /* Set the keys into use. The data will be encrypted after this. */
1659 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1660 &hmac_send, &hmac_receive, NULL)) {
1663 /* Try reconnecting if configuration wants it */
1664 if (!sconn->no_reconnect) {
1665 silc_schedule_task_add_timeout(server->schedule,
1666 silc_server_connect_to_router_retry,
1668 silc_dlist_del(server->conns, sconn);
1672 /* Error setting keys */
1673 if (sconn->callback)
1674 (*sconn->callback)(server, NULL, sconn->callback_context);
1675 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1676 silc_server_disconnect_remote(server, sconn->sock,
1677 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1680 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1681 hmac_receive, FALSE);
1683 SILC_LOG_DEBUG(("Starting connection authentication"));
1685 connauth = silc_connauth_alloc(server->schedule, ske,
1686 server->config->conn_auth_timeout);
1690 /* Try reconnecting if configuration wants it */
1691 if (!sconn->no_reconnect) {
1692 silc_schedule_task_add_timeout(server->schedule,
1693 silc_server_connect_to_router_retry,
1695 silc_dlist_del(server->conns, sconn);
1699 /** Error allocating auth protocol */
1700 if (sconn->callback)
1701 (*sconn->callback)(server, NULL, sconn->callback_context);
1702 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1703 silc_server_disconnect_remote(server, sconn->sock,
1704 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1708 /* Get authentication method */
1710 if (conn->passphrase) {
1711 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1712 auth_meth = SILC_AUTH_PUBLIC_KEY;
1713 auth_data = server->private_key;
1715 auth_meth = SILC_AUTH_PASSWORD;
1716 auth_data = conn->passphrase;
1717 auth_data_len = conn->passphrase_len;
1720 auth_meth = SILC_AUTH_PUBLIC_KEY;
1721 auth_data = server->private_key;
1725 entry->data.rekey = rekey;
1727 /* Start connection authentication */
1729 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1730 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1731 auth_data, auth_data_len,
1732 silc_server_ke_auth_compl, sconn);
1735 /* Function that is called when the network connection to a router has
1736 been established. This will continue with the key exchange protocol
1737 with the remote router. */
1739 void silc_server_start_key_exchange(SilcServerConnection sconn)
1741 SilcServer server = sconn->server;
1742 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1743 SilcUnknownEntry entry;
1744 SilcSKEParamsStruct params;
1747 /* Cancel any possible retry timeouts */
1748 silc_schedule_task_del_by_context(server->schedule, sconn);
1750 /* Create packet stream */
1751 sconn->sock = silc_packet_stream_create(server->packet_engine,
1752 server->schedule, sconn->stream);
1754 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1755 silc_stream_destroy(sconn->stream);
1757 /* Try reconnecting if configuration wants it */
1758 if (!sconn->no_reconnect) {
1759 silc_schedule_task_add_timeout(server->schedule,
1760 silc_server_connect_to_router_retry,
1762 silc_dlist_del(server->conns, sconn);
1766 if (sconn->callback)
1767 (*sconn->callback)(server, NULL, sconn->callback_context);
1768 silc_server_connection_free(sconn);
1771 server->stat.conn_num++;
1773 /* Set source ID to packet stream */
1774 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1776 silc_packet_stream_destroy(sconn->sock);
1778 /* Try reconnecting if configuration wants it */
1779 if (!sconn->no_reconnect) {
1780 silc_schedule_task_add_timeout(server->schedule,
1781 silc_server_connect_to_router_retry,
1783 silc_dlist_del(server->conns, sconn);
1787 if (sconn->callback)
1788 (*sconn->callback)(server, NULL, sconn->callback_context);
1789 silc_server_connection_free(sconn);
1793 /* Create entry for remote entity */
1794 entry = silc_calloc(1, sizeof(*entry));
1796 silc_packet_stream_destroy(sconn->sock);
1798 /* Try reconnecting if configuration wants it */
1799 if (!sconn->no_reconnect) {
1800 silc_schedule_task_add_timeout(server->schedule,
1801 silc_server_connect_to_router_retry,
1803 silc_dlist_del(server->conns, sconn);
1807 if (sconn->callback)
1808 (*sconn->callback)(server, NULL, sconn->callback_context);
1809 silc_server_connection_free(sconn);
1812 entry->server = server;
1813 entry->data.sconn = sconn;
1814 entry->data.conn_type = SILC_CONN_UNKNOWN;
1815 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1816 silc_packet_set_context(sconn->sock, entry);
1818 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1820 /* Set Key Exchange flags from configuration, but fall back to global
1822 memset(¶ms, 0, sizeof(params));
1823 SILC_GET_SKE_FLAGS(conn, params.flags);
1824 if (server->config->param.key_exchange_pfs)
1825 params.flags |= SILC_SKE_SP_FLAG_PFS;
1827 /* Start SILC Key Exchange protocol */
1828 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1829 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1830 server->public_key, server->private_key, sconn);
1833 silc_packet_stream_destroy(sconn->sock);
1835 /* Try reconnecting if configuration wants it */
1836 if (!sconn->no_reconnect) {
1837 silc_schedule_task_add_timeout(server->schedule,
1838 silc_server_connect_to_router_retry,
1840 silc_dlist_del(server->conns, sconn);
1844 if (sconn->callback)
1845 (*sconn->callback)(server, NULL, sconn->callback_context);
1846 silc_server_connection_free(sconn);
1849 silc_ske_set_callbacks(ske, silc_server_verify_key,
1850 silc_server_ke_completed, sconn->sock);
1852 /* Start key exchange protocol */
1853 params.version = silc_version_string;
1854 params.timeout_secs = server->config->key_exchange_timeout;
1855 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1858 /* Timeout callback that will be called to retry connecting to remote
1859 router. This is used by both normal and router server. This will wait
1860 before retrying the connecting. The timeout is generated by exponential
1861 backoff algorithm. */
1863 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1865 SilcServerConnection sconn = context;
1866 SilcServer server = sconn->server;
1867 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1868 SilcServerConfigConnParams *param =
1869 (conn->param ? conn->param : &server->config->param);
1871 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1872 sconn->remote_port));
1874 /* Calculate next timeout */
1875 if (sconn->retry_count >= 1) {
1876 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1877 if (sconn->retry_timeout > param->reconnect_interval_max)
1878 sconn->retry_timeout = param->reconnect_interval_max;
1880 sconn->retry_timeout = param->reconnect_interval;
1882 sconn->retry_count++;
1883 sconn->retry_timeout = sconn->retry_timeout +
1884 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1886 /* If we've reached max retry count, give up. */
1887 if ((sconn->retry_count > param->reconnect_count) &&
1888 sconn->no_reconnect) {
1889 SILC_LOG_ERROR(("Could not connect, giving up"));
1891 if (sconn->callback)
1892 (*sconn->callback)(server, NULL, sconn->callback_context);
1893 silc_server_connection_free(sconn);
1897 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1899 /* We will lookup a fresh pointer later */
1900 silc_server_config_unref(&sconn->conn);
1902 /* Wait before retrying */
1903 silc_schedule_task_del_by_context(server->schedule, sconn);
1904 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1905 sconn, sconn->retry_timeout, 0);
1908 /* Callback for async connection to remote router */
1910 static void silc_server_connection_established(SilcNetStatus status,
1914 SilcServerConnection sconn = context;
1915 SilcServer server = sconn->server;
1917 silc_schedule_task_del_by_context(server->schedule, sconn);
1922 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1923 sconn->remote_host, sconn->remote_port));
1925 /* Continue with key exchange protocol */
1926 sconn->stream = stream;
1927 silc_server_start_key_exchange(sconn);
1930 case SILC_NET_UNKNOWN_IP:
1931 case SILC_NET_UNKNOWN_HOST:
1932 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1933 sconn->remote_host, sconn->remote_port,
1934 silc_net_get_error_string(status)));
1935 if (!sconn->no_reconnect) {
1936 silc_schedule_task_add_timeout(sconn->server->schedule,
1937 silc_server_connect_to_router_retry,
1939 silc_dlist_del(server->conns, sconn);
1941 if (sconn->callback)
1942 (*sconn->callback)(server, NULL, sconn->callback_context);
1943 silc_server_connection_free(sconn);
1948 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1949 sconn->remote_host, sconn->remote_port,
1950 silc_net_get_error_string(status)));
1951 if (!sconn->no_reconnect) {
1952 silc_schedule_task_add_timeout(sconn->server->schedule,
1953 silc_server_connect_to_router_retry,
1955 silc_dlist_del(server->conns, sconn);
1957 if (sconn->callback)
1958 (*sconn->callback)(server, NULL, sconn->callback_context);
1959 silc_server_connection_free(sconn);
1965 /* Generic routine to use connect to a router. */
1967 SILC_TASK_CALLBACK(silc_server_connect_router)
1969 SilcServerConnection sconn = context;
1970 SilcServer server = sconn->server;
1971 SilcServerConfigRouter *rconn;
1973 silc_schedule_task_del_by_context(server->schedule, sconn);
1975 /* Don't connect if we are shutting down. */
1976 if (server->server_shutdown) {
1977 if (sconn->callback)
1978 (*sconn->callback)(server, NULL, sconn->callback_context);
1979 silc_server_connection_free(sconn);
1983 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1984 (sconn->backup ? "backup router" : "router"),
1985 sconn->remote_host, sconn->remote_port));
1987 if (!sconn->no_conf) {
1988 /* Find connection configuration */
1989 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1990 sconn->remote_port);
1992 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1993 (sconn->backup ? "backup router" : "router"),
1994 sconn->remote_host, sconn->remote_port));
1995 if (sconn->callback)
1996 (*sconn->callback)(server, NULL, sconn->callback_context);
1997 silc_server_connection_free(sconn);
2000 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
2003 /* Connect to remote host */
2005 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
2006 server->config->server_info->primary->server_ip),
2007 sconn->remote_host, sconn->remote_port,
2008 server->schedule, silc_server_connection_established,
2011 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2012 sconn->remote_host, sconn->remote_port));
2013 if (sconn->callback)
2014 (*sconn->callback)(server, NULL, sconn->callback_context);
2015 silc_server_connection_free(sconn);
2019 /* Add to connection list */
2020 silc_dlist_add(server->conns, sconn);
2023 /* This function connects to our primary router or if we are a router this
2024 establishes all our primary routes. This is called at the start of the
2025 server to do authentication and key exchange with our router - called
2028 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2030 SilcServer server = context;
2031 SilcServerConnection sconn;
2032 SilcServerConfigRouter *ptr;
2033 SilcServerConfigConnParams *param;
2035 /* Don't connect if we are shutting down. */
2036 if (server->server_shutdown)
2039 SILC_LOG_DEBUG(("We are %s",
2040 (server->server_type == SILC_SERVER ?
2041 "normal server" : server->server_type == SILC_ROUTER ?
2042 "router" : "backup router/normal server")));
2044 if (!server->config->routers) {
2045 /* There wasn't a configured router, we will continue but we don't
2046 have a connection to outside world. We will be standalone server. */
2047 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2048 server->standalone = TRUE;
2052 /* Cancel any possible retry timeouts */
2053 silc_schedule_task_del_by_callback(server->schedule,
2054 silc_server_connect_router);
2055 silc_schedule_task_del_by_callback(server->schedule,
2056 silc_server_connect_to_router_retry);
2058 /* Create the connections to all our routes */
2059 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2061 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2062 ptr->backup_router ? "Backup router" : "Router",
2063 ptr->initiator ? "Initiator" : "Responder",
2064 ptr->host, ptr->port));
2066 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2067 ptr->initiator == FALSE && !server->backup_router &&
2068 !silc_server_config_get_backup_router(server))
2069 server->wait_backup = TRUE;
2071 if (!ptr->initiator)
2073 if (ptr->dynamic_connection)
2076 /* Check whether we are connecting or connected to this host already */
2077 if (silc_server_num_sockets_by_remote(server,
2078 silc_net_is_ip(ptr->host) ?
2080 silc_net_is_ip(ptr->host) ?
2081 NULL : ptr->host, ptr->port,
2082 SILC_CONN_ROUTER)) {
2083 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2084 ptr->host, ptr->port));
2086 /* If we don't have primary router and this connection is our
2087 primary router we are in desync. Reconnect to the primary. */
2088 if (server->standalone && !server->router) {
2090 SilcPacketStream sock;
2091 SilcServerConfigRouter *primary =
2092 silc_server_config_get_primary_router(server);
2095 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2096 ptr->host, ptr->port);
2099 server->backup_noswitch = TRUE;
2100 silc_server_free_sock_user_data(server, sock, NULL);
2101 silc_server_disconnect_remote(server, sock, 0, NULL);
2102 server->backup_noswitch = FALSE;
2103 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2109 param = (ptr->param ? ptr->param : &server->config->param);
2111 /* Allocate connection object for hold connection specific stuff. */
2112 sconn = silc_calloc(1, sizeof(*sconn));
2115 sconn->server = server;
2116 sconn->remote_host = strdup(ptr->host);
2117 sconn->remote_port = ptr->port;
2118 sconn->backup = ptr->backup_router;
2119 if (sconn->backup) {
2120 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2121 sconn->backup_replace_port = ptr->backup_replace_port;
2123 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2125 SILC_LOG_DEBUG(("Created connection %p", sconn));
2127 if (!server->router_conn && !sconn->backup)
2128 server->router_conn = sconn;
2131 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2137 /************************ Accepting new connection **************************/
2139 /* After this is called, server don't wait for backup router anymore.
2140 This gets called automatically even after we have backup router
2141 connection established. */
2143 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2145 SilcServer server = context;
2146 server->wait_backup = FALSE;
2149 /* Authentication data callback */
2152 silc_server_accept_get_auth(SilcConnAuth connauth,
2153 SilcConnectionType conn_type,
2154 unsigned char **passphrase,
2155 SilcUInt32 *passphrase_len,
2156 SilcSKR *repository,
2159 SilcPacketStream sock = context;
2160 SilcUnknownEntry entry = silc_packet_get_context(sock);
2161 SilcServer server = entry->server;
2163 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2165 /* Remote end is client */
2166 if (conn_type == SILC_CONN_CLIENT) {
2167 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2171 *passphrase = cconfig->passphrase;
2172 *passphrase_len = cconfig->passphrase_len;
2173 if (cconfig->publickeys)
2174 *repository = server->repository;
2176 if (cconfig->publickeys) {
2177 if (server->config->prefer_passphrase_auth) {
2181 *passphrase_len = 0;
2185 entry->conn_type = conn_type;
2189 /* Remote end is server */
2190 if (conn_type == SILC_CONN_SERVER) {
2191 SilcServerConfigServer *sconfig;
2193 /* If we are normal server, don't accept the connection */
2194 if (server->server_type == SILC_SERVER)
2197 sconfig = entry->sconfig.ref_ptr;
2201 *passphrase = sconfig->passphrase;
2202 *passphrase_len = sconfig->passphrase_len;
2203 if (sconfig->publickeys)
2204 *repository = server->repository;
2206 if (sconfig->publickeys) {
2207 if (server->config->prefer_passphrase_auth) {
2211 *passphrase_len = 0;
2215 entry->conn_type = conn_type;
2219 /* Remote end is router */
2220 if (conn_type == SILC_CONN_ROUTER) {
2221 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2225 *passphrase = rconfig->passphrase;
2226 *passphrase_len = rconfig->passphrase_len;
2227 if (rconfig->publickeys)
2228 *repository = server->repository;
2230 if (rconfig->publickeys) {
2231 if (server->config->prefer_passphrase_auth) {
2235 *passphrase_len = 0;
2239 entry->conn_type = conn_type;
2246 /* Authentication completion callback. */
2249 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2252 SilcPacketStream sock = context;
2253 SilcUnknownEntry entry = silc_packet_get_context(sock);
2254 SilcIDListData idata = (SilcIDListData)entry;
2255 SilcServer server = entry->server;
2256 SilcServerConfigConnParams *param = &server->config->param;
2257 SilcServerConnection sconn;
2259 const char *hostname, *ip;
2263 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2264 NULL, &hostname, &ip, &port);
2266 if (success == FALSE) {
2267 /* Authentication failed */
2268 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2269 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2270 server->stat.auth_failures++;
2271 silc_server_disconnect_remote(server, sock,
2272 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2273 silc_server_config_unref(&entry->cconfig);
2274 silc_server_config_unref(&entry->sconfig);
2275 silc_server_config_unref(&entry->rconfig);
2276 silc_server_free_sock_user_data(server, sock, NULL);
2280 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2282 switch (entry->conn_type) {
2283 case SILC_CONN_CLIENT:
2285 SilcClientEntry client;
2286 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2288 /* Verify whether this connection is after all allowed to connect */
2289 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2290 &server->config->param,
2292 silc_connauth_get_ske(connauth))) {
2293 server->stat.auth_failures++;
2297 /* If we are primary router and we have backup router configured
2298 but it has not connected to use yet, do not accept any other
2300 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2301 !server->backup_router) {
2302 SilcServerConfigRouter *router;
2303 router = silc_server_config_get_backup_router(server);
2304 if (router && strcmp(server->config->server_info->primary->server_ip,
2306 silc_server_find_socket_by_host(server,
2308 router->backup_replace_ip, 0)) {
2309 SILC_LOG_INFO(("Will not accept connections because we do "
2310 "not have backup router connection established"));
2311 silc_server_disconnect_remote(server, sock,
2312 SILC_STATUS_ERR_PERM_DENIED,
2313 "We do not have connection to backup "
2314 "router established, try later");
2315 silc_server_config_unref(&entry->cconfig);
2316 silc_server_config_unref(&entry->sconfig);
2317 silc_server_config_unref(&entry->rconfig);
2318 silc_server_free_sock_user_data(server, sock, NULL);
2319 server->stat.auth_failures++;
2321 /* From here on, wait 20 seconds for the backup router to appear. */
2322 silc_schedule_task_add_timeout(server->schedule,
2323 silc_server_backup_router_wait,
2324 (void *)server, 20, 0);
2329 SILC_LOG_DEBUG(("Remote host is client"));
2330 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2333 /* Add the client to the client ID cache. The nickname and Client ID
2334 and other information is created after we have received NEW_CLIENT
2335 packet from client. */
2336 client = silc_idlist_add_client(server->local_list,
2337 NULL, NULL, NULL, NULL, NULL, sock);
2339 SILC_LOG_ERROR(("Could not add new client to cache"));
2340 server->stat.auth_failures++;
2341 silc_server_disconnect_remote(server, sock,
2342 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2343 silc_server_config_unref(&entry->cconfig);
2344 silc_server_config_unref(&entry->sconfig);
2345 silc_server_config_unref(&entry->rconfig);
2346 silc_server_free_sock_user_data(server, sock, NULL);
2349 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2350 entry->data.conn_type = SILC_CONN_CLIENT;
2353 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
2354 server->stat.clients + 1));
2355 server->stat.my_clients++;
2356 server->stat.clients++;
2357 server->stat.cell_clients++;
2359 /* Get connection parameters */
2361 param = conn->param;
2363 if (!param->keepalive_secs)
2364 param->keepalive_secs = server->config->param.keepalive_secs;
2366 if (!param->qos && server->config->param.qos) {
2367 param->qos = server->config->param.qos;
2368 param->qos_rate_limit = server->config->param.qos_rate_limit;
2369 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2370 param->qos_limit_sec = server->config->param.qos_limit_sec;
2371 param->qos_limit_usec = server->config->param.qos_limit_usec;
2374 /* Check if to be anonymous connection */
2375 if (param->anonymous)
2376 client->mode |= SILC_UMODE_ANONYMOUS;
2379 /* Add public key to repository */
2380 SILC_LOG_DEBUG(("Add client public key to repository"));
2381 if (!silc_server_get_public_key_by_client(server, client, NULL))
2382 silc_skr_add_public_key_simple(server->repository,
2383 entry->data.public_key,
2384 SILC_SKR_USAGE_IDENTIFICATION, client,
2387 id_entry = (void *)client;
2391 case SILC_CONN_SERVER:
2392 case SILC_CONN_ROUTER:
2394 SilcServerEntry new_server;
2395 SilcBool initiator = FALSE;
2396 SilcBool backup_local = FALSE;
2397 SilcBool backup_router = FALSE;
2398 char *backup_replace_ip = NULL;
2399 SilcUInt16 backup_replace_port = 0;
2400 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2401 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2403 /* If we are backup router and this is incoming server connection
2404 and we do not have connection to primary router, do not allow
2406 if (server->server_type == SILC_BACKUP_ROUTER &&
2407 entry->conn_type == SILC_CONN_SERVER &&
2408 !SILC_PRIMARY_ROUTE(server)) {
2409 SILC_LOG_INFO(("Will not accept server connection because we do "
2410 "not have primary router connection established"));
2411 silc_server_disconnect_remote(server, sock,
2412 SILC_STATUS_ERR_PERM_DENIED,
2413 "We do not have connection to primary "
2414 "router established, try later");
2415 silc_server_config_unref(&entry->cconfig);
2416 silc_server_config_unref(&entry->sconfig);
2417 silc_server_config_unref(&entry->rconfig);
2418 silc_server_free_sock_user_data(server, sock, NULL);
2419 server->stat.auth_failures++;
2423 if (entry->conn_type == SILC_CONN_ROUTER) {
2424 /* Verify whether this connection is after all allowed to connect */
2425 if (!silc_server_connection_allowed(server, sock,
2427 &server->config->param,
2428 rconn ? rconn->param : NULL,
2429 silc_connauth_get_ske(connauth))) {
2430 silc_server_config_unref(&entry->cconfig);
2431 silc_server_config_unref(&entry->sconfig);
2432 silc_server_config_unref(&entry->rconfig);
2433 server->stat.auth_failures++;
2439 param = rconn->param;
2441 if (!param->keepalive_secs)
2442 param->keepalive_secs = server->config->param.keepalive_secs;
2444 if (!param->qos && server->config->param.qos) {
2445 param->qos = server->config->param.qos;
2446 param->qos_rate_limit = server->config->param.qos_rate_limit;
2447 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2448 param->qos_limit_sec = server->config->param.qos_limit_sec;
2449 param->qos_limit_usec = server->config->param.qos_limit_usec;
2453 initiator = rconn->initiator;
2454 backup_local = rconn->backup_local;
2455 backup_router = rconn->backup_router;
2456 backup_replace_ip = rconn->backup_replace_ip;
2457 backup_replace_port = rconn->backup_replace_port;
2461 if (entry->conn_type == SILC_CONN_SERVER) {
2462 /* Verify whether this connection is after all allowed to connect */
2463 if (!silc_server_connection_allowed(server, sock,
2465 &server->config->param,
2466 srvconn ? srvconn->param : NULL,
2467 silc_connauth_get_ske(connauth))) {
2468 server->stat.auth_failures++;
2472 if (srvconn->param) {
2473 param = srvconn->param;
2475 if (!param->keepalive_secs)
2476 param->keepalive_secs = server->config->param.keepalive_secs;
2478 if (!param->qos && server->config->param.qos) {
2479 param->qos = server->config->param.qos;
2480 param->qos_rate_limit = server->config->param.qos_rate_limit;
2481 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2482 param->qos_limit_sec = server->config->param.qos_limit_sec;
2483 param->qos_limit_usec = server->config->param.qos_limit_usec;
2487 backup_router = srvconn->backup_router;
2491 /* If we are primary router and we have backup router configured
2492 but it has not connected to use yet, do not accept any other
2494 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2495 !server->backup_router && !backup_router) {
2496 SilcServerConfigRouter *router;
2497 router = silc_server_config_get_backup_router(server);
2498 if (router && strcmp(server->config->server_info->primary->server_ip,
2500 silc_server_find_socket_by_host(server,
2502 router->backup_replace_ip, 0)) {
2503 SILC_LOG_INFO(("Will not accept connections because we do "
2504 "not have backup router connection established"));
2505 silc_server_disconnect_remote(server, sock,
2506 SILC_STATUS_ERR_PERM_DENIED,
2507 "We do not have connection to backup "
2508 "router established, try later");
2509 silc_server_config_unref(&entry->cconfig);
2510 silc_server_config_unref(&entry->sconfig);
2511 silc_server_config_unref(&entry->rconfig);
2512 silc_server_free_sock_user_data(server, sock, NULL);
2513 server->stat.auth_failures++;
2515 /* From here on, wait 20 seconds for the backup router to appear. */
2516 silc_schedule_task_add_timeout(server->schedule,
2517 silc_server_backup_router_wait,
2518 (void *)server, 20, 0);
2523 SILC_LOG_DEBUG(("Remote host is %s",
2524 entry->conn_type == SILC_CONN_SERVER ?
2525 "server" : (backup_router ?
2526 "backup router" : "router")));
2527 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2528 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2529 "server" : (backup_router ?
2530 "backup router" : "router")));
2532 /* Add the server into server cache. The server name and Server ID
2533 is updated after we have received NEW_SERVER packet from the
2534 server. We mark ourselves as router for this server if we really
2537 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2538 server->local_list : (backup_router ?
2539 server->local_list :
2540 server->global_list)),
2542 (entry->conn_type == SILC_CONN_SERVER ?
2543 SILC_SERVER : SILC_ROUTER),
2545 (entry->conn_type == SILC_CONN_SERVER ?
2546 server->id_entry : (backup_router ?
2547 server->id_entry : NULL)),
2550 SILC_LOG_ERROR(("Could not add new server to cache"));
2551 silc_server_disconnect_remote(server, sock,
2552 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2553 silc_server_config_unref(&entry->cconfig);
2554 silc_server_config_unref(&entry->sconfig);
2555 silc_server_config_unref(&entry->rconfig);
2556 silc_server_free_sock_user_data(server, sock, NULL);
2557 server->stat.auth_failures++;
2560 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2561 entry->data.conn_type = entry->conn_type;
2563 id_entry = (void *)new_server;
2565 /* If the incoming connection is router and marked as backup router
2566 then add it to be one of our backups */
2567 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2568 /* Change it back to SERVER type since that's what it really is. */
2570 entry->data.conn_type = SILC_CONN_SERVER;
2571 new_server->server_type = SILC_BACKUP_ROUTER;
2573 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2574 ("Backup router %s is now online",
2577 /* Remove the backup waiting with timeout */
2578 silc_schedule_task_add_timeout(server->schedule,
2579 silc_server_backup_router_wait,
2580 (void *)server, 10, 0);
2584 if (entry->data.conn_type == SILC_CONN_SERVER) {
2585 server->stat.my_servers++;
2586 server->stat.servers++;
2587 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2589 server->stat.my_routers++;
2590 server->stat.routers++;
2591 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2594 /* Check whether this connection is to be our primary router connection
2595 if we do not already have the primary route. */
2596 if (!backup_router &&
2597 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2598 if (silc_server_config_is_primary_route(server) && !initiator)
2601 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2602 server->standalone = FALSE;
2603 if (!server->id_entry->router) {
2604 server->id_entry->router = id_entry;
2605 server->router = id_entry;
2617 /* Add connection to server->conns so that we know we have connection
2619 sconn = silc_calloc(1, sizeof(*sconn));
2620 sconn->server = server;
2622 sconn->remote_host = strdup(hostname);
2623 sconn->remote_port = port;
2624 silc_dlist_add(server->conns, sconn);
2625 idata->sconn = sconn;
2626 idata->sconn->callback = NULL;
2627 idata->last_receive = time(NULL);
2629 /* Add the common data structure to the ID entry. */
2630 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2631 silc_packet_set_context(sock, id_entry);
2633 /* Connection has been fully established now. Everything is ok. */
2634 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2636 /* Perform Quality of Service */
2638 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2639 param->qos_rate_limit, param->qos_bytes_limit,
2640 param->qos_limit_sec, param->qos_limit_usec);
2642 silc_server_config_unref(&entry->cconfig);
2643 silc_server_config_unref(&entry->sconfig);
2644 silc_server_config_unref(&entry->rconfig);
2648 silc_ske_free(silc_connauth_get_ske(connauth));
2649 silc_connauth_free(connauth);
2652 /* SKE completion callback. We set the new keys into use here. */
2655 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2656 SilcSKESecurityProperties prop,
2657 SilcSKEKeyMaterial keymat,
2658 SilcSKERekeyMaterial rekey,
2661 SilcPacketStream sock = context;
2662 SilcUnknownEntry entry = silc_packet_get_context(sock);
2663 SilcIDListData idata = (SilcIDListData)entry;
2664 SilcServer server = entry->server;
2665 SilcConnAuth connauth;
2666 SilcCipher send_key, receive_key;
2667 SilcHmac hmac_send, hmac_receive;
2674 if (status != SILC_SKE_STATUS_OK) {
2676 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2677 silc_ske_map_status(status), entry->hostname, entry->ip));
2679 silc_server_disconnect_remote(server, sock,
2680 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2681 silc_server_config_unref(&entry->cconfig);
2682 silc_server_config_unref(&entry->sconfig);
2683 silc_server_config_unref(&entry->rconfig);
2684 silc_server_free_sock_user_data(server, sock, NULL);
2688 SILC_LOG_DEBUG(("Setting keys into use"));
2690 /* Set the keys into use. The data will be encrypted after this. */
2691 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2692 &hmac_send, &hmac_receive, &hash)) {
2693 /* Error setting keys */
2695 silc_server_disconnect_remote(server, sock,
2696 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2697 silc_server_free_sock_user_data(server, sock, NULL);
2700 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2701 hmac_receive, FALSE);
2703 idata->rekey = rekey;
2704 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2705 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2707 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2712 SILC_LOG_DEBUG(("Starting connection authentication"));
2713 server->stat.auth_attempts++;
2715 connauth = silc_connauth_alloc(server->schedule, ske,
2716 server->config->conn_auth_timeout);
2718 /** Error allocating auth protocol */
2720 silc_server_disconnect_remote(server, sock,
2721 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2722 silc_server_config_unref(&entry->cconfig);
2723 silc_server_config_unref(&entry->sconfig);
2724 silc_server_config_unref(&entry->rconfig);
2725 silc_server_free_sock_user_data(server, sock, NULL);
2729 /* Start connection authentication */
2731 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2732 silc_server_accept_auth_compl, sock);
2735 /* Accept new TCP connection */
2737 static void silc_server_accept_new_connection(SilcNetStatus status,
2741 SilcServer server = context;
2742 SilcPacketStream packet_stream;
2743 SilcServerConfigClient *cconfig = NULL;
2744 SilcServerConfigServer *sconfig = NULL;
2745 SilcServerConfigRouter *rconfig = NULL;
2746 SilcServerConfigDeny *deny;
2747 SilcUnknownEntry entry;
2749 SilcSKEParamsStruct params;
2750 char *hostname, *ip;
2753 SILC_LOG_DEBUG(("Accepting new connection"));
2755 /* Check for maximum allowed connections */
2756 server->stat.conn_attempts++;
2757 if (silc_dlist_count(server->conns) >
2758 server->config->param.connections_max) {
2759 SILC_LOG_ERROR(("Refusing connection, server is full"));
2760 server->stat.conn_failures++;
2761 silc_stream_destroy(stream);
2765 /* Get hostname, IP and port */
2766 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2767 (const char **)&ip, &port)) {
2768 /* Bad socket stream */
2769 server->stat.conn_failures++;
2770 silc_stream_destroy(stream);
2774 /* Create packet stream */
2775 packet_stream = silc_packet_stream_create(server->packet_engine,
2776 server->schedule, stream);
2777 if (!packet_stream) {
2778 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2779 server->stat.conn_failures++;
2780 silc_stream_destroy(stream);
2783 server->stat.conn_num++;
2785 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2787 /* Set source ID to packet stream */
2788 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2791 server->stat.conn_failures++;
2792 silc_packet_stream_destroy(packet_stream);
2796 /* Check whether this connection is denied to connect to us. */
2797 deny = silc_server_config_find_denied(server, ip);
2799 deny = silc_server_config_find_denied(server, hostname);
2801 /* The connection is denied */
2802 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2803 silc_server_disconnect_remote(server, packet_stream,
2804 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2806 silc_server_free_sock_user_data(server, packet_stream, NULL);
2810 /* Check whether we have configured this sort of connection at all. We
2811 have to check all configurations since we don't know what type of
2812 connection this is. */
2813 if (!(cconfig = silc_server_config_find_client(server, ip)))
2814 cconfig = silc_server_config_find_client(server, hostname);
2815 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2816 sconfig = silc_server_config_find_server_conn(server, hostname);
2817 if (server->server_type == SILC_ROUTER)
2818 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2819 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2820 if (!cconfig && !sconfig && !rconfig) {
2821 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2822 server->stat.conn_failures++;
2823 silc_server_disconnect_remote(server, packet_stream,
2824 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2825 silc_server_free_sock_user_data(server, packet_stream, NULL);
2829 /* The connection is allowed */
2830 entry = silc_calloc(1, sizeof(*entry));
2832 server->stat.conn_failures++;
2833 silc_server_disconnect_remote(server, packet_stream,
2834 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2835 silc_server_free_sock_user_data(server, packet_stream, NULL);
2838 entry->hostname = hostname;
2841 entry->server = server;
2842 entry->data.conn_type = SILC_CONN_UNKNOWN;
2843 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2844 silc_packet_set_context(packet_stream, entry);
2846 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2848 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2849 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2850 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2852 /* Take flags for key exchange. Since we do not know what type of connection
2853 this is, we go through all found configurations and use the global ones
2854 as well. This will result always into strictest key exchange flags. */
2855 memset(¶ms, 0, sizeof(params));
2856 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2857 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2858 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2859 if (server->config->param.key_exchange_pfs)
2860 params.flags |= SILC_SKE_SP_FLAG_PFS;
2862 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2863 server->stat.conn_attempts++;
2865 /* Start SILC Key Exchange protocol */
2866 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2867 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2868 server->public_key, server->private_key,
2871 server->stat.conn_failures++;
2872 silc_server_disconnect_remote(server, packet_stream,
2873 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2874 silc_server_free_sock_user_data(server, packet_stream, NULL);
2877 silc_ske_set_callbacks(ske, silc_server_verify_key,
2878 silc_server_accept_completed, packet_stream);
2880 /* Start key exchange protocol */
2881 params.version = silc_version_string;
2882 params.timeout_secs = server->config->key_exchange_timeout;
2883 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2887 /********************************** Rekey ***********************************/
2889 /* Initiator rekey completion callback */
2891 static void silc_server_rekey_completion(SilcSKE ske,
2892 SilcSKEStatus status,
2893 const SilcSKESecurityProperties prop,
2894 const SilcSKEKeyMaterial keymat,
2895 SilcSKERekeyMaterial rekey,
2898 SilcPacketStream sock = context;
2899 SilcIDListData idata = silc_packet_get_context(sock);
2900 SilcServer server = idata->sconn->server;
2902 idata->sconn->op = NULL;
2903 if (status != SILC_SKE_STATUS_OK) {
2904 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2905 idata->sconn->remote_host));
2909 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2910 idata->sconn->remote_host, idata->sconn->remote_port,
2911 SILC_CONNTYPE_STRING(idata->conn_type)));
2913 /* Save rekey data for next rekey */
2914 idata->rekey = rekey;
2916 /* Register new rekey timeout */
2917 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2918 sock, idata->sconn->rekey_timeout, 0);
2921 /* Helper to stop future rekeys on a link. */
2922 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2924 if (!client->connection)
2927 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2929 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2930 client->connection);
2933 /* Rekey callback. Start rekey as initiator */
2935 SILC_TASK_CALLBACK(silc_server_do_rekey)
2937 SilcServer server = app_context;
2938 SilcPacketStream sock = context;
2939 SilcIDListData idata = silc_packet_get_context(sock);
2942 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2944 /* Do not execute rekey with disabled connections */
2945 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2948 /* If another protocol is active do not start rekey */
2949 if (idata->sconn->op) {
2950 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2951 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2956 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2957 idata->sconn->remote_host, idata->sconn->remote_port,
2958 SILC_CONNTYPE_STRING(idata->conn_type)));
2961 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2962 server->public_key, NULL, sock);
2966 /* Set SKE callbacks */
2967 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2970 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2973 /* Responder rekey completion callback */
2976 silc_server_rekey_resp_completion(SilcSKE ske,
2977 SilcSKEStatus status,
2978 const SilcSKESecurityProperties prop,
2979 const SilcSKEKeyMaterial keymat,
2980 SilcSKERekeyMaterial rekey,
2983 SilcPacketStream sock = context;
2984 SilcIDListData idata = silc_packet_get_context(sock);
2986 idata->sconn->op = NULL;
2987 if (status != SILC_SKE_STATUS_OK) {
2988 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2989 idata->sconn->remote_host));
2993 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2994 idata->sconn->remote_host, idata->sconn->remote_port,
2995 SILC_CONNTYPE_STRING(idata->conn_type)));
2997 /* Save rekey data for next rekey */
2998 idata->rekey = rekey;
3001 /* Start rekey as responder */
3003 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
3006 SilcIDListData idata = silc_packet_get_context(sock);
3009 if (!idata->rekey) {
3010 silc_packet_free(packet);
3014 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3015 idata->sconn->remote_host, idata->sconn->remote_port,
3016 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3019 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3020 server->public_key, NULL, sock);
3022 silc_packet_free(packet);
3026 /* Set SKE callbacks */
3027 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3030 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3035 /****************************** Disconnection *******************************/
3037 /* Destroys packet stream. */
3039 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3041 silc_packet_stream_unref(context);
3044 /* Closes connection to socket connection */
3046 void silc_server_close_connection(SilcServer server,
3047 SilcPacketStream sock)
3049 SilcIDListData idata = silc_packet_get_context(sock);
3051 const char *hostname;
3054 if (!silc_packet_stream_is_valid(sock))
3057 memset(tmp, 0, sizeof(tmp));
3058 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3059 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3060 NULL, &hostname, NULL, &port);
3061 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3062 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3063 tmp[0] ? tmp : ""));
3065 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3067 if (idata && idata->sconn) {
3068 silc_server_connection_free(idata->sconn);
3069 idata->sconn = NULL;
3072 /* Take a reference and then destroy the stream. The last reference
3073 is released later in a timeout callback. */
3074 silc_packet_stream_ref(sock);
3075 silc_packet_stream_destroy(sock);
3077 /* Close connection with timeout */
3078 server->stat.conn_num--;
3079 silc_schedule_task_del_by_all(server->schedule, 0,
3080 silc_server_close_connection_final, sock);
3081 silc_schedule_task_add_timeout(server->schedule,
3082 silc_server_close_connection_final,
3086 /* Sends disconnect message to remote connection and disconnects the
3089 void silc_server_disconnect_remote(SilcServer server,
3090 SilcPacketStream sock,
3091 SilcStatus status, ...)
3093 unsigned char buf[512];
3100 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock));
3102 va_start(ap, status);
3103 cp = va_arg(ap, char *);
3105 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3108 /* Send SILC_PACKET_DISCONNECT */
3109 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3110 SILC_STR_UI_CHAR(status),
3111 SILC_STR_UI8_STRING(cp ? buf : NULL),
3114 /* Close connection */
3115 silc_server_close_connection(server, sock);
3118 /* Frees client data and notifies about client's signoff. */
3120 void silc_server_free_client_data(SilcServer server,
3121 SilcPacketStream sock,
3122 SilcClientEntry client,
3124 const char *signoff)
3126 SILC_LOG_DEBUG(("Freeing client %p data", client));
3129 /* Check if anyone is watching this nickname */
3130 if (server->server_type == SILC_ROUTER)
3131 silc_server_check_watcher_list(server, client, NULL,
3132 SILC_NOTIFY_TYPE_SIGNOFF);
3134 /* Send SIGNOFF notify to routers. */
3136 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3137 SILC_BROADCAST(server), client->id,
3141 /* Remove client from all channels */
3143 silc_server_remove_from_channels(server, NULL, client,
3144 TRUE, (char *)signoff, TRUE, FALSE);
3146 silc_server_remove_from_channels(server, NULL, client,
3147 FALSE, NULL, FALSE, FALSE);
3149 /* Remove this client from watcher list if it is */
3150 silc_server_del_from_watcher_list(server, client);
3152 /* Remove client's public key from repository, this will free it too. */
3153 if (client->data.public_key) {
3154 silc_skr_del_public_key(server->repository, client->data.public_key,
3156 client->data.public_key = NULL;
3159 /* Update statistics */
3161 /* Local detached clients aren't counted. */
3162 if (!client->local_detached)
3163 server->stat.my_clients--;
3164 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3165 server->stat.clients - 1));
3166 SILC_VERIFY(server->stat.clients > 0);
3167 server->stat.clients--;
3168 if (server->stat.cell_clients)
3169 server->stat.cell_clients--;
3170 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3171 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3172 silc_schedule_task_del_by_context(server->schedule, client);
3174 if (client->data.sconn) {
3175 silc_server_connection_free(client->data.sconn);
3176 client->data.sconn = NULL;
3179 /* We will not delete the client entry right away. We will take it
3180 into history (for WHOWAS command) for 5 minutes, unless we're
3181 shutting down server. */
3182 if (!server->server_shutdown) {
3183 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3185 client->router = NULL;
3186 client->connection = NULL;
3187 client->data.created = silc_time();
3188 silc_dlist_del(server->expired_clients, client);
3189 silc_dlist_add(server->expired_clients, client);
3191 /* Delete directly since we're shutting down server */
3192 SILC_LOG_DEBUG(("Delete client directly"));
3193 silc_idlist_del_data(client);
3194 silc_idlist_del_client(server->local_list, client);
3198 /* Frees user_data pointer from socket connection object. This also sends
3199 appropriate notify packets to the network to inform about leaving
3202 void silc_server_free_sock_user_data(SilcServer server,
3203 SilcPacketStream sock,
3204 const char *signoff_message)
3206 SilcIDListData idata;
3213 SILC_LOG_DEBUG(("Start, sock %p", sock));
3215 idata = silc_packet_get_context(sock);
3219 /* Remove any possible pending timeout */
3220 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3222 silc_schedule_task_del_by_all(server->schedule, 0,
3223 silc_server_packet_error_timeout, sock);
3225 /* Cancel active protocols */
3227 if (idata->sconn && idata->sconn->op) {
3228 SILC_LOG_DEBUG(("Abort active protocol"));
3229 silc_async_abort(idata->sconn->op, NULL, NULL);
3230 idata->sconn->op = NULL;
3232 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3233 ((SilcUnknownEntry)idata)->op) {
3234 SILC_LOG_DEBUG(("Abort active protocol"));
3235 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3236 idata->sconn->op = NULL;
3240 switch (idata->conn_type) {
3241 case SILC_CONN_CLIENT:
3243 SilcClientEntry client_entry = (SilcClientEntry)idata;
3244 silc_server_free_client_data(server, sock, client_entry, TRUE,
3246 silc_packet_set_context(sock, NULL);
3250 case SILC_CONN_SERVER:
3251 case SILC_CONN_ROUTER:
3253 SilcServerEntry user_data = (SilcServerEntry)idata;
3254 SilcServerEntry backup_router = NULL;
3256 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3259 backup_router = silc_server_backup_get(server, user_data->id);
3261 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3262 backup_router == server->id_entry &&
3263 idata->conn_type != SILC_CONN_ROUTER)
3264 backup_router = NULL;
3266 if (server->server_shutdown || server->backup_noswitch)
3267 backup_router = NULL;
3269 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3270 NULL, NULL, &ip, &port);
3272 /* If this was our primary router connection then we're lost to
3273 the outside world. */
3274 if (server->router == user_data) {
3275 /* Check whether we have a backup router connection */
3276 if (!backup_router || backup_router == user_data) {
3277 if (!server->no_reconnect)
3278 silc_server_create_connections(server);
3279 server->id_entry->router = NULL;
3280 server->router = NULL;
3281 server->standalone = TRUE;
3282 server->backup_primary = FALSE;
3283 backup_router = NULL;
3285 if (server->id_entry != backup_router) {
3286 SILC_LOG_INFO(("New primary router is backup router %s",
3287 backup_router->server_name));
3288 server->id_entry->router = backup_router;
3289 server->router = backup_router;
3290 server->router_connect = time(0);
3291 server->backup_primary = TRUE;
3292 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3294 /* Send START_USE to backup router to indicate we have switched */
3295 silc_server_backup_send_start_use(server,
3296 backup_router->connection,
3299 SILC_LOG_INFO(("We are now new primary router in this cell"));
3300 server->id_entry->router = NULL;
3301 server->router = NULL;
3302 server->standalone = TRUE;
3305 /* We stop here to take a breath */
3308 if (server->backup_router) {
3309 server->server_type = SILC_ROUTER;
3311 /* We'll need to constantly try to reconnect to the primary
3312 router so that we'll see when it comes back online. */
3313 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3314 silc_server_backup_connected,
3318 /* Mark this connection as replaced */
3319 silc_server_backup_replaced_add(server, user_data->id,
3322 } else if (backup_router) {
3323 SILC_LOG_INFO(("Enabling the use of backup router %s",
3324 backup_router->server_name));
3326 /* Mark this connection as replaced */
3327 silc_server_backup_replaced_add(server, user_data->id,
3329 } else if (server->server_type == SILC_SERVER &&
3330 idata->conn_type == SILC_CONN_ROUTER) {
3331 /* Reconnect to the router (backup) */
3332 if (!server->no_reconnect)
3333 silc_server_create_connections(server);
3336 if (user_data->server_name)
3337 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3338 ("Server %s signoff", user_data->server_name));
3340 if (!backup_router) {
3341 /* Remove all servers that are originated from this server, and
3342 remove the clients of those servers too. */
3343 silc_server_remove_servers_by_server(server, user_data, TRUE);
3346 /* Remove the clients that this server owns as they will become
3347 invalid now too. For backup router the server is actually
3348 coming from the primary router, so mark that as the owner
3350 if (server->server_type == SILC_BACKUP_ROUTER &&
3351 sock->type == SILC_CONN_SERVER)
3352 silc_server_remove_clients_by_server(server, server->router,
3356 silc_server_remove_clients_by_server(server, user_data,
3359 /* Remove channels owned by this server */
3360 if (server->server_type == SILC_SERVER)
3361 silc_server_remove_channels_by_server(server, user_data);
3363 /* Enable local server connections that may be disabled */
3364 silc_server_local_servers_toggle_enabled(server, TRUE);
3366 /* Update the client entries of this server to the new backup
3367 router. If we are the backup router we also resolve the real
3368 servers for the clients. After updating is over this also
3369 removes the clients that this server explicitly owns. */
3370 silc_server_update_clients_by_server(server, user_data,
3371 backup_router, TRUE);
3373 /* If we are router and just lost our primary router (now standlaone)
3374 we remove everything that was behind it, since we don't know
3376 if (server->server_type == SILC_ROUTER && server->standalone)
3377 /* Remove all servers that are originated from this server, and
3378 remove the clients of those servers too. */
3379 silc_server_remove_servers_by_server(server, user_data, TRUE);
3381 /* Finally remove the clients that are explicitly owned by this
3382 server. They go down with the server. */
3383 silc_server_remove_clients_by_server(server, user_data,
3386 /* Update our server cache to use the new backup router too. */
3387 silc_server_update_servers_by_server(server, user_data, backup_router);
3388 if (server->server_type == SILC_SERVER)
3389 silc_server_update_channels_by_server(server, user_data,
3392 /* Send notify about primary router going down to local operators */
3393 if (server->backup_router)
3394 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3395 SILC_NOTIFY_TYPE_NONE,
3396 ("%s switched to backup router %s "
3397 "(we are primary router now)",
3398 server->server_name, server->server_name));
3399 else if (server->router)
3400 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3401 SILC_NOTIFY_TYPE_NONE,
3402 ("%s switched to backup router %s",
3403 server->server_name,
3404 server->router->server_name));
3406 server->backup_noswitch = FALSE;
3409 silc_server_connection_free(idata->sconn);
3410 idata->sconn = NULL;
3414 if (idata->conn_type == SILC_CONN_SERVER) {
3415 server->stat.my_servers--;
3416 server->stat.servers--;
3417 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3418 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3419 server->stat.my_routers--;
3420 server->stat.routers--;
3421 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3423 if (server->server_type == SILC_ROUTER)
3424 server->stat.cell_servers--;
3426 /* Free the server entry */
3427 silc_server_backup_del(server, user_data);
3428 silc_server_backup_replaced_del(server, user_data);
3429 silc_idlist_del_data(user_data);
3430 if (!silc_idlist_del_server(server->local_list, user_data))
3431 silc_idlist_del_server(server->global_list, user_data);
3433 if (backup_router && backup_router != server->id_entry) {
3434 /* Announce all of our stuff that was created about 5 minutes ago.
3435 The backup router knows all the other stuff already. */
3436 if (server->server_type == SILC_ROUTER)
3437 silc_server_announce_servers(server, FALSE, time(0) - 300,
3438 backup_router->connection);
3440 /* Announce our clients and channels to the router */
3441 silc_server_announce_clients(server, time(0) - 300,
3442 backup_router->connection);
3443 silc_server_announce_channels(server, time(0) - 300,
3444 backup_router->connection);
3447 silc_packet_set_context(sock, NULL);
3453 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3455 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3458 if (server->router_conn == idata->sconn) {
3459 if (!server->no_reconnect)
3460 silc_server_create_connections(server);
3461 server->router_conn = NULL;
3464 silc_server_connection_free(idata->sconn);
3465 idata->sconn = NULL;
3467 silc_idlist_del_data(idata);
3469 silc_packet_set_context(sock, NULL);
3475 /* Removes client from all channels it has joined. This is used when client
3476 connection is disconnected. If the client on a channel is last, the
3477 channel is removed as well. This sends the SIGNOFF notify types. */
3479 void silc_server_remove_from_channels(SilcServer server,
3480 SilcPacketStream sock,
3481 SilcClientEntry client,
3483 const char *signoff_message,
3487 SilcChannelEntry channel;
3488 SilcChannelClientEntry chl;
3489 SilcHashTableList htl;
3490 SilcBuffer clidp = NULL;
3495 if (notify && !client->id)
3498 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3499 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3502 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3507 /* Remove the client from all channels. The client is removed from
3508 the channels' user list. */
3509 silc_hash_table_list(client->channels, &htl);
3510 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3511 channel = chl->channel;
3513 /* Remove channel if this is last client leaving the channel, unless
3514 the channel is permanent. */
3515 if (server->server_type != SILC_SERVER &&
3516 silc_hash_table_count(channel->user_list) < 2) {
3517 silc_server_channel_delete(server, channel);
3521 silc_hash_table_del(client->channels, channel);
3522 silc_hash_table_del(channel->user_list, client);
3523 channel->user_count--;
3525 /* If there is no global users on the channel anymore mark the channel
3526 as local channel. Do not check if the removed client is local client. */
3527 if (server->server_type == SILC_SERVER && channel->global_users &&
3528 chl->client->router && !silc_server_channel_has_global(channel))
3529 channel->global_users = FALSE;
3531 memset(chl, 'A', sizeof(*chl));
3534 /* Update statistics */
3535 if (SILC_IS_LOCAL(client))
3536 server->stat.my_chanclients--;
3537 if (server->server_type == SILC_ROUTER) {
3538 server->stat.cell_chanclients--;
3539 server->stat.chanclients--;
3542 /* If there is not at least one local user on the channel then we don't
3543 need the channel entry anymore, we can remove it safely, unless the
3544 channel is permanent channel */
3545 if (server->server_type == SILC_SERVER &&
3546 !silc_server_channel_has_local(channel)) {
3547 /* Notify about leaving client if this channel has global users. */
3548 if (notify && channel->global_users)
3549 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3550 SILC_NOTIFY_TYPE_SIGNOFF,
3551 signoff_message ? 2 : 1,
3552 clidp->data, silc_buffer_len(clidp),
3553 signoff_message, signoff_message ?
3554 strlen(signoff_message) : 0);
3556 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3557 silc_server_channel_delete(server, channel);
3561 /* Send notify to channel about client leaving SILC and channel too */
3563 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3564 SILC_NOTIFY_TYPE_SIGNOFF,
3565 signoff_message ? 2 : 1,
3566 clidp->data, silc_buffer_len(clidp),
3567 signoff_message, signoff_message ?
3568 strlen(signoff_message) : 0);
3570 if (killed && clidp) {
3571 /* Remove the client from channel's invite list */
3572 if (channel->invite_list &&
3573 silc_hash_table_count(channel->invite_list)) {
3575 SilcArgumentPayload iargs;
3576 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3577 silc_buffer_len(clidp), 3);
3578 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3579 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3580 silc_buffer_free(ab);
3581 silc_argument_payload_free(iargs);
3585 /* Don't create keys if we are shutting down */
3586 if (server->server_shutdown)
3589 /* Re-generate channel key if needed */
3590 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3591 if (!silc_server_create_channel_key(server, channel, 0))
3594 /* Send the channel key to the channel. The key of course is not sent
3595 to the client who was removed from the channel. */
3596 silc_server_send_channel_key(server, client->connection, channel,
3597 server->server_type == SILC_ROUTER ?
3598 FALSE : !server->standalone);
3602 silc_hash_table_list_reset(&htl);
3604 silc_buffer_free(clidp);
3607 /* Removes client from one channel. This is used for example when client
3608 calls LEAVE command to remove itself from the channel. Returns TRUE
3609 if channel still exists and FALSE if the channel is removed when
3610 last client leaves the channel. If `notify' is FALSE notify messages
3613 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3614 SilcPacketStream sock,
3615 SilcChannelEntry channel,
3616 SilcClientEntry client,
3619 SilcChannelClientEntry chl;
3622 SILC_LOG_DEBUG(("Removing %s from channel %s",
3623 silc_id_render(client->id, SILC_ID_CLIENT),
3624 channel->channel_name));
3626 /* Get the entry to the channel, if this client is not on the channel
3628 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3631 /* Remove channel if this is last client leaving the channel, unless
3632 the channel is permanent. */
3633 if (server->server_type != SILC_SERVER &&
3634 silc_hash_table_count(channel->user_list) < 2) {
3635 silc_server_channel_delete(server, channel);
3639 silc_hash_table_del(client->channels, channel);
3640 silc_hash_table_del(channel->user_list, client);
3641 channel->user_count--;
3643 /* If there is no global users on the channel anymore mark the channel
3644 as local channel. Do not check if the client is local client. */
3645 if (server->server_type == SILC_SERVER && channel->global_users &&
3646 chl->client->router && !silc_server_channel_has_global(channel))
3647 channel->global_users = FALSE;
3649 memset(chl, 'O', sizeof(*chl));
3652 /* Update statistics */
3653 if (SILC_IS_LOCAL(client))
3654 server->stat.my_chanclients--;
3655 if (server->server_type == SILC_ROUTER) {
3656 server->stat.cell_chanclients--;
3657 server->stat.chanclients--;
3660 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3664 /* If there is not at least one local user on the channel then we don't
3665 need the channel entry anymore, we can remove it safely, unless the
3666 channel is permanent channel */
3667 if (server->server_type == SILC_SERVER &&
3668 !silc_server_channel_has_local(channel)) {
3669 /* Notify about leaving client if this channel has global users. */
3670 if (notify && channel->global_users)
3671 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3672 SILC_NOTIFY_TYPE_LEAVE, 1,
3673 clidp->data, silc_buffer_len(clidp));
3675 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3676 silc_server_channel_delete(server, channel);
3677 silc_buffer_free(clidp);
3681 /* Send notify to channel about client leaving the channel */
3683 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3684 SILC_NOTIFY_TYPE_LEAVE, 1,
3685 clidp->data, silc_buffer_len(clidp));
3687 silc_buffer_free(clidp);
3691 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3692 function may be used only by router. In real SILC network all channels
3693 are created by routers thus this function is never used by normal
3696 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3697 SilcServerID *router_id,
3703 SilcChannelID *channel_id;
3704 SilcChannelEntry entry;
3705 SilcCipher send_key, receive_key;
3708 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3711 cipher = SILC_DEFAULT_CIPHER;
3713 hmac = SILC_DEFAULT_HMAC;
3715 /* Allocate cipher */
3716 if (!silc_cipher_alloc(cipher, &send_key))
3718 if (!silc_cipher_alloc(cipher, &receive_key)) {
3719 silc_cipher_free(send_key);
3724 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3725 silc_cipher_free(send_key);
3726 silc_cipher_free(receive_key);
3730 channel_name = strdup(channel_name);
3732 /* Create the channel ID */
3733 if (!silc_id_create_channel_id(server, router_id, server->rng,
3735 silc_free(channel_name);
3736 silc_cipher_free(send_key);
3737 silc_cipher_free(receive_key);
3738 silc_hmac_free(newhmac);
3742 /* Create the channel */
3743 entry = silc_idlist_add_channel(server->local_list, channel_name,
3744 SILC_CHANNEL_MODE_NONE, channel_id,
3745 NULL, send_key, receive_key, newhmac);
3747 silc_free(channel_name);
3748 silc_cipher_free(send_key);
3749 silc_cipher_free(receive_key);
3750 silc_hmac_free(newhmac);
3751 silc_free(channel_id);
3755 entry->cipher = strdup(cipher);
3756 entry->hmac_name = strdup(hmac);
3758 /* Now create the actual key material */
3759 if (!silc_server_create_channel_key(server, entry,
3760 silc_cipher_get_key_len(send_key) / 8)) {
3761 silc_idlist_del_channel(server->local_list, entry);
3765 /* Notify other routers about the new channel. We send the packet
3766 to our primary route. */
3768 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3769 channel_name, entry->id,
3770 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3773 /* Distribute to backup routers */
3774 if (broadcast && server->server_type == SILC_ROUTER) {
3776 unsigned char cid[32];
3777 SilcUInt32 name_len = strlen(channel_name);
3780 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3781 packet = silc_channel_payload_encode(channel_name, name_len,
3782 cid, id_len, entry->mode);
3783 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3784 packet->data, silc_buffer_len(packet), FALSE,
3786 silc_buffer_free(packet);
3789 server->stat.my_channels++;
3790 if (server->server_type == SILC_ROUTER) {
3791 server->stat.channels++;
3792 server->stat.cell_channels++;
3793 entry->users_resolved = TRUE;
3799 /* Same as above but creates the channel with Channel ID `channel_id. */
3802 silc_server_create_new_channel_with_id(SilcServer server,
3806 SilcChannelID *channel_id,
3809 SilcChannelEntry entry;
3810 SilcCipher send_key, receive_key;
3813 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3816 cipher = SILC_DEFAULT_CIPHER;
3818 hmac = SILC_DEFAULT_HMAC;
3820 /* Allocate cipher */
3821 if (!silc_cipher_alloc(cipher, &send_key))
3823 if (!silc_cipher_alloc(cipher, &receive_key)) {
3824 silc_cipher_free(send_key);
3829 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3830 silc_cipher_free(send_key);
3831 silc_cipher_free(receive_key);
3835 channel_name = strdup(channel_name);
3837 /* Create the channel */
3838 entry = silc_idlist_add_channel(server->local_list, channel_name,
3839 SILC_CHANNEL_MODE_NONE, channel_id,
3840 NULL, send_key, receive_key, newhmac);
3842 silc_cipher_free(send_key);
3843 silc_cipher_free(receive_key);
3844 silc_hmac_free(newhmac);
3845 silc_free(channel_name);
3849 /* Now create the actual key material */
3850 if (!silc_server_create_channel_key(server, entry,
3851 silc_cipher_get_key_len(send_key) / 8)) {
3852 silc_idlist_del_channel(server->local_list, entry);
3856 /* Notify other routers about the new channel. We send the packet
3857 to our primary route. */
3859 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3860 channel_name, entry->id,
3861 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3864 /* Distribute to backup routers */
3865 if (broadcast && server->server_type == SILC_ROUTER) {
3867 unsigned char cid[32];
3868 SilcUInt32 name_len = strlen(channel_name);
3871 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3872 packet = silc_channel_payload_encode(channel_name, name_len,
3873 cid, id_len, entry->mode);
3874 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3875 packet->data, silc_buffer_len(packet), FALSE,
3877 silc_buffer_free(packet);
3880 server->stat.my_channels++;
3881 if (server->server_type == SILC_ROUTER) {
3882 server->stat.channels++;
3883 server->stat.cell_channels++;
3884 entry->users_resolved = TRUE;
3890 /* Channel's key re-key timeout callback. */
3892 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3894 SilcServer server = app_context;
3895 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3899 /* Return now if we are shutting down */
3900 if (server->server_shutdown)
3903 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3906 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3909 /* Generates new channel key. This is used to create the initial channel key
3910 but also to re-generate new key for channel. If `key_len' is provided
3911 it is the bytes of the key length. */
3913 SilcBool silc_server_create_channel_key(SilcServer server,
3914 SilcChannelEntry channel,
3918 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3921 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3922 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3926 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3928 if (!channel->send_key)
3929 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3930 channel->send_key = NULL;
3933 if (!channel->receive_key)
3934 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3935 silc_cipher_free(channel->send_key);
3936 channel->send_key = channel->receive_key = NULL;
3942 else if (channel->key_len)
3943 len = channel->key_len / 8;
3945 len = silc_cipher_get_key_len(channel->send_key) / 8;
3947 /* Create channel key */
3948 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3951 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3952 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3954 /* Remove old key if exists */
3956 memset(channel->key, 0, channel->key_len / 8);
3957 silc_free(channel->key);
3961 channel->key_len = len * 8;
3962 channel->key = silc_memdup(channel_key, len);
3963 memset(channel_key, 0, sizeof(channel_key));
3965 /* Generate HMAC key from the channel key data and set it */
3967 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3968 memset(channel->key, 0, channel->key_len / 8);
3969 silc_free(channel->key);
3970 silc_cipher_free(channel->send_key);
3971 silc_cipher_free(channel->receive_key);
3972 channel->send_key = channel->receive_key = NULL;
3975 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3976 silc_hmac_set_key(channel->hmac, hash,
3977 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3978 memset(hash, 0, sizeof(hash));
3980 if (server->server_type == SILC_ROUTER) {
3981 if (!channel->rekey)
3982 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3983 channel->rekey->channel = channel;
3984 channel->rekey->key_len = key_len;
3985 if (channel->rekey->task)
3986 silc_schedule_task_del(server->schedule, channel->rekey->task);
3988 channel->rekey->task =
3989 silc_schedule_task_add_timeout(server->schedule,
3990 silc_server_channel_key_rekey,
3991 (void *)channel->rekey,
3992 server->config->channel_rekey_secs, 0);
3998 /* Saves the channel key found in the encoded `key_payload' buffer. This
3999 function is used when we receive Channel Key Payload and also when we're
4000 processing JOIN command reply. Returns entry to the channel. */
4002 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4003 SilcBuffer key_payload,
4004 SilcChannelEntry channel)
4006 SilcChannelKeyPayload payload = NULL;
4008 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4012 /* Decode channel key payload */
4013 payload = silc_channel_key_payload_parse(key_payload->data,
4014 silc_buffer_len(key_payload));
4016 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4021 /* Get the channel entry */
4024 /* Get channel ID */
4025 tmp = silc_channel_key_get_id(payload, &tmp_len);
4026 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4031 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4033 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4035 if (server->server_type == SILC_ROUTER)
4036 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4037 silc_id_render(&id, SILC_ID_CHANNEL)));
4043 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4045 tmp = silc_channel_key_get_key(payload, &tmp_len);
4051 cipher = silc_channel_key_get_cipher(payload, NULL);
4057 /* Remove old key if exists */
4059 memset(channel->key, 0, channel->key_len / 8);
4060 silc_free(channel->key);
4061 silc_cipher_free(channel->send_key);
4062 silc_cipher_free(channel->receive_key);
4065 /* Create new cipher */
4066 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4067 channel->send_key = NULL;
4071 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4072 silc_cipher_free(channel->send_key);
4073 channel->send_key = channel->receive_key = NULL;
4078 if (channel->cipher)
4079 silc_free(channel->cipher);
4080 channel->cipher = strdup(cipher);
4083 channel->key_len = tmp_len * 8;
4084 channel->key = silc_memdup(tmp, tmp_len);
4085 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4086 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4088 /* Generate HMAC key from the channel key data and set it */
4090 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4091 memset(channel->key, 0, channel->key_len / 8);
4092 silc_free(channel->key);
4093 silc_cipher_free(channel->send_key);
4094 silc_cipher_free(channel->receive_key);
4095 channel->send_key = channel->receive_key = NULL;
4098 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4099 silc_hmac_set_key(channel->hmac, hash,
4100 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4102 memset(hash, 0, sizeof(hash));
4103 memset(tmp, 0, tmp_len);
4105 if (server->server_type == SILC_ROUTER) {
4106 if (!channel->rekey)
4107 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4108 channel->rekey->channel = channel;
4109 if (channel->rekey->task)
4110 silc_schedule_task_del(server->schedule, channel->rekey->task);
4112 channel->rekey->task =
4113 silc_schedule_task_add_timeout(server->schedule,
4114 silc_server_channel_key_rekey,
4115 (void *)channel->rekey,
4116 server->config->channel_rekey_secs, 0);
4121 silc_channel_key_payload_free(payload);
4126 /* Returns assembled of all servers in the given ID list. The packet's
4127 form is dictated by the New ID payload. */
4129 static void silc_server_announce_get_servers(SilcServer server,
4130 SilcServerEntry remote,
4132 SilcBuffer *servers,
4133 unsigned long creation_time)
4136 SilcIDCacheEntry id_cache;
4137 SilcServerEntry entry;
4141 /* Go through all clients in the list */
4142 if (silc_idcache_get_all(id_list->servers, &list)) {
4143 silc_list_start(list);
4144 while ((id_cache = silc_list_get(list))) {
4145 entry = (SilcServerEntry)id_cache->context;
4147 /* Do not announce the one we've sending our announcements and
4148 do not announce ourself. Also check the creation time if it's
4150 if ((entry == remote) || (entry == server->id_entry) ||
4151 (creation_time && entry->data.created < creation_time))
4154 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4156 tmp = silc_buffer_realloc(*servers,
4158 silc_buffer_truelen((*servers)) +
4159 silc_buffer_len(idp) :
4160 silc_buffer_len(idp)));
4164 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4165 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4166 silc_buffer_pull(*servers, silc_buffer_len(idp));
4167 silc_buffer_free(idp);
4173 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4179 p = silc_notify_payload_encode(notify, argc, ap);
4185 /* This function is used by router to announce existing servers to our
4186 primary router when we've connected to it. If `creation_time' is non-zero
4187 then only the servers that has been created after the `creation_time'
4188 will be announced. */
4190 void silc_server_announce_servers(SilcServer server, SilcBool global,
4191 unsigned long creation_time,
4192 SilcPacketStream remote)
4194 SilcBuffer servers = NULL;
4196 SILC_LOG_DEBUG(("Announcing servers"));
4198 /* Get servers in local list */
4199 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4200 server->local_list, &servers,
4204 /* Get servers in global list */
4205 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4206 server->global_list, &servers,
4210 silc_buffer_push(servers, servers->data - servers->head);
4211 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4213 /* Send the packet */
4214 silc_server_packet_send(server, remote,
4215 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4216 servers->data, silc_buffer_len(servers));
4218 silc_buffer_free(servers);
4222 /* Returns assembled packet of all clients in the given ID list. The
4223 packet's form is dictated by the New ID Payload. */
4225 static void silc_server_announce_get_clients(SilcServer server,
4227 SilcBuffer *clients,
4229 unsigned long creation_time)
4232 SilcIDCacheEntry id_cache;
4233 SilcClientEntry client;
4236 unsigned char mode[4];
4239 /* Go through all clients in the list */
4240 if (silc_idcache_get_all(id_list->clients, &list)) {
4241 silc_list_start(list);
4242 while ((id_cache = silc_list_get(list))) {
4243 client = (SilcClientEntry)id_cache->context;
4245 if (creation_time && client->data.created < creation_time)
4247 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4249 if (!client->connection && !client->router)
4252 SILC_LOG_DEBUG(("Announce Client ID %s",
4253 silc_id_render(client->id, SILC_ID_CLIENT)));
4255 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4259 tmp2 = silc_buffer_realloc(*clients,
4261 silc_buffer_truelen((*clients)) +
4262 silc_buffer_len(idp) :
4263 silc_buffer_len(idp)));
4267 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4268 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4269 silc_buffer_pull(*clients, silc_buffer_len(idp));
4271 SILC_PUT32_MSB(client->mode, mode);
4273 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4274 2, idp->data, silc_buffer_len(idp),
4276 tmp2 = silc_buffer_realloc(*umodes,
4278 silc_buffer_truelen((*umodes)) +
4279 silc_buffer_len(tmp) :
4280 silc_buffer_len(tmp)));
4284 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4285 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4286 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4287 silc_buffer_free(tmp);
4289 silc_buffer_free(idp);
4294 /* This function is used to announce our existing clients to our router
4295 when we've connected to it. If `creation_time' is non-zero then only
4296 the clients that has been created after the `creation_time' will be
4299 void silc_server_announce_clients(SilcServer server,
4300 unsigned long creation_time,
4301 SilcPacketStream remote)
4303 SilcBuffer clients = NULL;
4304 SilcBuffer umodes = NULL;
4306 SILC_LOG_DEBUG(("Announcing clients"));
4308 /* Get clients in local list */
4309 silc_server_announce_get_clients(server, server->local_list,
4310 &clients, &umodes, creation_time);
4312 /* As router we announce our global list as well */
4313 if (server->server_type == SILC_ROUTER)
4314 silc_server_announce_get_clients(server, server->global_list,
4315 &clients, &umodes, creation_time);
4318 silc_buffer_push(clients, clients->data - clients->head);
4319 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4321 /* Send the packet */
4322 silc_server_packet_send(server, remote,
4323 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4324 clients->data, silc_buffer_len(clients));
4326 silc_buffer_free(clients);
4330 silc_buffer_push(umodes, umodes->data - umodes->head);
4331 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4333 /* Send the packet */
4334 silc_server_packet_send(server, remote,
4335 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4336 umodes->data, silc_buffer_len(umodes));
4338 silc_buffer_free(umodes);
4342 /* Returns channel's topic for announcing it */
4344 void silc_server_announce_get_channel_topic(SilcServer server,
4345 SilcChannelEntry channel,
4350 if (channel->topic) {
4351 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4352 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4354 silc_buffer_len(chidp),
4356 strlen(channel->topic));
4357 silc_buffer_free(chidp);
4361 /* Returns channel's invite and ban lists */
4363 void silc_server_announce_get_inviteban(SilcServer server,
4364 SilcChannelEntry channel,
4368 SilcBuffer list, idp, idp2, tmp2;
4371 SilcHashTableList htl;
4372 const unsigned char a[1] = { 0x03 };
4374 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4376 /* Encode invite list */
4377 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4378 list = silc_buffer_alloc_size(2);
4379 type = silc_hash_table_count(channel->invite_list);
4380 SILC_PUT16_MSB(type, list->data);
4381 silc_hash_table_list(channel->invite_list, &htl);
4382 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4383 list = silc_argument_payload_encode_one(list, tmp2->data,
4384 silc_buffer_len(tmp2),
4385 SILC_PTR_TO_32(ptype));
4386 silc_hash_table_list_reset(&htl);
4388 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4390 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4391 idp->data, silc_buffer_len(idp),
4392 channel->channel_name,
4393 strlen(channel->channel_name),
4394 idp2->data, silc_buffer_len(idp2),
4396 list->data, silc_buffer_len(list));
4397 silc_buffer_free(idp2);
4398 silc_buffer_free(list);
4401 /* Encode ban list */
4402 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4403 list = silc_buffer_alloc_size(2);
4404 type = silc_hash_table_count(channel->ban_list);
4405 SILC_PUT16_MSB(type, list->data);
4406 silc_hash_table_list(channel->ban_list, &htl);
4407 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4408 list = silc_argument_payload_encode_one(list, tmp2->data,
4409 silc_buffer_len(tmp2),
4410 SILC_PTR_TO_32(ptype));
4411 silc_hash_table_list_reset(&htl);
4414 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4415 idp->data, silc_buffer_len(idp),
4417 list->data, silc_buffer_len(list));
4418 silc_buffer_free(list);
4421 silc_buffer_free(idp);
4424 /* Returns assembled packets for channel users of the `channel'. */
4426 void silc_server_announce_get_channel_users(SilcServer server,
4427 SilcChannelEntry channel,
4428 SilcBuffer *channel_modes,
4429 SilcBuffer *channel_users,
4430 SilcBuffer *channel_users_modes)
4432 SilcChannelClientEntry chl;
4433 SilcHashTableList htl;
4434 SilcBuffer chidp, clidp, csidp;
4435 SilcBuffer tmp, fkey = NULL, chpklist;
4437 unsigned char mode[4], ulimit[4];
4441 SILC_LOG_DEBUG(("Start"));
4443 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4444 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4445 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4448 SILC_PUT32_MSB(channel->mode, mode);
4449 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4450 SILC_PUT32_MSB(channel->user_limit, ulimit);
4451 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4452 if (channel->founder_key)
4453 fkey = silc_public_key_payload_encode(channel->founder_key);
4455 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4457 silc_buffer_len(csidp),
4460 hmac, hmac ? strlen(hmac) : 0,
4461 channel->passphrase,
4462 channel->passphrase ?
4463 strlen(channel->passphrase) : 0,
4464 fkey ? fkey->data : NULL,
4465 fkey ? silc_buffer_len(fkey) : 0,
4466 chpklist ? chpklist->data : NULL,
4468 silc_buffer_len(chpklist) : 0,
4470 SILC_CHANNEL_MODE_ULIMIT ?
4473 SILC_CHANNEL_MODE_ULIMIT ?
4474 sizeof(ulimit) : 0));
4475 len = silc_buffer_len(tmp);
4477 silc_buffer_realloc(*channel_modes,
4479 silc_buffer_truelen((*channel_modes)) + len : len));
4482 *channel_modes = tmp2;
4483 silc_buffer_pull_tail(*channel_modes,
4484 ((*channel_modes)->end -
4485 (*channel_modes)->data));
4486 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4487 silc_buffer_pull(*channel_modes, len);
4488 silc_buffer_free(tmp);
4489 silc_buffer_free(fkey);
4492 /* Now find all users on the channel */
4493 silc_hash_table_list(channel->user_list, &htl);
4494 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4495 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4497 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4501 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4503 silc_buffer_len(clidp),
4505 silc_buffer_len(chidp));
4506 len = silc_buffer_len(tmp);
4508 silc_buffer_realloc(*channel_users,
4510 silc_buffer_truelen((*channel_users)) + len : len));
4513 *channel_users = tmp2;
4514 silc_buffer_pull_tail(*channel_users,
4515 ((*channel_users)->end -
4516 (*channel_users)->data));
4518 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4519 silc_buffer_pull(*channel_users, len);
4520 silc_buffer_free(tmp);
4522 /* CUMODE notify for mode change on the channel */
4523 SILC_PUT32_MSB(chl->mode, mode);
4524 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4525 fkey = silc_public_key_payload_encode(channel->founder_key);
4526 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4528 silc_buffer_len(csidp),
4531 silc_buffer_len(clidp),
4532 fkey ? fkey->data : NULL,
4533 fkey ? silc_buffer_len(fkey) : 0);
4534 len = silc_buffer_len(tmp);
4536 silc_buffer_realloc(*channel_users_modes,
4537 (*channel_users_modes ?
4538 silc_buffer_truelen((*channel_users_modes)) +
4542 *channel_users_modes = tmp2;
4543 silc_buffer_pull_tail(*channel_users_modes,
4544 ((*channel_users_modes)->end -
4545 (*channel_users_modes)->data));
4547 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4548 silc_buffer_pull(*channel_users_modes, len);
4549 silc_buffer_free(tmp);
4550 silc_buffer_free(fkey);
4552 silc_buffer_free(clidp);
4554 silc_hash_table_list_reset(&htl);
4555 silc_buffer_free(chidp);
4556 silc_buffer_free(csidp);
4559 /* Returns assembled packets for all channels and users on those channels
4560 from the given ID List. The packets are in the form dictated by the
4561 New Channel and New Channel User payloads. */
4563 void silc_server_announce_get_channels(SilcServer server,
4565 SilcBuffer *channels,
4566 SilcBuffer **channel_modes,
4567 SilcBuffer *channel_users,
4568 SilcBuffer **channel_users_modes,
4569 SilcUInt32 *channel_users_modes_c,
4570 SilcBuffer **channel_topics,
4571 SilcBuffer **channel_invites,
4572 SilcBuffer **channel_bans,
4573 SilcChannelID ***channel_ids,
4574 unsigned long creation_time)
4577 SilcIDCacheEntry id_cache;
4578 SilcChannelEntry channel;
4579 unsigned char cid[32];
4581 SilcUInt16 name_len;
4583 int i = *channel_users_modes_c;
4587 SILC_LOG_DEBUG(("Start"));
4589 /* Go through all channels in the list */
4590 if (silc_idcache_get_all(id_list->channels, &list)) {
4591 silc_list_start(list);
4592 while ((id_cache = silc_list_get(list))) {
4593 channel = (SilcChannelEntry)id_cache->context;
4595 if (creation_time && channel->created < creation_time)
4600 SILC_LOG_DEBUG(("Announce Channel ID %s",
4601 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4603 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4604 name_len = strlen(channel->channel_name);
4607 len = 4 + name_len + id_len + 4;
4609 silc_buffer_realloc(*channels,
4611 silc_buffer_truelen((*channels)) +
4617 silc_buffer_pull_tail(*channels,
4618 ((*channels)->end - (*channels)->data));
4619 silc_buffer_format(*channels,
4620 SILC_STR_UI_SHORT(name_len),
4621 SILC_STR_UI_XNSTRING(channel->channel_name,
4623 SILC_STR_UI_SHORT(id_len),
4624 SILC_STR_UI_XNSTRING(cid, id_len),
4625 SILC_STR_UI_INT(channel->mode),
4627 silc_buffer_pull(*channels, len);
4630 if (creation_time && channel->updated < creation_time)
4636 /* Channel user modes */
4637 tmp = silc_realloc(*channel_users_modes,
4638 sizeof(**channel_users_modes) * (i + 1));
4641 *channel_users_modes = tmp;
4642 (*channel_users_modes)[i] = NULL;
4643 tmp = silc_realloc(*channel_modes,
4644 sizeof(**channel_modes) * (i + 1));
4647 *channel_modes = tmp;
4648 (*channel_modes)[i] = NULL;
4649 tmp = silc_realloc(*channel_ids,
4650 sizeof(**channel_ids) * (i + 1));
4654 (*channel_ids)[i] = NULL;
4655 silc_server_announce_get_channel_users(server, channel,
4656 &(*channel_modes)[i],
4658 &(*channel_users_modes)[i]);
4659 (*channel_ids)[i] = channel->id;
4661 /* Channel's topic */
4662 tmp = silc_realloc(*channel_topics,
4663 sizeof(**channel_topics) * (i + 1));
4666 *channel_topics = tmp;
4667 (*channel_topics)[i] = NULL;
4668 silc_server_announce_get_channel_topic(server, channel,
4669 &(*channel_topics)[i]);
4671 /* Channel's invite and ban list */
4672 tmp = silc_realloc(*channel_invites,
4673 sizeof(**channel_invites) * (i + 1));
4676 *channel_invites = tmp;
4677 (*channel_invites)[i] = NULL;
4678 tmp = silc_realloc(*channel_bans,
4679 sizeof(**channel_bans) * (i + 1));
4682 *channel_bans = tmp;
4683 (*channel_bans)[i] = NULL;
4684 silc_server_announce_get_inviteban(server, channel,
4685 &(*channel_invites)[i],
4686 &(*channel_bans)[i]);
4688 (*channel_users_modes_c)++;
4696 /* This function is used to announce our existing channels to our router
4697 when we've connected to it. This also announces the users on the
4698 channels to the router. If the `creation_time' is non-zero only the
4699 channels that was created after the `creation_time' are announced.
4700 Note that the channel users are still announced even if the `creation_time'
4703 void silc_server_announce_channels(SilcServer server,
4704 unsigned long creation_time,
4705 SilcPacketStream remote)
4707 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4708 SilcBuffer *channel_users_modes = NULL;
4709 SilcBuffer *channel_topics = NULL;
4710 SilcBuffer *channel_invites = NULL;
4711 SilcBuffer *channel_bans = NULL;
4712 SilcUInt32 channel_users_modes_c = 0;
4713 SilcChannelID **channel_ids = NULL;
4715 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4717 /* Get channels and channel users in local list */
4718 silc_server_announce_get_channels(server, server->local_list,
4719 &channels, &channel_modes,
4721 &channel_users_modes,
4722 &channel_users_modes_c,
4726 &channel_ids, creation_time);
4728 /* Get channels and channel users in global list */
4729 if (server->server_type != SILC_SERVER)
4730 silc_server_announce_get_channels(server, server->global_list,
4731 &channels, &channel_modes,
4733 &channel_users_modes,
4734 &channel_users_modes_c,
4738 &channel_ids, creation_time);
4741 silc_buffer_push(channels, channels->data - channels->head);
4742 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4744 /* Send the packet */
4745 silc_server_packet_send(server, remote,
4746 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4747 channels->data, silc_buffer_len(channels));
4749 silc_buffer_free(channels);
4752 if (channel_users) {
4753 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4754 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4755 silc_buffer_len(channel_users));
4757 /* Send the packet */
4758 silc_server_packet_send(server, remote,
4759 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4760 channel_users->data, silc_buffer_len(channel_users));
4762 silc_buffer_free(channel_users);
4765 if (channel_modes) {
4768 for (i = 0; i < channel_users_modes_c; i++) {
4769 if (!channel_modes[i])
4771 silc_buffer_push(channel_modes[i],
4772 channel_modes[i]->data -
4773 channel_modes[i]->head);
4774 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4775 silc_buffer_len(channel_modes[i]));
4776 silc_server_packet_send_dest(server, remote,
4777 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4778 channel_ids[i], SILC_ID_CHANNEL,
4779 channel_modes[i]->data,
4780 silc_buffer_len(channel_modes[i]));
4781 silc_buffer_free(channel_modes[i]);
4783 silc_free(channel_modes);
4786 if (channel_users_modes) {
4789 for (i = 0; i < channel_users_modes_c; i++) {
4790 if (!channel_users_modes[i])
4792 silc_buffer_push(channel_users_modes[i],
4793 channel_users_modes[i]->data -
4794 channel_users_modes[i]->head);
4795 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4796 silc_buffer_len(channel_users_modes[i]));
4797 silc_server_packet_send_dest(server, remote,
4798 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4799 channel_ids[i], SILC_ID_CHANNEL,
4800 channel_users_modes[i]->data,
4801 silc_buffer_len(channel_users_modes[i]));
4802 silc_buffer_free(channel_users_modes[i]);
4804 silc_free(channel_users_modes);
4807 if (channel_topics) {
4810 for (i = 0; i < channel_users_modes_c; i++) {
4811 if (!channel_topics[i])
4814 silc_buffer_push(channel_topics[i],
4815 channel_topics[i]->data -
4816 channel_topics[i]->head);
4817 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4818 silc_buffer_len(channel_topics[i]));
4819 silc_server_packet_send_dest(server, remote,
4820 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4821 channel_ids[i], SILC_ID_CHANNEL,
4822 channel_topics[i]->data,
4823 silc_buffer_len(channel_topics[i]));
4824 silc_buffer_free(channel_topics[i]);
4826 silc_free(channel_topics);
4829 if (channel_invites) {
4832 for (i = 0; i < channel_users_modes_c; i++) {
4833 if (!channel_invites[i])
4836 silc_buffer_push(channel_invites[i],
4837 channel_invites[i]->data -
4838 channel_invites[i]->head);
4839 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4840 silc_buffer_len(channel_invites[i]));
4841 silc_server_packet_send_dest(server, remote,
4842 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4843 channel_ids[i], SILC_ID_CHANNEL,
4844 channel_invites[i]->data,
4845 silc_buffer_len(channel_invites[i]));
4846 silc_buffer_free(channel_invites[i]);
4848 silc_free(channel_invites);
4854 for (i = 0; i < channel_users_modes_c; i++) {
4855 if (!channel_bans[i])
4858 silc_buffer_push(channel_bans[i],
4859 channel_bans[i]->data -
4860 channel_bans[i]->head);
4861 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4862 silc_buffer_len(channel_bans[i]));
4863 silc_server_packet_send_dest(server, remote,
4864 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4865 channel_ids[i], SILC_ID_CHANNEL,
4866 channel_bans[i]->data,
4867 silc_buffer_len(channel_bans[i]));
4868 silc_buffer_free(channel_bans[i]);
4870 silc_free(channel_bans);
4873 silc_free(channel_ids);
4876 /* Announces WATCH list. */
4878 void silc_server_announce_watches(SilcServer server,
4879 SilcPacketStream remote)
4881 SilcHashTableList htl;
4882 SilcBuffer buffer, idp, args, pkp;
4883 SilcClientEntry client;
4886 SILC_LOG_DEBUG(("Announcing watch list"));
4888 /* XXX because way we save the nicks (hash) we cannot announce them. */
4890 /* XXX we should send all public keys in one command if client is
4891 watching more than one key */
4892 silc_hash_table_list(server->watcher_list_pk, &htl);
4893 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4894 if (!client || !client->id)
4897 server->stat.commands_sent++;
4899 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4900 args = silc_buffer_alloc_size(2);
4901 silc_buffer_format(args,
4902 SILC_STR_UI_SHORT(1),
4904 pkp = silc_public_key_payload_encode(key);
4905 args = silc_argument_payload_encode_one(args, pkp->data,
4906 silc_buffer_len(pkp), 0x00);
4907 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4908 ++server->cmd_ident, 2,
4909 1, idp->data, silc_buffer_len(idp),
4911 silc_buffer_len(args));
4914 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4915 buffer->data, silc_buffer_len(buffer));
4917 silc_buffer_free(pkp);
4918 silc_buffer_free(args);
4919 silc_buffer_free(idp);
4920 silc_buffer_free(buffer);
4922 silc_hash_table_list_reset(&htl);
4925 /* Assembles user list and users mode list from the `channel'. */
4927 SilcBool silc_server_get_users_on_channel(SilcServer server,
4928 SilcChannelEntry channel,
4929 SilcBuffer *user_list,
4930 SilcBuffer *mode_list,
4931 SilcUInt32 *user_count)
4933 SilcChannelClientEntry chl;
4934 SilcHashTableList htl;
4935 SilcBuffer client_id_list;
4936 SilcBuffer client_mode_list;
4938 SilcUInt32 list_count = 0, len = 0;
4940 if (!silc_hash_table_count(channel->user_list))
4943 silc_hash_table_list(channel->user_list, &htl);
4944 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4945 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4946 silc_hash_table_list_reset(&htl);
4948 client_id_list = silc_buffer_alloc(len);
4950 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4951 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4952 silc_buffer_pull_tail(client_mode_list,
4953 silc_buffer_truelen(client_mode_list));
4955 silc_hash_table_list(channel->user_list, &htl);
4956 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4958 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4959 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4960 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4961 silc_buffer_free(idp);
4963 /* Client's mode on channel */
4964 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4965 silc_buffer_pull(client_mode_list, 4);
4969 silc_hash_table_list_reset(&htl);
4970 silc_buffer_push(client_id_list,
4971 client_id_list->data - client_id_list->head);
4972 silc_buffer_push(client_mode_list,
4973 client_mode_list->data - client_mode_list->head);
4975 *user_list = client_id_list;
4976 *mode_list = client_mode_list;
4977 *user_count = list_count;
4981 /* Saves users and their modes to the `channel'. */
4983 void silc_server_save_users_on_channel(SilcServer server,
4984 SilcPacketStream sock,
4985 SilcChannelEntry channel,
4986 SilcClientID *noadd,
4987 SilcBuffer user_list,
4988 SilcBuffer mode_list,
4989 SilcUInt32 user_count)
4995 SilcClientEntry client;
4996 SilcIDCacheEntry cache;
4997 SilcChannelClientEntry chl;
4999 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5000 channel->channel_name));
5002 for (i = 0; i < user_count; i++) {
5004 SILC_GET16_MSB(idp_len, user_list->data + 2);
5006 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5008 silc_buffer_pull(user_list, idp_len);
5011 SILC_GET32_MSB(mode, mode_list->data);
5012 silc_buffer_pull(mode_list, 4);
5014 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5019 /* Check if we have this client cached already. */
5020 client = silc_idlist_find_client_by_id(server->local_list,
5022 server->server_type, &cache);
5024 client = silc_idlist_find_client_by_id(server->global_list,
5026 server->server_type, &cache);
5028 /* If router did not find such Client ID in its lists then this must
5029 be bogus client or some router in the net is buggy. */
5030 if (server->server_type != SILC_SERVER)
5033 /* We don't have that client anywhere, add it. The client is added
5034 to global list since server didn't have it in the lists so it must be
5036 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5037 silc_id_dup(&id.u.client_id,
5039 silc_packet_get_context(sock),
5042 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5046 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5049 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5050 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5051 "%s", channel->channel_name));
5055 if (!silc_server_client_on_channel(client, channel, &chl)) {
5056 /* Client was not on the channel, add it. */
5057 chl = silc_calloc(1, sizeof(*chl));
5058 chl->client = client;
5060 chl->channel = channel;
5061 silc_hash_table_add(channel->user_list, chl->client, chl);
5062 silc_hash_table_add(client->channels, chl->channel, chl);
5063 channel->user_count++;
5071 /* Saves channels and channels user modes to the `client'. Removes
5072 the client from those channels that are not sent in the list but
5075 void silc_server_save_user_channels(SilcServer server,
5076 SilcPacketStream sock,
5077 SilcClientEntry client,
5078 SilcBuffer channels,
5079 SilcBuffer channels_user_modes)
5082 SilcUInt32 *chumodes;
5083 SilcChannelPayload entry;
5084 SilcChannelEntry channel;
5085 SilcChannelID channel_id;
5086 SilcChannelClientEntry chl;
5087 SilcHashTable ht = NULL;
5088 SilcHashTableList htl;
5092 if (!channels || !channels_user_modes ||
5093 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5096 ch = silc_channel_payload_parse_list(channels->data,
5097 silc_buffer_len(channels));
5098 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5100 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5101 NULL, NULL, NULL, TRUE);
5102 silc_dlist_start(ch);
5103 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5104 /* Check if we have this channel, and add it if we don't have it.
5105 Also add the client on the channel unless it is there already. */
5106 if (!silc_channel_get_id_parse(entry, &channel_id))
5108 channel = silc_idlist_find_channel_by_id(server->local_list,
5111 channel = silc_idlist_find_channel_by_id(server->global_list,
5114 if (server->server_type != SILC_SERVER) {
5119 /* We don't have that channel anywhere, add it. */
5120 name = silc_channel_get_name(entry, NULL);
5121 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5122 silc_id_dup(&channel_id,
5124 server->router, NULL, NULL, 0);
5131 channel->mode = silc_channel_get_mode(entry);
5133 /* Add the client on the channel */
5134 if (!silc_server_client_on_channel(client, channel, &chl)) {
5135 chl = silc_calloc(1, sizeof(*chl));
5136 chl->client = client;
5137 chl->mode = chumodes[i++];
5138 chl->channel = channel;
5139 silc_hash_table_add(channel->user_list, chl->client, chl);
5140 silc_hash_table_add(client->channels, chl->channel, chl);
5141 channel->user_count++;
5144 chl->mode = chumodes[i++];
5147 silc_hash_table_add(ht, channel, channel);
5149 silc_channel_payload_list_free(ch);
5150 silc_free(chumodes);
5154 /* Go through the list again and remove client from channels that
5155 are no part of the list. */
5157 silc_hash_table_list(client->channels, &htl);
5158 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5159 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5160 silc_hash_table_del(chl->channel->user_list, chl->client);
5161 silc_hash_table_del(chl->client->channels, chl->channel);
5165 silc_hash_table_list_reset(&htl);
5166 silc_hash_table_free(ht);
5168 silc_hash_table_list(client->channels, &htl);
5169 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5170 silc_hash_table_del(chl->channel->user_list, chl->client);
5171 silc_hash_table_del(chl->client->channels, chl->channel);
5174 silc_hash_table_list_reset(&htl);
5178 /* Lookups route to the client indicated by the `id_data'. The connection
5179 object and internal data object is returned. Returns NULL if route
5180 could not be found to the client. If the `client_id' is specified then
5181 it is used and the `id_data' is ignored. */
5184 silc_server_get_client_route(SilcServer server,
5185 unsigned char *id_data,
5187 SilcClientID *client_id,
5188 SilcIDListData *idata,
5189 SilcClientEntry *client_entry)
5191 SilcClientID *id, clid;
5192 SilcClientEntry client;
5194 SILC_LOG_DEBUG(("Start"));
5197 *client_entry = NULL;
5199 /* Decode destination Client ID */
5201 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5203 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5205 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5208 /* If the destination belongs to our server we don't have to route
5209 the packet anywhere but to send it to the local destination. */
5210 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5214 /* If we are router and the client has router then the client is in
5215 our cell but not directly connected to us. */
5216 if (server->server_type == SILC_ROUTER && client->router) {
5217 /* We are of course in this case the client's router thus the route
5218 to the client is the server who owns the client. So, we will send
5219 the packet to that server. */
5221 *idata = (SilcIDListData)client->router;
5222 return client->router->connection;
5225 /* Seems that client really is directly connected to us */
5227 *idata = (SilcIDListData)client;
5229 *client_entry = client;
5230 return client->connection;
5233 /* Destination belongs to someone not in this server. If we are normal
5234 server our action is to send the packet to our router. */
5235 if (server->server_type != SILC_ROUTER && !server->standalone) {
5238 *idata = (SilcIDListData)server->router;
5239 return SILC_PRIMARY_ROUTE(server);
5242 /* We are router and we will perform route lookup for the destination
5243 and send the packet to fastest route. */
5244 if (server->server_type == SILC_ROUTER && !server->standalone) {
5245 /* Check first that the ID is valid */
5246 client = silc_idlist_find_client_by_id(server->global_list, id,
5249 SilcPacketStream dst_sock;
5251 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5254 if (idata && dst_sock)
5255 *idata = silc_packet_get_context(dst_sock);
5264 /* Encodes and returns channel list of channels the `client' has joined.
5265 Secret channels are not put to the list. */
5267 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5268 SilcClientEntry client,
5269 SilcBool get_private,
5270 SilcBool get_secret,
5271 SilcBuffer *user_mode_list)
5273 SilcBuffer buffer = NULL;
5274 SilcChannelEntry channel;
5275 SilcChannelClientEntry chl;
5276 SilcHashTableList htl;
5277 unsigned char cid[32];
5279 SilcUInt16 name_len;
5283 *user_mode_list = NULL;
5285 silc_hash_table_list(client->channels, &htl);
5286 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5287 channel = chl->channel;
5289 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5291 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5294 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5295 name_len = strlen(channel->channel_name);
5297 len = 4 + name_len + id_len + 4;
5298 buffer = silc_buffer_realloc(buffer,
5300 silc_buffer_truelen(buffer) + len : len));
5301 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5302 silc_buffer_format(buffer,
5303 SILC_STR_UI_SHORT(name_len),
5304 SILC_STR_DATA(channel->channel_name, name_len),
5305 SILC_STR_UI_SHORT(id_len),
5306 SILC_STR_DATA(cid, id_len),
5307 SILC_STR_UI_INT(chl->channel->mode),
5309 silc_buffer_pull(buffer, len);
5311 if (user_mode_list) {
5313 silc_buffer_realloc(*user_mode_list,
5315 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5316 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5317 (*user_mode_list)->data));
5318 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5319 silc_buffer_pull(*user_mode_list, 4);
5322 silc_hash_table_list_reset(&htl);
5325 silc_buffer_push(buffer, buffer->data - buffer->head);
5326 if (user_mode_list && *user_mode_list)
5327 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5328 (*user_mode_list)->head));
5333 /* Task callback used to retrieve network statistical information from
5334 router server once in a while. */
5336 SILC_TASK_CALLBACK(silc_server_get_stats)
5338 SilcServer server = (SilcServer)context;
5339 SilcBuffer idp, packet;
5341 if (!server->standalone) {
5342 SILC_LOG_DEBUG(("Retrieving stats from router"));
5343 server->stat.commands_sent++;
5344 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5346 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5347 ++server->cmd_ident, 1,
5349 silc_buffer_len(idp));
5350 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5351 SILC_PACKET_COMMAND, 0, packet->data,
5352 silc_buffer_len(packet));
5353 silc_buffer_free(packet);
5354 silc_buffer_free(idp);
5358 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,