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"
24 /************************* Types and definitions ****************************/
26 SILC_TASK_CALLBACK(silc_server_get_stats);
27 SILC_TASK_CALLBACK(silc_server_connect_router);
28 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
29 SILC_TASK_CALLBACK(silc_server_do_rekey);
30 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
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 if (server->router_conn && server->router_conn->sock == stream &&
204 !server->router && server->standalone) {
205 if (idata->sconn && idata->sconn->callback)
206 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
207 silc_server_create_connections(server);
208 silc_server_free_sock_user_data(server, stream, NULL);
210 /* If backup disconnected then mark that resuming will not be allowed */
211 if (server->server_type == SILC_ROUTER && !server->backup_router &&
212 idata->conn_type == SILC_CONN_SERVER) {
213 SilcServerEntry server_entry = (SilcServerEntry)idata;
214 if (server_entry->server_type == SILC_BACKUP_ROUTER)
215 server->backup_closed = TRUE;
218 if (idata->sconn && idata->sconn->callback)
219 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
220 silc_server_free_sock_user_data(server, stream, NULL);
223 silc_server_close_connection(server, stream);
226 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
228 SilcServer server = app_context;
229 SilcPacketStream stream = context;
230 SilcIDListData idata = silc_packet_get_context(stream);
235 if (server->router_conn && server->router_conn->sock == stream &&
236 !server->router && server->standalone) {
237 silc_server_create_connections(server);
239 /* If backup disconnected then mark that resuming will not be allowed */
240 if (server->server_type == SILC_ROUTER && !server->backup_router &&
241 idata->conn_type == SILC_CONN_SERVER) {
242 SilcServerEntry server_entry = (SilcServerEntry)idata;
243 if (server_entry->server_type == SILC_BACKUP_ROUTER)
244 server->backup_closed = TRUE;
247 if (idata->sconn && idata->sconn->callback)
248 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
249 silc_server_free_sock_user_data(server, stream, NULL);
252 silc_server_close_connection(server, stream);
255 /* Packet engine callback to indicate error */
257 static void silc_server_packet_error(SilcPacketEngine engine,
258 SilcPacketStream stream,
259 SilcPacketError error,
260 void *callback_context,
261 void *stream_context)
263 SilcServer server = callback_context;
264 SilcIDListData idata = silc_packet_get_context(stream);
265 SilcStream sock = silc_packet_stream_get_stream(stream);
269 SILC_LOG_DEBUG(("Packet error, sock %p", stream));
274 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
277 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
278 SILC_CONNTYPE_STRING(idata->conn_type),
279 silc_packet_error_string(error)));
281 if (!silc_packet_stream_is_valid(stream))
284 silc_schedule_task_add_timeout(server->schedule,
285 silc_server_packet_error_timeout,
289 /* Packet stream callbacks */
290 static SilcPacketCallbacks silc_server_stream_cbs =
292 silc_server_packet_receive,
293 silc_server_packet_eos,
294 silc_server_packet_error
297 /* Parses the packet type and calls what ever routines the packet type
298 requires. This is done for all incoming packets. */
300 static void silc_server_packet_parse_type(SilcServer server,
301 SilcPacketStream sock,
304 SilcPacketType type = packet->type;
305 SilcIDListData idata = silc_packet_get_context(sock);
307 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
308 silc_get_packet_name(type), packet->flags));
310 /* Parse the packet type */
312 case SILC_PACKET_NOTIFY:
314 * Received notify packet. Server can receive notify packets from
315 * router. Server then relays the notify messages to clients if needed.
317 if (packet->flags & SILC_PACKET_FLAG_LIST)
318 silc_server_notify_list(server, sock, packet);
320 silc_server_notify(server, sock, packet);
324 * Private Message packets
326 case SILC_PACKET_PRIVATE_MESSAGE:
328 * Received private message packet. The packet is coming from either
331 if (packet->flags & SILC_PACKET_FLAG_LIST)
333 idata->last_receive = time(NULL);
334 silc_server_private_message(server, sock, packet);
340 case SILC_PACKET_CHANNEL_MESSAGE:
342 * Received channel message. Channel messages are special packets
343 * (although probably most common ones) thus they are handled
346 if (packet->flags & SILC_PACKET_FLAG_LIST)
348 idata->last_receive = time(NULL);
349 silc_server_channel_message(server, sock, packet);
355 case SILC_PACKET_COMMAND:
357 * Recived command. Processes the command request and allocates the
358 * command context and calls the command.
360 if (packet->flags & SILC_PACKET_FLAG_LIST)
362 server->stat.commands_received++;
363 silc_server_command_process(server, sock, packet);
366 case SILC_PACKET_COMMAND_REPLY:
368 * Received command reply packet. Received command reply to command. It
369 * may be reply to command sent by us or reply to command sent by client
370 * that we've routed further.
372 if (packet->flags & SILC_PACKET_FLAG_LIST)
374 server->stat.commands_received++;
375 silc_server_command_reply(server, sock, packet);
378 case SILC_PACKET_DISCONNECT:
381 char *message = NULL;
382 const char *hostname, *ip;
384 if (packet->flags & SILC_PACKET_FLAG_LIST)
386 if (silc_buffer_len(&packet->buffer) < 1)
389 status = (SilcStatus)packet->buffer.data[0];
390 if (silc_buffer_len(&packet->buffer) > 1 &&
391 silc_utf8_valid(packet->buffer.data + 1,
392 silc_buffer_len(&packet->buffer) - 1))
393 message = silc_memdup(packet->buffer.data + 1,
394 silc_buffer_len(&packet->buffer) - 1);
396 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
397 NULL, &hostname, &ip, NULL))
400 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
401 silc_get_status_message(status), status,
402 message ? message : ""));
406 /* Do not switch to backup in case of error */
407 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
409 /* If backup disconnected then mark that resuming will not be allowed */
410 if (server->server_type == SILC_ROUTER && !server->backup_router &&
411 idata->conn_type == SILC_CONN_SERVER) {
412 SilcServerEntry server_entry = (SilcServerEntry)idata;
413 if (server_entry->server_type == SILC_BACKUP_ROUTER)
414 server->backup_closed = TRUE;
417 /* Handle the disconnection from our end too */
418 if (SILC_IS_LOCAL(idata))
419 silc_server_free_sock_user_data(server, sock, NULL);
420 silc_server_close_connection(server, sock);
421 server->backup_noswitch = FALSE;
425 case SILC_PACKET_CHANNEL_KEY:
427 * Received key for channel. As channels are created by the router
428 * the keys are as well. We will distribute the key to all of our
429 * locally connected clients on the particular channel. Router
430 * never receives this channel and thus is ignored.
432 if (packet->flags & SILC_PACKET_FLAG_LIST)
434 silc_server_channel_key(server, sock, packet);
437 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
439 * Private message key packet.
441 if (packet->flags & SILC_PACKET_FLAG_LIST)
443 silc_server_private_message_key(server, sock, packet);
446 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
448 * Connection authentication request packet. When we receive this packet
449 * we will send to the other end information about our mandatory
450 * authentication method for the connection. This packet maybe received
453 if (packet->flags & SILC_PACKET_FLAG_LIST)
455 silc_server_connection_auth_request(server, sock, packet);
458 case SILC_PACKET_NEW_ID:
460 * Received New ID packet. This includes some new ID that has been
461 * created. It may be for client, server or channel. This is the way
462 * to distribute information about new registered entities in the
465 if (packet->flags & SILC_PACKET_FLAG_LIST)
466 silc_server_new_id_list(server, sock, packet);
468 silc_server_new_id(server, sock, packet);
471 case SILC_PACKET_NEW_CLIENT:
473 * Received new client packet. This includes client information that
474 * we will use to create initial client ID. After creating new
475 * ID we will send it to the client.
477 if (packet->flags & SILC_PACKET_FLAG_LIST)
479 silc_server_new_client(server, sock, packet);
482 case SILC_PACKET_NEW_SERVER:
484 * Received new server packet. This includes Server ID and some other
485 * information that we may save. This is received after server has
488 if (packet->flags & SILC_PACKET_FLAG_LIST)
490 silc_server_new_server(server, sock, packet);
493 case SILC_PACKET_NEW_CHANNEL:
495 * Received new channel packet. Information about new channel in the
496 * network are distributed using this packet.
498 if (packet->flags & SILC_PACKET_FLAG_LIST)
499 silc_server_new_channel_list(server, sock, packet);
501 silc_server_new_channel(server, sock, packet);
504 case SILC_PACKET_HEARTBEAT:
506 * Received heartbeat.
508 if (packet->flags & SILC_PACKET_FLAG_LIST)
512 case SILC_PACKET_KEY_AGREEMENT:
514 * Received heartbeat.
516 if (packet->flags & SILC_PACKET_FLAG_LIST)
518 silc_server_key_agreement(server, sock, packet);
521 case SILC_PACKET_REKEY:
523 * Received re-key packet. The sender wants to regenerate the session
526 if (packet->flags & SILC_PACKET_FLAG_LIST)
528 silc_server_rekey(server, sock, packet);
531 case SILC_PACKET_FTP:
533 if (packet->flags & SILC_PACKET_FLAG_LIST)
535 silc_server_ftp(server, sock, packet);
538 case SILC_PACKET_RESUME_CLIENT:
540 if (packet->flags & SILC_PACKET_FLAG_LIST)
542 silc_server_resume_client(server, sock, packet);
545 case SILC_PACKET_RESUME_ROUTER:
546 /* Resume router packet received. This packet is received for backup
547 router resuming protocol. */
548 if (packet->flags & SILC_PACKET_FLAG_LIST)
550 silc_server_backup_resume_router(server, sock, packet);
554 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
559 /****************************** Server API **********************************/
561 /* Allocates a new SILC server object. This has to be done before the server
562 can be used. After allocation one must call silc_server_init to initialize
563 the server. The new allocated server object is returned to the new_server
566 SilcBool silc_server_alloc(SilcServer *new_server)
570 SILC_LOG_DEBUG(("Allocating new server object"));
572 server = silc_calloc(1, sizeof(*server));
575 server->server_type = SILC_SERVER;
576 server->standalone = TRUE;
577 server->local_list = silc_calloc(1, sizeof(*server->local_list));
578 if (!server->local_list)
580 server->global_list = silc_calloc(1, sizeof(*server->global_list));
581 if (!server->global_list)
583 server->pending_commands = silc_dlist_init();
584 if (!server->pending_commands)
586 server->listeners = silc_dlist_init();
587 if (!server->listeners)
589 server->repository = silc_skr_alloc();
590 if (!server->repository)
592 server->conns = silc_dlist_init();
595 server->expired_clients = silc_dlist_init();
596 if (!server->expired_clients)
599 *new_server = server;
604 /* Free's the SILC server object. This is called at the very end before
607 void silc_server_free(SilcServer server)
610 SilcIDCacheEntry cache;
611 SilcIDListData idata;
613 SILC_LOG_DEBUG(("Free server %p", server));
618 silc_server_backup_free(server);
619 silc_server_config_unref(&server->config_ref);
621 silc_rng_free(server->rng);
622 if (server->public_key)
623 silc_pkcs_public_key_free(server->public_key);
624 if (server->private_key)
625 silc_pkcs_private_key_free(server->private_key);
626 if (server->pending_commands)
627 silc_dlist_uninit(server->pending_commands);
628 if (server->id_entry) {
629 if (server->id_entry->data.sconn)
630 silc_schedule_task_del_by_context(server->schedule,
631 server->id_entry->data.sconn->sock);
632 silc_idlist_del_server(server->local_list, server->id_entry);
635 /* Delete all channels */
636 if (silc_idcache_get_all(server->local_list->channels, &list)) {
637 silc_list_start(list);
638 while ((cache = silc_list_get(list)))
639 silc_idlist_del_channel(server->local_list, cache->context);
641 if (silc_idcache_get_all(server->global_list->channels, &list)) {
642 silc_list_start(list);
643 while ((cache = silc_list_get(list)))
644 silc_idlist_del_channel(server->global_list, cache->context);
647 /* Delete all clients */
648 if (silc_idcache_get_all(server->local_list->clients, &list)) {
649 silc_list_start(list);
650 while ((cache = silc_list_get(list))) {
651 silc_schedule_task_del_by_context(server->schedule, cache->context);
652 silc_idlist_del_client(server->local_list, cache->context);
655 if (silc_idcache_get_all(server->global_list->clients, &list)) {
656 silc_list_start(list);
657 while ((cache = silc_list_get(list))) {
658 silc_schedule_task_del_by_context(server->schedule, cache->context);
659 silc_idlist_del_client(server->global_list, cache->context);
663 /* Delete all servers */
664 if (silc_idcache_get_all(server->local_list->servers, &list)) {
665 silc_list_start(list);
666 while ((cache = silc_list_get(list))) {
667 idata = (SilcIDListData)cache->context;
669 silc_schedule_task_del_by_context(server->schedule,
671 silc_idlist_del_server(server->local_list, cache->context);
674 if (silc_idcache_get_all(server->global_list->servers, &list)) {
675 while ((cache = silc_list_get(list))) {
676 idata = (SilcIDListData)cache->context;
678 silc_schedule_task_del_by_context(server->schedule,
680 silc_idlist_del_server(server->global_list, cache->context);
684 silc_schedule_task_del_by_context(server->schedule, server);
685 silc_schedule_uninit(server->schedule);
686 server->schedule = NULL;
688 silc_idcache_free(server->local_list->clients);
689 silc_idcache_free(server->local_list->servers);
690 silc_idcache_free(server->local_list->channels);
691 silc_idcache_free(server->global_list->clients);
692 silc_idcache_free(server->global_list->servers);
693 silc_idcache_free(server->global_list->channels);
694 silc_hash_table_free(server->watcher_list);
695 silc_hash_table_free(server->watcher_list_pk);
696 silc_hash_free(server->md5hash);
697 silc_hash_free(server->sha1hash);
699 silc_dlist_uninit(server->listeners);
700 silc_dlist_uninit(server->conns);
701 silc_dlist_uninit(server->expired_clients);
702 silc_skr_free(server->repository);
703 silc_packet_engine_stop(server->packet_engine);
705 silc_free(server->local_list);
706 silc_free(server->global_list);
707 silc_free(server->server_name);
708 silc_free(server->id);
711 silc_hmac_unregister_all();
712 silc_hash_unregister_all();
713 silc_cipher_unregister_all();
714 silc_pkcs_unregister_all();
717 /* Creates a new server listener. */
719 static SilcNetListener
720 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
722 SilcNetListener listener;
725 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
726 server->config->require_reverse_lookup,
728 silc_server_accept_new_connection, server);
730 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
738 /* Adds a secondary listener. */
740 SilcBool silc_server_init_secondary(SilcServer server)
742 SilcServerConfigServerInfoInterface *interface;
743 SilcNetListener listener;
745 for (interface = server->config->server_info->secondary; interface;
746 interface = interface->next) {
747 listener = silc_server_listen(server, interface->server_ip,
751 silc_dlist_add(server->listeners, listener);
757 /* Initializes the entire SILC server. This is called always before running
758 the server. This is called only once at the initialization of the program.
759 This binds the server to its listenning port. After this function returns
760 one should call silc_server_run to start the server. This returns TRUE
761 when everything is ok to run the server. Configuration file must be
762 read and parsed before calling this. */
764 SilcBool silc_server_init(SilcServer server)
767 SilcServerEntry id_entry;
768 SilcNetListener listener;
773 SILC_LOG_DEBUG(("Initializing server"));
775 server->starttime = time(NULL);
777 /* Take config object for us */
778 silc_server_config_ref(&server->config_ref, server->config,
782 /* Set debugging on if configured */
783 if (server->config->debug_string) {
784 silc_log_debug(TRUE);
785 silc_log_set_debug_string(server->config->debug_string);
787 #endif /* SILC_DEBUG */
789 /* Steal public and private key from the config object */
790 server->public_key = server->config->server_info->public_key;
791 server->private_key = server->config->server_info->private_key;
792 server->config->server_info->public_key = NULL;
793 server->config->server_info->private_key = NULL;
795 /* Register all configured ciphers, PKCS and hash functions. */
796 if (!silc_server_config_register_ciphers(server))
797 silc_cipher_register_default();
798 if (!silc_server_config_register_pkcs(server))
799 silc_pkcs_register_default();
800 if (!silc_server_config_register_hashfuncs(server))
801 silc_hash_register_default();
802 if (!silc_server_config_register_hmacs(server))
803 silc_hmac_register_default();
805 /* Initialize random number generator for the server. */
806 server->rng = silc_rng_alloc();
807 silc_rng_init(server->rng);
808 silc_rng_global_init(server->rng);
810 /* Initialize hash functions for server to use */
811 silc_hash_alloc("md5", &server->md5hash);
812 silc_hash_alloc("sha1", &server->sha1hash);
814 /* Initialize the scheduler */
815 server->schedule = silc_schedule_init(server->config->param.connections_max,
817 if (!server->schedule)
820 /* First, register log files configuration for error output */
821 silc_server_config_setlogfiles(server);
823 /* Initialize ID caches */
824 server->local_list->clients =
825 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
827 server->local_list->servers =
828 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
830 server->local_list->channels =
831 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
834 /* These are allocated for normal server as well as these hold some
835 global information that the server has fetched from its router. For
836 router these are used as they are supposed to be used on router. */
837 server->global_list->clients =
838 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
840 server->global_list->servers =
841 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
843 server->global_list->channels =
844 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
847 /* Init watcher lists */
848 server->watcher_list =
849 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
850 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
852 if (!server->watcher_list)
854 server->watcher_list_pk =
855 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
856 silc_hash_public_key_compare, NULL,
858 if (!server->watcher_list_pk)
861 /* Create TCP listener */
862 listener = silc_server_listen(
864 server->config->server_info->primary == NULL ? NULL :
865 server->config->server_info->primary->server_ip,
866 server->config->server_info->primary == NULL ? 0 :
867 server->config->server_info->primary->port);
870 silc_dlist_add(server->listeners, listener);
872 /* Create a Server ID for the server. */
873 port = silc_net_listener_get_port(listener, NULL);
874 ip = silc_net_listener_get_ip(listener, NULL);
875 external_ip = server->config->server_info->external_ip ?
876 server->config->server_info->external_ip :
877 server->config->server_info->primary->public_ip;
878 silc_id_create_server_id(external_ip ?
880 ip[0], port[0], server->rng, &id);
889 server->server_name = server->config->server_info->server_name;
890 server->config->server_info->server_name = NULL;
891 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
892 sizeof(server->id_string), &server->id_string_len);
894 /* Add ourselves to the server list. We don't have a router yet
895 beacuse we haven't established a route yet. It will be done later.
896 For now, NULL is sent as router. This allocates new entry to
899 silc_idlist_add_server(server->local_list, strdup(server->server_name),
901 silc_id_dup(server->id, SILC_ID_SERVER),
904 SILC_LOG_ERROR(("Could not add local server to cache"));
907 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
908 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
909 SILC_CONN_SERVER : SILC_CONN_ROUTER);
910 server->id_entry = id_entry;
912 /* Create secondary TCP listeners */
913 if (silc_server_init_secondary(server) == FALSE)
916 server->listenning = TRUE;
918 /* Create connections to configured routers. */
919 silc_server_create_connections(server);
921 /* If server connections has been configured then we must be router as
922 normal server cannot have server connections, only router connections. */
923 if (server->config->servers) {
924 SilcServerConfigServer *ptr = server->config->servers;
926 server->server_type = SILC_ROUTER;
928 if (ptr->backup_router) {
929 server->server_type = SILC_BACKUP_ROUTER;
930 server->backup_router = TRUE;
931 server->id_entry->server_type = SILC_BACKUP_ROUTER;
938 if (server->server_type != SILC_ROUTER) {
939 server->stat.servers = 1;
940 server->stat.cell_servers = 1;
942 server->stat.routers = 1;
945 /* If we are normal server we'll retrieve network statisticial information
946 once in a while from the router. */
947 if (server->server_type != SILC_ROUTER)
948 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
951 /* Start packet engine */
952 server->packet_engine =
953 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
954 &silc_server_stream_cbs, server);
955 if (!server->packet_engine)
958 /* Register client entry expiration timeout */
959 silc_schedule_task_add_timeout(server->schedule,
960 silc_server_purge_expired_clients, server,
963 /* Initialize HTTP server */
964 silc_server_http_init(server);
966 SILC_LOG_DEBUG(("Server initialized"));
968 /* We are done here, return succesfully */
972 silc_server_config_unref(&server->config_ref);
976 /* Task callback to close a socket connection after rehash */
978 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
980 SilcServer server = app_context;
981 SilcPacketStream sock = context;
982 SilcIDListData idata = silc_packet_get_context(sock);
983 const char *hostname;
986 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
987 NULL, &hostname, NULL, &port);
989 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
990 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
991 silc_schedule_task_del_by_context(server->schedule, sock);
992 silc_server_disconnect_remote(server, sock,
993 SILC_STATUS_ERR_BANNED_FROM_SERVER,
994 "This connection is removed from "
996 silc_server_free_sock_user_data(server, sock, NULL);
999 /* This function basically reads the config file again and switches the config
1000 object pointed by the server object. After that, we have to fix various
1001 things such as the server_name and the listening ports.
1002 Keep in mind that we no longer have the root privileges at this point. */
1004 SilcBool silc_server_rehash(SilcServer server)
1006 SilcServerConfig newconfig;
1008 SILC_LOG_INFO(("Rehashing server"));
1010 /* Reset the logging system */
1011 silc_log_quick(TRUE);
1012 silc_log_flush_all();
1014 /* Start the main rehash phase (read again the config file) */
1015 newconfig = silc_server_config_alloc(server->config_file, server);
1017 SILC_LOG_ERROR(("Rehash FAILED."));
1021 /* Fix the server_name field */
1022 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1023 silc_free(server->server_name);
1025 /* Check server name */
1026 server->server_name =
1027 silc_identifier_check(newconfig->server_info->server_name,
1028 strlen(newconfig->server_info->server_name),
1029 SILC_STRING_LOCALE, 256, NULL);
1030 if (!server->server_name) {
1031 SILC_LOG_ERROR(("Malformed server name string '%s'",
1032 server->config->server_info->server_name));
1036 /* Update the idcache list with a fresh pointer */
1037 silc_free(server->id_entry->server_name);
1038 server->id_entry->server_name = strdup(server->server_name);
1039 silc_idcache_update_by_context(server->local_list->servers,
1040 server->id_entry, NULL,
1041 strdup(server->id_entry->server_name),
1046 silc_server_config_setlogfiles(server);
1048 /* Change new key pair if necessary */
1049 if (newconfig->server_info->public_key &&
1050 !silc_pkcs_public_key_compare(server->public_key,
1051 newconfig->server_info->public_key)) {
1052 silc_pkcs_public_key_free(server->public_key);
1053 silc_pkcs_private_key_free(server->private_key);
1054 server->public_key = newconfig->server_info->public_key;
1055 server->private_key = newconfig->server_info->private_key;
1056 newconfig->server_info->public_key = NULL;
1057 newconfig->server_info->private_key = NULL;
1060 /* Check for unconfigured server and router connections and close
1061 connections that were unconfigured. */
1063 if (server->config->routers) {
1064 SilcServerConfigRouter *ptr;
1065 SilcServerConfigRouter *newptr;
1068 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1071 /* Check whether new config has this one too */
1072 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1073 if (silc_string_compare(newptr->host, ptr->host) &&
1074 newptr->port == ptr->port &&
1075 newptr->initiator == ptr->initiator) {
1081 if (!found && ptr->host) {
1082 /* Remove this connection */
1083 SilcPacketStream sock;
1084 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1085 ptr->host, ptr->port);
1087 silc_schedule_task_add_timeout(server->schedule,
1088 silc_server_rehash_close_connection,
1094 if (server->config->servers) {
1095 SilcServerConfigServer *ptr;
1096 SilcServerConfigServer *newptr;
1099 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1102 /* Check whether new config has this one too */
1103 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1104 if (silc_string_compare(newptr->host, ptr->host)) {
1110 if (!found && ptr->host) {
1111 /* Remove this connection */
1112 SilcPacketStream sock;
1113 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1116 silc_schedule_task_add_timeout(server->schedule,
1117 silc_server_rehash_close_connection,
1123 if (server->config->clients) {
1124 SilcServerConfigClient *ptr;
1125 SilcServerConfigClient *newptr;
1128 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1131 /* Check whether new config has this one too */
1132 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1133 if (silc_string_compare(newptr->host, ptr->host)) {
1139 if (!found && ptr->host) {
1140 /* Remove this connection */
1141 SilcPacketStream sock;
1142 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1145 silc_schedule_task_add_timeout(server->schedule,
1146 silc_server_rehash_close_connection,
1152 /* Create connections after rehash */
1153 silc_server_create_connections(server);
1155 /* Check whether our router status has changed */
1156 if (newconfig->servers) {
1157 SilcServerConfigServer *ptr = newconfig->servers;
1159 server->server_type = SILC_ROUTER;
1161 if (ptr->backup_router) {
1162 server->server_type = SILC_BACKUP_ROUTER;
1163 server->backup_router = TRUE;
1164 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1171 /* Our old config is gone now. We'll unreference our reference made in
1172 silc_server_init and then destroy it since we are destroying it
1173 underneath the application (layer which called silc_server_init). */
1174 silc_server_config_unref(&server->config_ref);
1175 silc_server_config_destroy(server->config);
1177 /* Take new config context */
1178 server->config = newconfig;
1179 silc_server_config_ref(&server->config_ref, server->config, server->config);
1182 /* Set debugging on if configured */
1183 if (server->config->debug_string) {
1184 silc_log_debug(TRUE);
1185 silc_log_set_debug_string(server->config->debug_string);
1187 #endif /* SILC_DEBUG */
1189 SILC_LOG_DEBUG(("Server rehashed"));
1194 /* The heart of the server. This runs the scheduler thus runs the server.
1195 When this returns the server has been stopped and the program will
1198 void silc_server_run(SilcServer server)
1200 SILC_LOG_INFO(("SILC Server started"));
1202 /* Start the scheduler, the heart of the SILC server. When this returns
1203 the program will be terminated. */
1204 silc_schedule(server->schedule);
1207 /* Stops the SILC server. This function is used to shutdown the server.
1208 This is usually called after the scheduler has returned. After stopping
1209 the server one should call silc_server_free. */
1211 void silc_server_stop(SilcServer server)
1214 SilcPacketStream ps;
1215 SilcNetListener listener;
1217 SILC_LOG_INFO(("SILC Server shutting down"));
1219 server->server_shutdown = TRUE;
1221 /* Close all connections */
1222 if (server->packet_engine) {
1223 list = silc_packet_engine_get_streams(server->packet_engine);
1225 silc_dlist_start(list);
1226 while ((ps = silc_dlist_get(list))) {
1227 SilcIDListData idata = silc_packet_get_context(ps);
1229 if (!silc_packet_stream_is_valid(ps))
1233 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1235 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1236 "Server is shutting down");
1237 silc_server_free_sock_user_data(server, ps,
1238 "Server is shutting down");
1240 silc_packet_engine_free_streams_list(list);
1243 /* We are not connected to network anymore */
1244 server->standalone = TRUE;
1246 silc_dlist_start(server->listeners);
1247 while ((listener = silc_dlist_get(server->listeners)))
1248 silc_net_close_listener(listener);
1250 silc_server_http_uninit(server);
1252 /* Cancel any possible retry timeouts */
1253 silc_schedule_task_del_by_callback(server->schedule,
1254 silc_server_connect_router);
1255 silc_schedule_task_del_by_callback(server->schedule,
1256 silc_server_connect_to_router_retry);
1257 silc_schedule_task_del_by_callback(server->schedule,
1258 silc_server_connect_to_router);
1260 silc_schedule_stop(server->schedule);
1262 SILC_LOG_DEBUG(("Server stopped"));
1265 /* Purge expired client entries from the server */
1267 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1269 SilcServer server = context;
1270 SilcClientEntry client;
1272 SilcUInt64 curtime = silc_time();
1274 SILC_LOG_DEBUG(("Expire timeout"));
1276 silc_dlist_start(server->expired_clients);
1277 while ((client = silc_dlist_get(server->expired_clients))) {
1278 /* For unregistered clients the created timestamp is actually
1279 unregistered timestamp. Make sure client remains in history
1280 at least 500 seconds. */
1281 if (client->data.created && curtime - client->data.created < 500)
1284 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1285 server->local_list : server->global_list);
1287 silc_idlist_del_data(client);
1288 silc_idlist_del_client(id_list, client);
1289 silc_dlist_del(server->expired_clients, client);
1292 silc_schedule_task_add_timeout(server->schedule,
1293 silc_server_purge_expired_clients, server,
1298 /******************************* Connecting *********************************/
1300 /* Free connection context */
1302 void silc_server_connection_free(SilcServerConnection sconn)
1306 SILC_LOG_DEBUG(("Free connection %p", sconn));
1307 silc_dlist_del(sconn->server->conns, sconn);
1308 silc_server_config_unref(&sconn->conn);
1309 silc_free(sconn->remote_host);
1310 silc_free(sconn->backup_replace_ip);
1314 /* Creates connection to a remote router. */
1316 void silc_server_create_connection(SilcServer server,
1319 const char *remote_host, SilcUInt32 port,
1320 SilcServerConnectCallback callback,
1323 SilcServerConnection sconn;
1325 /* Allocate connection object for hold connection specific stuff. */
1326 sconn = silc_calloc(1, sizeof(*sconn));
1329 sconn->remote_host = strdup(remote_host);
1330 sconn->remote_port = port;
1331 sconn->no_reconnect = reconnect == FALSE;
1332 sconn->callback = callback;
1333 sconn->callback_context = context;
1334 sconn->no_conf = dynamic;
1335 sconn->server = server;
1337 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1338 remote_host, port));
1340 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1344 /* Connection authentication completion callback */
1347 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1350 SilcServerConnection sconn = context;
1351 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1352 SilcServer server = entry->server;
1353 SilcServerConfigServer *conn;
1354 SilcServerConfigConnParams *param;
1355 SilcIDListData idata;
1356 SilcServerEntry id_entry = NULL;
1357 unsigned char id[32];
1362 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1367 if (success == FALSE) {
1368 /* Authentication failed */
1370 /* Try reconnecting if configuration wants it */
1371 if (!sconn->no_reconnect) {
1372 silc_schedule_task_add_timeout(server->schedule,
1373 silc_server_connect_to_router_retry,
1375 silc_dlist_del(server->conns, sconn);
1379 if (sconn->callback)
1380 (*sconn->callback)(server, NULL, sconn->callback_context);
1381 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1382 silc_server_disconnect_remote(server, sconn->sock,
1383 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1387 /* XXX For now remote is router always */
1388 entry->data.conn_type = SILC_CONN_ROUTER;
1390 SILC_LOG_INFO(("Connected to %s %s",
1391 SILC_CONNTYPE_STRING(entry->data.conn_type),
1392 sconn->remote_host));
1394 /* Create the actual entry for remote entity */
1395 switch (entry->data.conn_type) {
1396 case SILC_CONN_SERVER:
1397 SILC_LOG_DEBUG(("Remote is SILC server"));
1399 /* Add new server. The server must register itself to us before it
1400 becomes registered to SILC network. */
1401 id_entry = silc_idlist_add_server(server->local_list,
1402 strdup(sconn->remote_host),
1403 SILC_SERVER, NULL, NULL, sconn->sock);
1405 if (sconn->callback)
1406 (*sconn->callback)(server, NULL, sconn->callback_context);
1407 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1408 silc_server_disconnect_remote(server, sconn->sock,
1409 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1414 server->stat.my_servers++;
1415 if (server->server_type == SILC_ROUTER)
1416 server->stat.servers++;
1417 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1419 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1422 case SILC_CONN_ROUTER:
1423 SILC_LOG_DEBUG(("Remote is SILC router"));
1425 /* Register to network */
1426 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1427 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1428 SILC_STR_UI_SHORT(id_len),
1429 SILC_STR_DATA(id, id_len),
1430 SILC_STR_UI_SHORT(strlen(server->server_name)),
1431 SILC_STR_DATA(server->server_name,
1432 strlen(server->server_name)),
1434 if (sconn->callback)
1435 (*sconn->callback)(server, NULL, sconn->callback_context);
1436 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1437 silc_server_disconnect_remote(server, sconn->sock,
1438 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1443 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1445 /* Check that we do not have this ID already */
1446 id_entry = silc_idlist_find_server_by_id(server->local_list,
1447 &remote_id.u.server_id,
1450 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1452 id_entry = silc_idlist_find_server_by_id(server->global_list,
1453 &remote_id.u.server_id,
1456 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1460 SILC_LOG_DEBUG(("New server id(%s)",
1461 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1463 /* Add the connected router to global server list. Router is sent
1464 as NULL since it's local to us. */
1465 id_entry = silc_idlist_add_server(server->global_list,
1466 strdup(sconn->remote_host),
1468 silc_id_dup(&remote_id.u.server_id,
1472 /* Try reconnecting if configuration wants it */
1473 if (!sconn->no_reconnect) {
1474 silc_schedule_task_add_timeout(server->schedule,
1475 silc_server_connect_to_router_retry,
1477 silc_dlist_del(server->conns, sconn);
1481 if (sconn->callback)
1482 (*sconn->callback)(server, NULL, sconn->callback_context);
1483 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1484 silc_server_disconnect_remote(server, sconn->sock,
1485 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1490 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1491 idata = (SilcIDListData)id_entry;
1492 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1493 SILC_IDLIST_STATUS_LOCAL);
1494 idata->sconn = sconn;
1495 idata->sconn->callback = NULL;
1498 server->stat.my_routers++;
1499 if (server->server_type == SILC_ROUTER)
1500 server->stat.routers++;
1501 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1503 if (!sconn->backup) {
1504 /* Mark this router our primary router if we're still standalone */
1505 if (server->standalone) {
1506 SILC_LOG_DEBUG(("This connection is our primary router"));
1507 server->id_entry->router = id_entry;
1508 server->router = id_entry;
1509 server->router->server_type = SILC_ROUTER;
1510 server->standalone = FALSE;
1511 server->backup_primary = FALSE;
1513 /* Announce data if we are not backup router (unless not as primary
1514 currently). Backup router announces later at the end of
1515 resuming protocol. */
1516 if (server->backup_router && server->server_type == SILC_ROUTER) {
1517 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1519 /* If we are router then announce our possible servers. Backup
1520 router announces also global servers. */
1521 if (server->server_type == SILC_ROUTER)
1522 silc_server_announce_servers(server,
1523 server->backup_router ? TRUE : FALSE,
1524 0, SILC_PRIMARY_ROUTE(server));
1526 /* Announce our clients and channels to the router */
1527 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1528 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1531 /* If we are backup router then this primary router is whom we are
1533 if (server->server_type == SILC_BACKUP_ROUTER) {
1534 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1536 NULL, NULL, &ip, NULL);
1537 silc_server_backup_add(server, server->id_entry, ip,
1538 sconn->remote_port, TRUE);
1543 /* We already have primary router. Disconnect this connection */
1544 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1545 silc_idlist_del_server(server->global_list, id_entry);
1546 if (sconn->callback)
1547 (*sconn->callback)(server, NULL, sconn->callback_context);
1548 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1549 silc_server_disconnect_remote(server, sconn->sock,
1550 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1555 /* Add this server to be our backup router */
1556 id_entry->server_type = SILC_BACKUP_ROUTER;
1557 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1558 sconn->backup_replace_port, FALSE);
1564 if (sconn->callback)
1565 (*sconn->callback)(server, NULL, sconn->callback_context);
1566 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1567 silc_server_disconnect_remote(server, sconn->sock,
1568 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1572 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1574 conn = sconn->conn.ref_ptr;
1575 param = &server->config->param;
1576 if (conn && conn->param)
1577 param = conn->param;
1579 /* Register rekey timeout */
1580 sconn->rekey_timeout = param->key_exchange_rekey;
1581 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1582 sconn->sock, sconn->rekey_timeout, 0);
1584 /* Set the entry as packet stream context */
1585 silc_packet_set_context(sconn->sock, id_entry);
1587 /* Call the completion callback to indicate that we've connected to
1589 if (sconn && sconn->callback)
1590 (*sconn->callback)(server, id_entry, sconn->callback_context);
1592 if (sconn == server->router_conn)
1593 server->router_conn = NULL;
1598 /* SKE completion callback */
1600 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1601 SilcSKESecurityProperties prop,
1602 SilcSKEKeyMaterial keymat,
1603 SilcSKERekeyMaterial rekey,
1606 SilcPacketStream sock = context;
1607 SilcUnknownEntry entry = silc_packet_get_context(sock);
1608 SilcServerConnection sconn;
1610 SilcServerConfigRouter *conn;
1611 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1612 void *auth_data = NULL;
1613 SilcUInt32 auth_data_len = 0;
1614 SilcConnAuth connauth;
1615 SilcCipher send_key, receive_key;
1616 SilcHmac hmac_send, hmac_receive;
1618 server = entry->server;
1619 sconn = entry->data.sconn;
1620 conn = sconn->conn.ref_ptr;
1623 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1625 if (status != SILC_SKE_STATUS_OK) {
1627 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1628 silc_ske_map_status(status), entry->hostname, entry->ip));
1631 /* Try reconnecting if configuration wants it */
1632 if (!sconn->no_reconnect) {
1633 silc_schedule_task_add_timeout(server->schedule,
1634 silc_server_connect_to_router_retry,
1636 silc_dlist_del(server->conns, sconn);
1640 if (sconn->callback)
1641 (*sconn->callback)(server, NULL, sconn->callback_context);
1642 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1643 silc_server_disconnect_remote(server, sconn->sock,
1644 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1648 SILC_LOG_DEBUG(("Setting keys into use"));
1650 /* Set the keys into use. The data will be encrypted after this. */
1651 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1652 &hmac_send, &hmac_receive, NULL)) {
1655 /* Try reconnecting if configuration wants it */
1656 if (!sconn->no_reconnect) {
1657 silc_schedule_task_add_timeout(server->schedule,
1658 silc_server_connect_to_router_retry,
1660 silc_dlist_del(server->conns, sconn);
1664 /* Error setting keys */
1665 if (sconn->callback)
1666 (*sconn->callback)(server, NULL, sconn->callback_context);
1667 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1668 silc_server_disconnect_remote(server, sconn->sock,
1669 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1672 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1673 hmac_receive, FALSE);
1675 SILC_LOG_DEBUG(("Starting connection authentication"));
1677 connauth = silc_connauth_alloc(server->schedule, ske,
1678 server->config->conn_auth_timeout);
1682 /* Try reconnecting if configuration wants it */
1683 if (!sconn->no_reconnect) {
1684 silc_schedule_task_add_timeout(server->schedule,
1685 silc_server_connect_to_router_retry,
1687 silc_dlist_del(server->conns, sconn);
1691 /** Error allocating auth protocol */
1692 if (sconn->callback)
1693 (*sconn->callback)(server, NULL, sconn->callback_context);
1694 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1695 silc_server_disconnect_remote(server, sconn->sock,
1696 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1700 /* Get authentication method */
1702 if (conn->passphrase) {
1703 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1704 auth_meth = SILC_AUTH_PUBLIC_KEY;
1705 auth_data = server->private_key;
1707 auth_meth = SILC_AUTH_PASSWORD;
1708 auth_data = conn->passphrase;
1709 auth_data_len = conn->passphrase_len;
1712 auth_meth = SILC_AUTH_PUBLIC_KEY;
1713 auth_data = server->private_key;
1717 entry->data.rekey = rekey;
1719 /* Start connection authentication */
1721 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1722 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1723 auth_data, auth_data_len,
1724 silc_server_ke_auth_compl, sconn);
1727 /* Function that is called when the network connection to a router has
1728 been established. This will continue with the key exchange protocol
1729 with the remote router. */
1731 void silc_server_start_key_exchange(SilcServerConnection sconn)
1733 SilcServer server = sconn->server;
1734 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1735 SilcUnknownEntry entry;
1736 SilcSKEParamsStruct params;
1739 /* Cancel any possible retry timeouts */
1740 silc_schedule_task_del_by_context(server->schedule, sconn);
1742 /* Create packet stream */
1743 sconn->sock = silc_packet_stream_create(server->packet_engine,
1744 server->schedule, sconn->stream);
1746 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1747 silc_stream_destroy(sconn->stream);
1749 /* Try reconnecting if configuration wants it */
1750 if (!sconn->no_reconnect) {
1751 silc_schedule_task_add_timeout(server->schedule,
1752 silc_server_connect_to_router_retry,
1754 silc_dlist_del(server->conns, sconn);
1758 if (sconn->callback)
1759 (*sconn->callback)(server, NULL, sconn->callback_context);
1760 silc_server_connection_free(sconn);
1763 server->stat.conn_num++;
1765 /* Set source ID to packet stream */
1766 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1768 silc_packet_stream_destroy(sconn->sock);
1770 /* Try reconnecting if configuration wants it */
1771 if (!sconn->no_reconnect) {
1772 silc_schedule_task_add_timeout(server->schedule,
1773 silc_server_connect_to_router_retry,
1775 silc_dlist_del(server->conns, sconn);
1779 if (sconn->callback)
1780 (*sconn->callback)(server, NULL, sconn->callback_context);
1781 silc_server_connection_free(sconn);
1785 /* Create entry for remote entity */
1786 entry = silc_calloc(1, sizeof(*entry));
1788 silc_packet_stream_destroy(sconn->sock);
1790 /* Try reconnecting if configuration wants it */
1791 if (!sconn->no_reconnect) {
1792 silc_schedule_task_add_timeout(server->schedule,
1793 silc_server_connect_to_router_retry,
1795 silc_dlist_del(server->conns, sconn);
1799 if (sconn->callback)
1800 (*sconn->callback)(server, NULL, sconn->callback_context);
1801 silc_server_connection_free(sconn);
1804 entry->server = server;
1805 entry->data.sconn = sconn;
1806 entry->data.conn_type = SILC_CONN_UNKNOWN;
1807 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1808 silc_packet_set_context(sconn->sock, entry);
1810 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1812 /* Set Key Exchange flags from configuration, but fall back to global
1814 memset(¶ms, 0, sizeof(params));
1815 SILC_GET_SKE_FLAGS(conn, params.flags);
1816 if (server->config->param.key_exchange_pfs)
1817 params.flags |= SILC_SKE_SP_FLAG_PFS;
1819 /* Start SILC Key Exchange protocol */
1820 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1821 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1822 server->public_key, server->private_key, sconn);
1825 silc_packet_stream_destroy(sconn->sock);
1827 /* Try reconnecting if configuration wants it */
1828 if (!sconn->no_reconnect) {
1829 silc_schedule_task_add_timeout(server->schedule,
1830 silc_server_connect_to_router_retry,
1832 silc_dlist_del(server->conns, sconn);
1836 if (sconn->callback)
1837 (*sconn->callback)(server, NULL, sconn->callback_context);
1838 silc_server_connection_free(sconn);
1841 silc_ske_set_callbacks(ske, silc_server_verify_key,
1842 silc_server_ke_completed, sconn->sock);
1844 /* Start key exchange protocol */
1845 params.version = silc_version_string;
1846 params.timeout_secs = server->config->key_exchange_timeout;
1847 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1850 /* Timeout callback that will be called to retry connecting to remote
1851 router. This is used by both normal and router server. This will wait
1852 before retrying the connecting. The timeout is generated by exponential
1853 backoff algorithm. */
1855 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1857 SilcServerConnection sconn = context;
1858 SilcServer server = sconn->server;
1859 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1860 SilcServerConfigConnParams *param =
1861 (conn->param ? conn->param : &server->config->param);
1863 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1864 sconn->remote_port));
1866 /* Calculate next timeout */
1867 if (sconn->retry_count >= 1) {
1868 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1869 if (sconn->retry_timeout > param->reconnect_interval_max)
1870 sconn->retry_timeout = param->reconnect_interval_max;
1872 sconn->retry_timeout = param->reconnect_interval;
1874 sconn->retry_count++;
1875 sconn->retry_timeout = sconn->retry_timeout +
1876 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1878 /* If we've reached max retry count, give up. */
1879 if ((sconn->retry_count > param->reconnect_count) &&
1880 sconn->no_reconnect) {
1881 SILC_LOG_ERROR(("Could not connect, giving up"));
1883 if (sconn->callback)
1884 (*sconn->callback)(server, NULL, sconn->callback_context);
1885 silc_server_connection_free(sconn);
1889 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1891 /* We will lookup a fresh pointer later */
1892 silc_server_config_unref(&sconn->conn);
1894 /* Wait before retrying */
1895 silc_schedule_task_del_by_context(server->schedule, sconn);
1896 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1897 sconn, sconn->retry_timeout, 0);
1900 /* Callback for async connection to remote router */
1902 static void silc_server_connection_established(SilcNetStatus status,
1906 SilcServerConnection sconn = context;
1907 SilcServer server = sconn->server;
1909 silc_schedule_task_del_by_context(server->schedule, sconn);
1914 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1915 sconn->remote_host, sconn->remote_port));
1917 /* Continue with key exchange protocol */
1918 sconn->stream = stream;
1919 silc_server_start_key_exchange(sconn);
1922 case SILC_NET_UNKNOWN_IP:
1923 case SILC_NET_UNKNOWN_HOST:
1924 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1925 sconn->remote_host, sconn->remote_port,
1926 silc_net_get_error_string(status)));
1927 if (!sconn->no_reconnect) {
1928 silc_schedule_task_add_timeout(sconn->server->schedule,
1929 silc_server_connect_to_router_retry,
1931 silc_dlist_del(server->conns, sconn);
1933 if (sconn->callback)
1934 (*sconn->callback)(server, NULL, sconn->callback_context);
1935 silc_server_connection_free(sconn);
1940 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1941 sconn->remote_host, sconn->remote_port,
1942 silc_net_get_error_string(status)));
1943 if (!sconn->no_reconnect) {
1944 silc_schedule_task_add_timeout(sconn->server->schedule,
1945 silc_server_connect_to_router_retry,
1947 silc_dlist_del(server->conns, sconn);
1949 if (sconn->callback)
1950 (*sconn->callback)(server, NULL, sconn->callback_context);
1951 silc_server_connection_free(sconn);
1957 /* Generic routine to use connect to a router. */
1959 SILC_TASK_CALLBACK(silc_server_connect_router)
1961 SilcServerConnection sconn = context;
1962 SilcServer server = sconn->server;
1963 SilcServerConfigRouter *rconn;
1965 silc_schedule_task_del_by_context(server->schedule, sconn);
1967 /* Don't connect if we are shutting down. */
1968 if (server->server_shutdown) {
1969 if (sconn->callback)
1970 (*sconn->callback)(server, NULL, sconn->callback_context);
1971 silc_server_connection_free(sconn);
1975 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1976 (sconn->backup ? "backup router" : "router"),
1977 sconn->remote_host, sconn->remote_port));
1979 if (!sconn->no_conf) {
1980 /* Find connection configuration */
1981 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1982 sconn->remote_port);
1984 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1985 (sconn->backup ? "backup router" : "router"),
1986 sconn->remote_host, sconn->remote_port));
1987 if (sconn->callback)
1988 (*sconn->callback)(server, NULL, sconn->callback_context);
1989 silc_server_connection_free(sconn);
1992 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1995 /* Connect to remote host */
1997 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1998 server->config->server_info->primary->server_ip),
1999 sconn->remote_host, sconn->remote_port,
2000 server->schedule, silc_server_connection_established,
2003 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2004 sconn->remote_host, sconn->remote_port));
2005 if (sconn->callback)
2006 (*sconn->callback)(server, NULL, sconn->callback_context);
2007 silc_server_connection_free(sconn);
2011 /* Add to connection list */
2012 silc_dlist_add(server->conns, sconn);
2015 /* This function connects to our primary router or if we are a router this
2016 establishes all our primary routes. This is called at the start of the
2017 server to do authentication and key exchange with our router - called
2020 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2022 SilcServer server = context;
2023 SilcServerConnection sconn;
2024 SilcServerConfigRouter *ptr;
2025 SilcServerConfigConnParams *param;
2027 /* Don't connect if we are shutting down. */
2028 if (server->server_shutdown)
2031 SILC_LOG_DEBUG(("We are %s",
2032 (server->server_type == SILC_SERVER ?
2033 "normal server" : server->server_type == SILC_ROUTER ?
2034 "router" : "backup router/normal server")));
2036 if (!server->config->routers) {
2037 /* There wasn't a configured router, we will continue but we don't
2038 have a connection to outside world. We will be standalone server. */
2039 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2040 server->standalone = TRUE;
2044 /* Cancel any possible retry timeouts */
2045 silc_schedule_task_del_by_callback(server->schedule,
2046 silc_server_connect_router);
2047 silc_schedule_task_del_by_callback(server->schedule,
2048 silc_server_connect_to_router_retry);
2050 /* Create the connections to all our routes */
2051 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2053 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2054 ptr->backup_router ? "Backup router" : "Router",
2055 ptr->initiator ? "Initiator" : "Responder",
2056 ptr->host, ptr->port));
2058 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2059 ptr->initiator == FALSE && !server->backup_router &&
2060 !silc_server_config_get_backup_router(server))
2061 server->wait_backup = TRUE;
2063 if (!ptr->initiator)
2065 if (ptr->dynamic_connection)
2068 /* Check whether we are connecting or connected to this host already */
2069 if (silc_server_num_sockets_by_remote(server,
2070 silc_net_is_ip(ptr->host) ?
2072 silc_net_is_ip(ptr->host) ?
2073 NULL : ptr->host, ptr->port,
2074 SILC_CONN_ROUTER)) {
2075 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2076 ptr->host, ptr->port));
2078 /* If we don't have primary router and this connection is our
2079 primary router we are in desync. Reconnect to the primary. */
2080 if (server->standalone && !server->router) {
2082 SilcPacketStream sock;
2083 SilcServerConfigRouter *primary =
2084 silc_server_config_get_primary_router(server);
2087 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2088 ptr->host, ptr->port);
2091 server->backup_noswitch = TRUE;
2092 silc_server_free_sock_user_data(server, sock, NULL);
2093 silc_server_disconnect_remote(server, sock, 0, NULL);
2094 server->backup_noswitch = FALSE;
2095 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2101 param = (ptr->param ? ptr->param : &server->config->param);
2103 /* Allocate connection object for hold connection specific stuff. */
2104 sconn = silc_calloc(1, sizeof(*sconn));
2107 sconn->server = server;
2108 sconn->remote_host = strdup(ptr->host);
2109 sconn->remote_port = ptr->port;
2110 sconn->backup = ptr->backup_router;
2111 if (sconn->backup) {
2112 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2113 sconn->backup_replace_port = ptr->backup_replace_port;
2115 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2117 SILC_LOG_DEBUG(("Created connection %p", sconn));
2119 if (!server->router_conn && !sconn->backup)
2120 server->router_conn = sconn;
2123 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2129 /************************ Accepting new connection **************************/
2131 /* After this is called, server don't wait for backup router anymore.
2132 This gets called automatically even after we have backup router
2133 connection established. */
2135 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2137 SilcServer server = context;
2138 server->wait_backup = FALSE;
2141 /* Authentication data callback */
2144 silc_server_accept_get_auth(SilcConnAuth connauth,
2145 SilcConnectionType conn_type,
2146 unsigned char **passphrase,
2147 SilcUInt32 *passphrase_len,
2148 SilcSKR *repository,
2151 SilcPacketStream sock = context;
2152 SilcUnknownEntry entry = silc_packet_get_context(sock);
2153 SilcServer server = entry->server;
2155 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2157 /* Remote end is client */
2158 if (conn_type == SILC_CONN_CLIENT) {
2159 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2163 *passphrase = cconfig->passphrase;
2164 *passphrase_len = cconfig->passphrase_len;
2165 if (cconfig->publickeys)
2166 *repository = server->repository;
2168 if (cconfig->publickeys) {
2169 if (server->config->prefer_passphrase_auth) {
2173 *passphrase_len = 0;
2177 entry->conn_type = conn_type;
2181 /* Remote end is server */
2182 if (conn_type == SILC_CONN_SERVER) {
2183 SilcServerConfigServer *sconfig;
2185 /* If we are normal server, don't accept the connection */
2186 if (server->server_type == SILC_SERVER)
2189 sconfig = entry->sconfig.ref_ptr;
2193 *passphrase = sconfig->passphrase;
2194 *passphrase_len = sconfig->passphrase_len;
2195 if (sconfig->publickeys)
2196 *repository = server->repository;
2198 if (sconfig->publickeys) {
2199 if (server->config->prefer_passphrase_auth) {
2203 *passphrase_len = 0;
2207 entry->conn_type = conn_type;
2211 /* Remote end is router */
2212 if (conn_type == SILC_CONN_ROUTER) {
2213 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2217 *passphrase = rconfig->passphrase;
2218 *passphrase_len = rconfig->passphrase_len;
2219 if (rconfig->publickeys)
2220 *repository = server->repository;
2222 if (rconfig->publickeys) {
2223 if (server->config->prefer_passphrase_auth) {
2227 *passphrase_len = 0;
2231 entry->conn_type = conn_type;
2238 /* Authentication completion callback. */
2241 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2244 SilcPacketStream sock = context;
2245 SilcUnknownEntry entry = silc_packet_get_context(sock);
2246 SilcIDListData idata = (SilcIDListData)entry;
2247 SilcServer server = entry->server;
2248 SilcServerConfigConnParams *param = &server->config->param;
2249 SilcServerConnection sconn;
2251 const char *hostname, *ip;
2255 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2256 NULL, &hostname, &ip, &port);
2258 if (success == FALSE) {
2259 /* Authentication failed */
2260 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2261 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2262 server->stat.auth_failures++;
2263 silc_server_disconnect_remote(server, sock,
2264 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2265 silc_server_config_unref(&entry->cconfig);
2266 silc_server_config_unref(&entry->sconfig);
2267 silc_server_config_unref(&entry->rconfig);
2268 silc_server_free_sock_user_data(server, sock, NULL);
2272 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2274 switch (entry->conn_type) {
2275 case SILC_CONN_CLIENT:
2277 SilcClientEntry client;
2278 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2280 /* Verify whether this connection is after all allowed to connect */
2281 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2282 &server->config->param,
2284 silc_connauth_get_ske(connauth))) {
2285 server->stat.auth_failures++;
2289 /* If we are primary router and we have backup router configured
2290 but it has not connected to use yet, do not accept any other
2292 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2293 !server->backup_router) {
2294 SilcServerConfigRouter *router;
2295 router = silc_server_config_get_backup_router(server);
2296 if (router && strcmp(server->config->server_info->primary->server_ip,
2298 silc_server_find_socket_by_host(server,
2300 router->backup_replace_ip, 0)) {
2301 SILC_LOG_INFO(("Will not accept connections because we do "
2302 "not have backup router connection established"));
2303 silc_server_disconnect_remote(server, sock,
2304 SILC_STATUS_ERR_PERM_DENIED,
2305 "We do not have connection to backup "
2306 "router established, try later");
2307 silc_server_config_unref(&entry->cconfig);
2308 silc_server_config_unref(&entry->sconfig);
2309 silc_server_config_unref(&entry->rconfig);
2310 silc_server_free_sock_user_data(server, sock, NULL);
2311 server->stat.auth_failures++;
2313 /* From here on, wait 20 seconds for the backup router to appear. */
2314 silc_schedule_task_add_timeout(server->schedule,
2315 silc_server_backup_router_wait,
2316 (void *)server, 20, 0);
2321 SILC_LOG_DEBUG(("Remote host is client"));
2322 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2325 /* Add the client to the client ID cache. The nickname and Client ID
2326 and other information is created after we have received NEW_CLIENT
2327 packet from client. */
2328 client = silc_idlist_add_client(server->local_list,
2329 NULL, NULL, NULL, NULL, NULL, sock);
2331 SILC_LOG_ERROR(("Could not add new client to cache"));
2332 server->stat.auth_failures++;
2333 silc_server_disconnect_remote(server, sock,
2334 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2335 silc_server_config_unref(&entry->cconfig);
2336 silc_server_config_unref(&entry->sconfig);
2337 silc_server_config_unref(&entry->rconfig);
2338 silc_server_free_sock_user_data(server, sock, NULL);
2341 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2342 entry->data.conn_type = SILC_CONN_CLIENT;
2345 server->stat.my_clients++;
2346 server->stat.clients++;
2347 server->stat.cell_clients++;
2349 /* Get connection parameters */
2351 param = conn->param;
2353 if (!param->keepalive_secs)
2354 param->keepalive_secs = server->config->param.keepalive_secs;
2356 if (!param->qos && server->config->param.qos) {
2357 param->qos = server->config->param.qos;
2358 param->qos_rate_limit = server->config->param.qos_rate_limit;
2359 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2360 param->qos_limit_sec = server->config->param.qos_limit_sec;
2361 param->qos_limit_usec = server->config->param.qos_limit_usec;
2364 /* Check if to be anonymous connection */
2365 if (param->anonymous)
2366 client->mode |= SILC_UMODE_ANONYMOUS;
2369 /* Add public key to repository */
2370 SILC_LOG_DEBUG(("Add client public key to repository"));
2371 if (!silc_server_get_public_key_by_client(server, client, NULL))
2372 silc_skr_add_public_key_simple(server->repository,
2373 entry->data.public_key,
2374 SILC_SKR_USAGE_IDENTIFICATION, client,
2377 id_entry = (void *)client;
2381 case SILC_CONN_SERVER:
2382 case SILC_CONN_ROUTER:
2384 SilcServerEntry new_server;
2385 SilcBool initiator = FALSE;
2386 SilcBool backup_local = FALSE;
2387 SilcBool backup_router = FALSE;
2388 char *backup_replace_ip = NULL;
2389 SilcUInt16 backup_replace_port = 0;
2390 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2391 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2393 /* If we are backup router and this is incoming server connection
2394 and we do not have connection to primary router, do not allow
2396 if (server->server_type == SILC_BACKUP_ROUTER &&
2397 entry->conn_type == SILC_CONN_SERVER &&
2398 !SILC_PRIMARY_ROUTE(server)) {
2399 SILC_LOG_INFO(("Will not accept server connection because we do "
2400 "not have primary router connection established"));
2401 silc_server_disconnect_remote(server, sock,
2402 SILC_STATUS_ERR_PERM_DENIED,
2403 "We do not have connection to primary "
2404 "router established, try later");
2405 silc_server_config_unref(&entry->cconfig);
2406 silc_server_config_unref(&entry->sconfig);
2407 silc_server_config_unref(&entry->rconfig);
2408 silc_server_free_sock_user_data(server, sock, NULL);
2409 server->stat.auth_failures++;
2413 if (entry->conn_type == SILC_CONN_ROUTER) {
2414 /* Verify whether this connection is after all allowed to connect */
2415 if (!silc_server_connection_allowed(server, sock,
2417 &server->config->param,
2418 rconn ? rconn->param : NULL,
2419 silc_connauth_get_ske(connauth))) {
2420 silc_server_config_unref(&entry->cconfig);
2421 silc_server_config_unref(&entry->sconfig);
2422 silc_server_config_unref(&entry->rconfig);
2423 server->stat.auth_failures++;
2429 param = rconn->param;
2431 if (!param->keepalive_secs)
2432 param->keepalive_secs = server->config->param.keepalive_secs;
2434 if (!param->qos && server->config->param.qos) {
2435 param->qos = server->config->param.qos;
2436 param->qos_rate_limit = server->config->param.qos_rate_limit;
2437 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2438 param->qos_limit_sec = server->config->param.qos_limit_sec;
2439 param->qos_limit_usec = server->config->param.qos_limit_usec;
2443 initiator = rconn->initiator;
2444 backup_local = rconn->backup_local;
2445 backup_router = rconn->backup_router;
2446 backup_replace_ip = rconn->backup_replace_ip;
2447 backup_replace_port = rconn->backup_replace_port;
2451 if (entry->conn_type == SILC_CONN_SERVER) {
2452 /* Verify whether this connection is after all allowed to connect */
2453 if (!silc_server_connection_allowed(server, sock,
2455 &server->config->param,
2456 srvconn ? srvconn->param : NULL,
2457 silc_connauth_get_ske(connauth))) {
2458 server->stat.auth_failures++;
2462 if (srvconn->param) {
2463 param = srvconn->param;
2465 if (!param->keepalive_secs)
2466 param->keepalive_secs = server->config->param.keepalive_secs;
2468 if (!param->qos && server->config->param.qos) {
2469 param->qos = server->config->param.qos;
2470 param->qos_rate_limit = server->config->param.qos_rate_limit;
2471 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2472 param->qos_limit_sec = server->config->param.qos_limit_sec;
2473 param->qos_limit_usec = server->config->param.qos_limit_usec;
2477 backup_router = srvconn->backup_router;
2481 /* If we are primary router and we have backup router configured
2482 but it has not connected to use yet, do not accept any other
2484 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2485 !server->backup_router && !backup_router) {
2486 SilcServerConfigRouter *router;
2487 router = silc_server_config_get_backup_router(server);
2488 if (router && strcmp(server->config->server_info->primary->server_ip,
2490 silc_server_find_socket_by_host(server,
2492 router->backup_replace_ip, 0)) {
2493 SILC_LOG_INFO(("Will not accept connections because we do "
2494 "not have backup router connection established"));
2495 silc_server_disconnect_remote(server, sock,
2496 SILC_STATUS_ERR_PERM_DENIED,
2497 "We do not have connection to backup "
2498 "router established, try later");
2499 silc_server_config_unref(&entry->cconfig);
2500 silc_server_config_unref(&entry->sconfig);
2501 silc_server_config_unref(&entry->rconfig);
2502 silc_server_free_sock_user_data(server, sock, NULL);
2503 server->stat.auth_failures++;
2505 /* From here on, wait 20 seconds for the backup router to appear. */
2506 silc_schedule_task_add_timeout(server->schedule,
2507 silc_server_backup_router_wait,
2508 (void *)server, 20, 0);
2513 SILC_LOG_DEBUG(("Remote host is %s",
2514 entry->conn_type == SILC_CONN_SERVER ?
2515 "server" : (backup_router ?
2516 "backup router" : "router")));
2517 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2518 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2519 "server" : (backup_router ?
2520 "backup router" : "router")));
2522 /* Add the server into server cache. The server name and Server ID
2523 is updated after we have received NEW_SERVER packet from the
2524 server. We mark ourselves as router for this server if we really
2527 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2528 server->local_list : (backup_router ?
2529 server->local_list :
2530 server->global_list)),
2532 (entry->conn_type == SILC_CONN_SERVER ?
2533 SILC_SERVER : SILC_ROUTER),
2535 (entry->conn_type == SILC_CONN_SERVER ?
2536 server->id_entry : (backup_router ?
2537 server->id_entry : NULL)),
2540 SILC_LOG_ERROR(("Could not add new server to cache"));
2541 silc_server_disconnect_remote(server, sock,
2542 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2543 silc_server_config_unref(&entry->cconfig);
2544 silc_server_config_unref(&entry->sconfig);
2545 silc_server_config_unref(&entry->rconfig);
2546 silc_server_free_sock_user_data(server, sock, NULL);
2547 server->stat.auth_failures++;
2550 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2551 entry->data.conn_type = entry->conn_type;
2553 id_entry = (void *)new_server;
2555 /* If the incoming connection is router and marked as backup router
2556 then add it to be one of our backups */
2557 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2558 /* Change it back to SERVER type since that's what it really is. */
2560 entry->data.conn_type = SILC_CONN_SERVER;
2561 new_server->server_type = SILC_BACKUP_ROUTER;
2563 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2564 ("Backup router %s is now online",
2567 /* Remove the backup waiting with timeout */
2568 silc_schedule_task_add_timeout(server->schedule,
2569 silc_server_backup_router_wait,
2570 (void *)server, 10, 0);
2574 if (entry->data.conn_type == SILC_CONN_SERVER) {
2575 server->stat.my_servers++;
2576 server->stat.servers++;
2577 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2579 server->stat.my_routers++;
2580 server->stat.routers++;
2581 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2584 /* Check whether this connection is to be our primary router connection
2585 if we do not already have the primary route. */
2586 if (!backup_router &&
2587 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2588 if (silc_server_config_is_primary_route(server) && !initiator)
2591 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2592 server->standalone = FALSE;
2593 if (!server->id_entry->router) {
2594 server->id_entry->router = id_entry;
2595 server->router = id_entry;
2607 /* Add connection to server->conns so that we know we have connection
2609 sconn = silc_calloc(1, sizeof(*sconn));
2610 sconn->server = server;
2612 sconn->remote_host = strdup(hostname);
2613 sconn->remote_port = port;
2614 silc_dlist_add(server->conns, sconn);
2615 idata->sconn = sconn;
2616 idata->sconn->callback = NULL;
2617 idata->last_receive = time(NULL);
2619 /* Add the common data structure to the ID entry. */
2620 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2621 silc_packet_set_context(sock, id_entry);
2623 /* Connection has been fully established now. Everything is ok. */
2624 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2626 /* Perform Quality of Service */
2628 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2629 param->qos_rate_limit, param->qos_bytes_limit,
2630 param->qos_limit_sec, param->qos_limit_usec);
2632 silc_server_config_unref(&entry->cconfig);
2633 silc_server_config_unref(&entry->sconfig);
2634 silc_server_config_unref(&entry->rconfig);
2638 silc_ske_free(silc_connauth_get_ske(connauth));
2639 silc_connauth_free(connauth);
2642 /* SKE completion callback. We set the new keys into use here. */
2645 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2646 SilcSKESecurityProperties prop,
2647 SilcSKEKeyMaterial keymat,
2648 SilcSKERekeyMaterial rekey,
2651 SilcPacketStream sock = context;
2652 SilcUnknownEntry entry = silc_packet_get_context(sock);
2653 SilcIDListData idata = (SilcIDListData)entry;
2654 SilcServer server = entry->server;
2655 SilcConnAuth connauth;
2656 SilcCipher send_key, receive_key;
2657 SilcHmac hmac_send, hmac_receive;
2664 if (status != SILC_SKE_STATUS_OK) {
2666 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2667 silc_ske_map_status(status), entry->hostname, entry->ip));
2669 silc_server_disconnect_remote(server, sock,
2670 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2671 silc_server_config_unref(&entry->cconfig);
2672 silc_server_config_unref(&entry->sconfig);
2673 silc_server_config_unref(&entry->rconfig);
2674 silc_server_free_sock_user_data(server, sock, NULL);
2678 SILC_LOG_DEBUG(("Setting keys into use"));
2680 /* Set the keys into use. The data will be encrypted after this. */
2681 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2682 &hmac_send, &hmac_receive, &hash)) {
2683 /* Error setting keys */
2685 silc_server_disconnect_remote(server, sock,
2686 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2687 silc_server_free_sock_user_data(server, sock, NULL);
2690 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2691 hmac_receive, FALSE);
2693 idata->rekey = rekey;
2694 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2695 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2697 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2702 SILC_LOG_DEBUG(("Starting connection authentication"));
2703 server->stat.auth_attempts++;
2705 connauth = silc_connauth_alloc(server->schedule, ske,
2706 server->config->conn_auth_timeout);
2708 /** Error allocating auth protocol */
2710 silc_server_disconnect_remote(server, sock,
2711 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2712 silc_server_config_unref(&entry->cconfig);
2713 silc_server_config_unref(&entry->sconfig);
2714 silc_server_config_unref(&entry->rconfig);
2715 silc_server_free_sock_user_data(server, sock, NULL);
2719 /* Start connection authentication */
2721 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2722 silc_server_accept_auth_compl, sock);
2725 /* Accept new TCP connection */
2727 static void silc_server_accept_new_connection(SilcNetStatus status,
2731 SilcServer server = context;
2732 SilcPacketStream packet_stream;
2733 SilcServerConfigClient *cconfig = NULL;
2734 SilcServerConfigServer *sconfig = NULL;
2735 SilcServerConfigRouter *rconfig = NULL;
2736 SilcServerConfigDeny *deny;
2737 SilcUnknownEntry entry;
2739 SilcSKEParamsStruct params;
2740 char *hostname, *ip;
2743 SILC_LOG_DEBUG(("Accepting new connection"));
2745 /* Check for maximum allowed connections */
2746 server->stat.conn_attempts++;
2747 if (silc_dlist_count(server->conns) >
2748 server->config->param.connections_max) {
2749 SILC_LOG_ERROR(("Refusing connection, server is full"));
2750 server->stat.conn_failures++;
2751 silc_stream_destroy(stream);
2755 /* Get hostname, IP and port */
2756 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2757 (const char **)&ip, &port)) {
2758 /* Bad socket stream */
2759 server->stat.conn_failures++;
2760 silc_stream_destroy(stream);
2764 /* Create packet stream */
2765 packet_stream = silc_packet_stream_create(server->packet_engine,
2766 server->schedule, stream);
2767 if (!packet_stream) {
2768 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2769 server->stat.conn_failures++;
2770 silc_stream_destroy(stream);
2773 server->stat.conn_num++;
2775 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2777 /* Set source ID to packet stream */
2778 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2781 server->stat.conn_failures++;
2782 silc_packet_stream_destroy(packet_stream);
2786 /* Check whether this connection is denied to connect to us. */
2787 deny = silc_server_config_find_denied(server, ip);
2789 deny = silc_server_config_find_denied(server, hostname);
2791 /* The connection is denied */
2792 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2793 silc_server_disconnect_remote(server, packet_stream,
2794 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2796 silc_server_free_sock_user_data(server, packet_stream, NULL);
2800 /* Check whether we have configured this sort of connection at all. We
2801 have to check all configurations since we don't know what type of
2802 connection this is. */
2803 if (!(cconfig = silc_server_config_find_client(server, ip)))
2804 cconfig = silc_server_config_find_client(server, hostname);
2805 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2806 sconfig = silc_server_config_find_server_conn(server, hostname);
2807 if (server->server_type == SILC_ROUTER)
2808 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2809 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2810 if (!cconfig && !sconfig && !rconfig) {
2811 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2812 server->stat.conn_failures++;
2813 silc_server_disconnect_remote(server, packet_stream,
2814 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2815 silc_server_free_sock_user_data(server, packet_stream, NULL);
2819 /* The connection is allowed */
2820 entry = silc_calloc(1, sizeof(*entry));
2822 server->stat.conn_failures++;
2823 silc_server_disconnect_remote(server, packet_stream,
2824 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2825 silc_server_free_sock_user_data(server, packet_stream, NULL);
2828 entry->hostname = hostname;
2831 entry->server = server;
2832 entry->data.conn_type = SILC_CONN_UNKNOWN;
2833 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2834 silc_packet_set_context(packet_stream, entry);
2836 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2838 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2839 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2840 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2842 /* Take flags for key exchange. Since we do not know what type of connection
2843 this is, we go through all found configurations and use the global ones
2844 as well. This will result always into strictest key exchange flags. */
2845 memset(¶ms, 0, sizeof(params));
2846 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2847 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2848 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2849 if (server->config->param.key_exchange_pfs)
2850 params.flags |= SILC_SKE_SP_FLAG_PFS;
2852 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2853 server->stat.conn_attempts++;
2855 /* Start SILC Key Exchange protocol */
2856 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2857 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2858 server->public_key, server->private_key,
2861 server->stat.conn_failures++;
2862 silc_server_disconnect_remote(server, packet_stream,
2863 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2864 silc_server_free_sock_user_data(server, packet_stream, NULL);
2867 silc_ske_set_callbacks(ske, silc_server_verify_key,
2868 silc_server_accept_completed, packet_stream);
2870 /* Start key exchange protocol */
2871 params.version = silc_version_string;
2872 params.timeout_secs = server->config->key_exchange_timeout;
2873 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2877 /********************************** Rekey ***********************************/
2879 /* Initiator rekey completion callback */
2881 static void silc_server_rekey_completion(SilcSKE ske,
2882 SilcSKEStatus status,
2883 const SilcSKESecurityProperties prop,
2884 const SilcSKEKeyMaterial keymat,
2885 SilcSKERekeyMaterial rekey,
2888 SilcPacketStream sock = context;
2889 SilcIDListData idata = silc_packet_get_context(sock);
2890 SilcServer server = idata->sconn->server;
2892 idata->sconn->op = NULL;
2893 if (status != SILC_SKE_STATUS_OK) {
2894 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2895 idata->sconn->remote_host));
2899 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2900 idata->sconn->remote_host, idata->sconn->remote_port,
2901 SILC_CONNTYPE_STRING(idata->conn_type)));
2903 /* Save rekey data for next rekey */
2904 idata->rekey = rekey;
2906 /* Register new rekey timeout */
2907 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2908 sock, idata->sconn->rekey_timeout, 0);
2911 /* Rekey callback. Start rekey as initiator */
2913 SILC_TASK_CALLBACK(silc_server_do_rekey)
2915 SilcServer server = app_context;
2916 SilcPacketStream sock = context;
2917 SilcIDListData idata = silc_packet_get_context(sock);
2920 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2922 /* Do not execute rekey with disabled connections */
2923 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2926 /* If another protocol is active do not start rekey */
2927 if (idata->sconn->op) {
2928 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2929 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2934 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2935 idata->sconn->remote_host, idata->sconn->remote_port,
2936 SILC_CONNTYPE_STRING(idata->conn_type)));
2939 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2940 server->public_key, NULL, sock);
2944 /* Set SKE callbacks */
2945 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2948 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2951 /* Responder rekey completion callback */
2954 silc_server_rekey_resp_completion(SilcSKE ske,
2955 SilcSKEStatus status,
2956 const SilcSKESecurityProperties prop,
2957 const SilcSKEKeyMaterial keymat,
2958 SilcSKERekeyMaterial rekey,
2961 SilcPacketStream sock = context;
2962 SilcIDListData idata = silc_packet_get_context(sock);
2964 idata->sconn->op = NULL;
2965 if (status != SILC_SKE_STATUS_OK) {
2966 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2967 idata->sconn->remote_host));
2971 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2972 idata->sconn->remote_host, idata->sconn->remote_port,
2973 SILC_CONNTYPE_STRING(idata->conn_type)));
2975 /* Save rekey data for next rekey */
2976 idata->rekey = rekey;
2979 /* Start rekey as responder */
2981 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2984 SilcIDListData idata = silc_packet_get_context(sock);
2987 if (!idata->rekey) {
2988 silc_packet_free(packet);
2992 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
2993 idata->sconn->remote_host, idata->sconn->remote_port,
2994 SILC_CONNTYPE_STRING(idata->conn_type), sock));
2997 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2998 server->public_key, NULL, sock);
3000 silc_packet_free(packet);
3004 /* Set SKE callbacks */
3005 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3008 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3013 /****************************** Disconnection *******************************/
3015 /* Destroys packet stream. */
3017 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3019 silc_packet_stream_unref(context);
3022 /* Closes connection to socket connection */
3024 void silc_server_close_connection(SilcServer server,
3025 SilcPacketStream sock)
3027 SilcIDListData idata = silc_packet_get_context(sock);
3029 const char *hostname;
3032 if (!silc_packet_stream_is_valid(sock))
3035 memset(tmp, 0, sizeof(tmp));
3036 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3037 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3038 NULL, &hostname, NULL, &port);
3039 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3040 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3041 tmp[0] ? tmp : ""));
3043 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3045 if (idata && idata->sconn) {
3046 silc_server_connection_free(idata->sconn);
3047 idata->sconn = NULL;
3050 /* Take a reference and then destroy the stream. The last reference
3051 is released later in a timeout callback. */
3052 silc_packet_stream_ref(sock);
3053 silc_packet_stream_destroy(sock);
3055 /* Close connection with timeout */
3056 server->stat.conn_num--;
3057 silc_schedule_task_del_by_all(server->schedule, 0,
3058 silc_server_close_connection_final, sock);
3059 silc_schedule_task_add_timeout(server->schedule,
3060 silc_server_close_connection_final,
3064 /* Sends disconnect message to remote connection and disconnects the
3067 void silc_server_disconnect_remote(SilcServer server,
3068 SilcPacketStream sock,
3069 SilcStatus status, ...)
3071 unsigned char buf[512];
3078 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock));
3080 va_start(ap, status);
3081 cp = va_arg(ap, char *);
3083 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3086 /* Send SILC_PACKET_DISCONNECT */
3087 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3088 SILC_STR_UI_CHAR(status),
3089 SILC_STR_UI8_STRING(cp ? buf : NULL),
3092 /* Close connection */
3093 silc_server_close_connection(server, sock);
3096 /* Frees client data and notifies about client's signoff. */
3098 void silc_server_free_client_data(SilcServer server,
3099 SilcPacketStream sock,
3100 SilcClientEntry client,
3102 const char *signoff)
3104 SILC_LOG_DEBUG(("Freeing client %p data", client));
3107 /* Check if anyone is watching this nickname */
3108 if (server->server_type == SILC_ROUTER)
3109 silc_server_check_watcher_list(server, client, NULL,
3110 SILC_NOTIFY_TYPE_SIGNOFF);
3112 /* Send SIGNOFF notify to routers. */
3114 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3115 SILC_BROADCAST(server), client->id,
3119 /* Remove client from all channels */
3121 silc_server_remove_from_channels(server, NULL, client,
3122 TRUE, (char *)signoff, TRUE, FALSE);
3124 silc_server_remove_from_channels(server, NULL, client,
3125 FALSE, NULL, FALSE, FALSE);
3127 /* Remove this client from watcher list if it is */
3128 silc_server_del_from_watcher_list(server, client);
3130 /* Remove client's public key from repository, this will free it too. */
3131 if (client->data.public_key) {
3132 silc_skr_del_public_key(server->repository, client->data.public_key,
3134 client->data.public_key = NULL;
3137 /* Update statistics */
3138 server->stat.my_clients--;
3139 assert(server->stat.clients > 0);
3140 server->stat.clients--;
3141 if (server->stat.cell_clients)
3142 server->stat.cell_clients--;
3143 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3144 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3145 silc_schedule_task_del_by_context(server->schedule, client);
3147 if (client->data.sconn) {
3148 silc_server_connection_free(client->data.sconn);
3149 client->data.sconn = NULL;
3152 /* We will not delete the client entry right away. We will take it
3153 into history (for WHOWAS command) for 5 minutes, unless we're
3154 shutting down server. */
3155 if (!server->server_shutdown) {
3156 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3158 client->router = NULL;
3159 client->connection = NULL;
3160 client->data.created = silc_time();
3161 silc_dlist_del(server->expired_clients, client);
3162 silc_dlist_add(server->expired_clients, client);
3164 /* Delete directly since we're shutting down server */
3165 SILC_LOG_DEBUG(("Delete client directly"));
3166 silc_idlist_del_data(client);
3167 silc_idlist_del_client(server->local_list, client);
3171 /* Frees user_data pointer from socket connection object. This also sends
3172 appropriate notify packets to the network to inform about leaving
3175 void silc_server_free_sock_user_data(SilcServer server,
3176 SilcPacketStream sock,
3177 const char *signoff_message)
3179 SilcIDListData idata;
3186 SILC_LOG_DEBUG(("Start, sock %p", sock));
3188 idata = silc_packet_get_context(sock);
3192 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3195 /* Cancel active protocols */
3197 if (idata->sconn && idata->sconn->op) {
3198 SILC_LOG_DEBUG(("Abort active protocol"));
3199 silc_async_abort(idata->sconn->op, NULL, NULL);
3201 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3202 ((SilcUnknownEntry)idata)->op) {
3203 SILC_LOG_DEBUG(("Abort active protocol"));
3204 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3208 switch (idata->conn_type) {
3209 case SILC_CONN_CLIENT:
3211 SilcClientEntry client_entry = (SilcClientEntry)idata;
3212 silc_server_free_client_data(server, sock, client_entry, TRUE,
3214 silc_packet_set_context(sock, NULL);
3218 case SILC_CONN_SERVER:
3219 case SILC_CONN_ROUTER:
3221 SilcServerEntry user_data = (SilcServerEntry)idata;
3222 SilcServerEntry backup_router = NULL;
3224 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3227 backup_router = silc_server_backup_get(server, user_data->id);
3229 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3230 backup_router == server->id_entry &&
3231 idata->conn_type != SILC_CONN_ROUTER)
3232 backup_router = NULL;
3234 if (server->server_shutdown || server->backup_noswitch)
3235 backup_router = NULL;
3237 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3238 NULL, NULL, &ip, &port);
3240 /* If this was our primary router connection then we're lost to
3241 the outside world. */
3242 if (server->router == user_data) {
3243 /* Check whether we have a backup router connection */
3244 if (!backup_router || backup_router == user_data) {
3245 if (!server->no_reconnect)
3246 silc_server_create_connections(server);
3247 server->id_entry->router = NULL;
3248 server->router = NULL;
3249 server->standalone = TRUE;
3250 server->backup_primary = FALSE;
3251 backup_router = NULL;
3253 if (server->id_entry != backup_router) {
3254 SILC_LOG_INFO(("New primary router is backup router %s",
3255 backup_router->server_name));
3256 server->id_entry->router = backup_router;
3257 server->router = backup_router;
3258 server->router_connect = time(0);
3259 server->backup_primary = TRUE;
3260 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3262 /* Send START_USE to backup router to indicate we have switched */
3263 silc_server_backup_send_start_use(server,
3264 backup_router->connection,
3267 SILC_LOG_INFO(("We are now new primary router in this cell"));
3268 server->id_entry->router = NULL;
3269 server->router = NULL;
3270 server->standalone = TRUE;
3273 /* We stop here to take a breath */
3276 if (server->backup_router) {
3277 server->server_type = SILC_ROUTER;
3279 /* We'll need to constantly try to reconnect to the primary
3280 router so that we'll see when it comes back online. */
3281 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3282 silc_server_backup_connected,
3286 /* Mark this connection as replaced */
3287 silc_server_backup_replaced_add(server, user_data->id,
3290 } else if (backup_router) {
3291 SILC_LOG_INFO(("Enabling the use of backup router %s",
3292 backup_router->server_name));
3294 /* Mark this connection as replaced */
3295 silc_server_backup_replaced_add(server, user_data->id,
3297 } else if (server->server_type == SILC_SERVER &&
3298 idata->conn_type == SILC_CONN_ROUTER) {
3299 /* Reconnect to the router (backup) */
3300 if (!server->no_reconnect)
3301 silc_server_create_connections(server);
3304 if (user_data->server_name)
3305 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3306 ("Server %s signoff", user_data->server_name));
3308 if (!backup_router) {
3309 /* Remove all servers that are originated from this server, and
3310 remove the clients of those servers too. */
3311 silc_server_remove_servers_by_server(server, user_data, TRUE);
3314 /* Remove the clients that this server owns as they will become
3315 invalid now too. For backup router the server is actually
3316 coming from the primary router, so mark that as the owner
3318 if (server->server_type == SILC_BACKUP_ROUTER &&
3319 sock->type == SILC_CONN_SERVER)
3320 silc_server_remove_clients_by_server(server, server->router,
3324 silc_server_remove_clients_by_server(server, user_data,
3327 /* Remove channels owned by this server */
3328 if (server->server_type == SILC_SERVER)
3329 silc_server_remove_channels_by_server(server, user_data);
3331 /* Enable local server connections that may be disabled */
3332 silc_server_local_servers_toggle_enabled(server, TRUE);
3334 /* Update the client entries of this server to the new backup
3335 router. If we are the backup router we also resolve the real
3336 servers for the clients. After updating is over this also
3337 removes the clients that this server explicitly owns. */
3338 silc_server_update_clients_by_server(server, user_data,
3339 backup_router, TRUE);
3341 /* If we are router and just lost our primary router (now standlaone)
3342 we remove everything that was behind it, since we don't know
3344 if (server->server_type == SILC_ROUTER && server->standalone)
3345 /* Remove all servers that are originated from this server, and
3346 remove the clients of those servers too. */
3347 silc_server_remove_servers_by_server(server, user_data, TRUE);
3349 /* Finally remove the clients that are explicitly owned by this
3350 server. They go down with the server. */
3351 silc_server_remove_clients_by_server(server, user_data,
3354 /* Update our server cache to use the new backup router too. */
3355 silc_server_update_servers_by_server(server, user_data, backup_router);
3356 if (server->server_type == SILC_SERVER)
3357 silc_server_update_channels_by_server(server, user_data,
3360 /* Send notify about primary router going down to local operators */
3361 if (server->backup_router)
3362 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3363 SILC_NOTIFY_TYPE_NONE,
3364 ("%s switched to backup router %s "
3365 "(we are primary router now)",
3366 server->server_name, server->server_name));
3367 else if (server->router)
3368 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3369 SILC_NOTIFY_TYPE_NONE,
3370 ("%s switched to backup router %s",
3371 server->server_name,
3372 server->router->server_name));
3374 server->backup_noswitch = FALSE;
3377 silc_server_connection_free(idata->sconn);
3378 idata->sconn = NULL;
3382 if (idata->conn_type == SILC_CONN_SERVER) {
3383 server->stat.my_servers--;
3384 server->stat.servers--;
3385 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3386 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3387 server->stat.my_routers--;
3388 server->stat.routers--;
3389 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3391 if (server->server_type == SILC_ROUTER)
3392 server->stat.cell_servers--;
3394 /* Free the server entry */
3395 silc_server_backup_del(server, user_data);
3396 silc_server_backup_replaced_del(server, user_data);
3397 silc_idlist_del_data(user_data);
3398 if (!silc_idlist_del_server(server->local_list, user_data))
3399 silc_idlist_del_server(server->global_list, user_data);
3401 if (backup_router && backup_router != server->id_entry) {
3402 /* Announce all of our stuff that was created about 5 minutes ago.
3403 The backup router knows all the other stuff already. */
3404 if (server->server_type == SILC_ROUTER)
3405 silc_server_announce_servers(server, FALSE, time(0) - 300,
3406 backup_router->connection);
3408 /* Announce our clients and channels to the router */
3409 silc_server_announce_clients(server, time(0) - 300,
3410 backup_router->connection);
3411 silc_server_announce_channels(server, time(0) - 300,
3412 backup_router->connection);
3415 silc_packet_set_context(sock, NULL);
3421 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3423 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3426 if (server->router_conn == idata->sconn) {
3427 if (!server->no_reconnect)
3428 silc_server_create_connections(server);
3429 server->router_conn = NULL;
3432 silc_server_connection_free(idata->sconn);
3433 idata->sconn = NULL;
3435 silc_idlist_del_data(idata);
3437 silc_packet_set_context(sock, NULL);
3443 /* Removes client from all channels it has joined. This is used when client
3444 connection is disconnected. If the client on a channel is last, the
3445 channel is removed as well. This sends the SIGNOFF notify types. */
3447 void silc_server_remove_from_channels(SilcServer server,
3448 SilcPacketStream sock,
3449 SilcClientEntry client,
3451 const char *signoff_message,
3455 SilcChannelEntry channel;
3456 SilcChannelClientEntry chl;
3457 SilcHashTableList htl;
3458 SilcBuffer clidp = NULL;
3463 if (notify && !client->id)
3466 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3467 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3470 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3475 /* Remove the client from all channels. The client is removed from
3476 the channels' user list. */
3477 silc_hash_table_list(client->channels, &htl);
3478 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3479 channel = chl->channel;
3481 /* Remove channel if this is last client leaving the channel, unless
3482 the channel is permanent. */
3483 if (server->server_type != SILC_SERVER &&
3484 silc_hash_table_count(channel->user_list) < 2) {
3485 silc_server_channel_delete(server, channel);
3489 silc_hash_table_del(client->channels, channel);
3490 silc_hash_table_del(channel->user_list, client);
3491 channel->user_count--;
3493 /* If there is no global users on the channel anymore mark the channel
3494 as local channel. Do not check if the removed client is local client. */
3495 if (server->server_type == SILC_SERVER && channel->global_users &&
3496 chl->client->router && !silc_server_channel_has_global(channel))
3497 channel->global_users = FALSE;
3499 memset(chl, 'A', sizeof(*chl));
3502 /* Update statistics */
3503 if (SILC_IS_LOCAL(client))
3504 server->stat.my_chanclients--;
3505 if (server->server_type == SILC_ROUTER) {
3506 server->stat.cell_chanclients--;
3507 server->stat.chanclients--;
3510 /* If there is not at least one local user on the channel then we don't
3511 need the channel entry anymore, we can remove it safely, unless the
3512 channel is permanent channel */
3513 if (server->server_type == SILC_SERVER &&
3514 !silc_server_channel_has_local(channel)) {
3515 /* Notify about leaving client if this channel has global users. */
3516 if (notify && channel->global_users)
3517 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3518 SILC_NOTIFY_TYPE_SIGNOFF,
3519 signoff_message ? 2 : 1,
3520 clidp->data, silc_buffer_len(clidp),
3521 signoff_message, signoff_message ?
3522 strlen(signoff_message) : 0);
3524 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3525 silc_server_channel_delete(server, channel);
3529 /* Send notify to channel about client leaving SILC and channel too */
3531 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3532 SILC_NOTIFY_TYPE_SIGNOFF,
3533 signoff_message ? 2 : 1,
3534 clidp->data, silc_buffer_len(clidp),
3535 signoff_message, signoff_message ?
3536 strlen(signoff_message) : 0);
3538 if (killed && clidp) {
3539 /* Remove the client from channel's invite list */
3540 if (channel->invite_list &&
3541 silc_hash_table_count(channel->invite_list)) {
3543 SilcArgumentPayload iargs;
3544 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3545 silc_buffer_len(clidp), 3);
3546 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3547 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3548 silc_buffer_free(ab);
3549 silc_argument_payload_free(iargs);
3553 /* Don't create keys if we are shutting down */
3554 if (server->server_shutdown)
3557 /* Re-generate channel key if needed */
3558 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3559 if (!silc_server_create_channel_key(server, channel, 0))
3562 /* Send the channel key to the channel. The key of course is not sent
3563 to the client who was removed from the channel. */
3564 silc_server_send_channel_key(server, client->connection, channel,
3565 server->server_type == SILC_ROUTER ?
3566 FALSE : !server->standalone);
3570 silc_hash_table_list_reset(&htl);
3572 silc_buffer_free(clidp);
3575 /* Removes client from one channel. This is used for example when client
3576 calls LEAVE command to remove itself from the channel. Returns TRUE
3577 if channel still exists and FALSE if the channel is removed when
3578 last client leaves the channel. If `notify' is FALSE notify messages
3581 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3582 SilcPacketStream sock,
3583 SilcChannelEntry channel,
3584 SilcClientEntry client,
3587 SilcChannelClientEntry chl;
3590 SILC_LOG_DEBUG(("Removing %s from channel %s",
3591 silc_id_render(client->id, SILC_ID_CLIENT),
3592 channel->channel_name));
3594 /* Get the entry to the channel, if this client is not on the channel
3596 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3599 /* Remove channel if this is last client leaving the channel, unless
3600 the channel is permanent. */
3601 if (server->server_type != SILC_SERVER &&
3602 silc_hash_table_count(channel->user_list) < 2) {
3603 silc_server_channel_delete(server, channel);
3607 silc_hash_table_del(client->channels, channel);
3608 silc_hash_table_del(channel->user_list, client);
3609 channel->user_count--;
3611 /* If there is no global users on the channel anymore mark the channel
3612 as local channel. Do not check if the client is local client. */
3613 if (server->server_type == SILC_SERVER && channel->global_users &&
3614 chl->client->router && !silc_server_channel_has_global(channel))
3615 channel->global_users = FALSE;
3617 memset(chl, 'O', sizeof(*chl));
3620 /* Update statistics */
3621 if (SILC_IS_LOCAL(client))
3622 server->stat.my_chanclients--;
3623 if (server->server_type == SILC_ROUTER) {
3624 server->stat.cell_chanclients--;
3625 server->stat.chanclients--;
3628 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3632 /* If there is not at least one local user on the channel then we don't
3633 need the channel entry anymore, we can remove it safely, unless the
3634 channel is permanent channel */
3635 if (server->server_type == SILC_SERVER &&
3636 !silc_server_channel_has_local(channel)) {
3637 /* Notify about leaving client if this channel has global users. */
3638 if (notify && channel->global_users)
3639 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3640 SILC_NOTIFY_TYPE_LEAVE, 1,
3641 clidp->data, silc_buffer_len(clidp));
3643 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3644 silc_server_channel_delete(server, channel);
3645 silc_buffer_free(clidp);
3649 /* Send notify to channel about client leaving the channel */
3651 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3652 SILC_NOTIFY_TYPE_LEAVE, 1,
3653 clidp->data, silc_buffer_len(clidp));
3655 silc_buffer_free(clidp);
3659 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3660 function may be used only by router. In real SILC network all channels
3661 are created by routers thus this function is never used by normal
3664 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3665 SilcServerID *router_id,
3671 SilcChannelID *channel_id;
3672 SilcChannelEntry entry;
3673 SilcCipher send_key, receive_key;
3676 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3679 cipher = SILC_DEFAULT_CIPHER;
3681 hmac = SILC_DEFAULT_HMAC;
3683 /* Allocate cipher */
3684 if (!silc_cipher_alloc(cipher, &send_key))
3686 if (!silc_cipher_alloc(cipher, &receive_key)) {
3687 silc_cipher_free(send_key);
3692 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3693 silc_cipher_free(send_key);
3694 silc_cipher_free(receive_key);
3698 channel_name = strdup(channel_name);
3700 /* Create the channel ID */
3701 if (!silc_id_create_channel_id(server, router_id, server->rng,
3703 silc_free(channel_name);
3704 silc_cipher_free(send_key);
3705 silc_cipher_free(receive_key);
3706 silc_hmac_free(newhmac);
3710 /* Create the channel */
3711 entry = silc_idlist_add_channel(server->local_list, channel_name,
3712 SILC_CHANNEL_MODE_NONE, channel_id,
3713 NULL, send_key, receive_key, newhmac);
3715 silc_free(channel_name);
3716 silc_cipher_free(send_key);
3717 silc_cipher_free(receive_key);
3718 silc_hmac_free(newhmac);
3719 silc_free(channel_id);
3723 entry->cipher = strdup(cipher);
3724 entry->hmac_name = strdup(hmac);
3726 /* Now create the actual key material */
3727 if (!silc_server_create_channel_key(server, entry,
3728 silc_cipher_get_key_len(send_key) / 8)) {
3729 silc_idlist_del_channel(server->local_list, entry);
3733 /* Notify other routers about the new channel. We send the packet
3734 to our primary route. */
3736 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3737 channel_name, entry->id,
3738 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3741 /* Distribute to backup routers */
3742 if (broadcast && server->server_type == SILC_ROUTER) {
3744 unsigned char cid[32];
3745 SilcUInt32 name_len = strlen(channel_name);
3748 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3749 packet = silc_channel_payload_encode(channel_name, name_len,
3750 cid, id_len, entry->mode);
3751 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3752 packet->data, silc_buffer_len(packet), FALSE,
3754 silc_buffer_free(packet);
3757 server->stat.my_channels++;
3758 if (server->server_type == SILC_ROUTER) {
3759 server->stat.channels++;
3760 server->stat.cell_channels++;
3761 entry->users_resolved = TRUE;
3767 /* Same as above but creates the channel with Channel ID `channel_id. */
3770 silc_server_create_new_channel_with_id(SilcServer server,
3774 SilcChannelID *channel_id,
3777 SilcChannelEntry entry;
3778 SilcCipher send_key, receive_key;
3781 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3784 cipher = SILC_DEFAULT_CIPHER;
3786 hmac = SILC_DEFAULT_HMAC;
3788 /* Allocate cipher */
3789 if (!silc_cipher_alloc(cipher, &send_key))
3791 if (!silc_cipher_alloc(cipher, &receive_key)) {
3792 silc_cipher_free(send_key);
3797 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3798 silc_cipher_free(send_key);
3799 silc_cipher_free(receive_key);
3803 channel_name = strdup(channel_name);
3805 /* Create the channel */
3806 entry = silc_idlist_add_channel(server->local_list, channel_name,
3807 SILC_CHANNEL_MODE_NONE, channel_id,
3808 NULL, send_key, receive_key, newhmac);
3810 silc_cipher_free(send_key);
3811 silc_cipher_free(receive_key);
3812 silc_hmac_free(newhmac);
3813 silc_free(channel_name);
3817 /* Now create the actual key material */
3818 if (!silc_server_create_channel_key(server, entry,
3819 silc_cipher_get_key_len(send_key) / 8)) {
3820 silc_idlist_del_channel(server->local_list, entry);
3824 /* Notify other routers about the new channel. We send the packet
3825 to our primary route. */
3827 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3828 channel_name, entry->id,
3829 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3832 /* Distribute to backup routers */
3833 if (broadcast && server->server_type == SILC_ROUTER) {
3835 unsigned char cid[32];
3836 SilcUInt32 name_len = strlen(channel_name);
3839 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3840 packet = silc_channel_payload_encode(channel_name, name_len,
3841 cid, id_len, entry->mode);
3842 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3843 packet->data, silc_buffer_len(packet), FALSE,
3845 silc_buffer_free(packet);
3848 server->stat.my_channels++;
3849 if (server->server_type == SILC_ROUTER) {
3850 server->stat.channels++;
3851 server->stat.cell_channels++;
3852 entry->users_resolved = TRUE;
3858 /* Channel's key re-key timeout callback. */
3860 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3862 SilcServer server = app_context;
3863 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3867 /* Return now if we are shutting down */
3868 if (server->server_shutdown)
3871 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3874 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3877 /* Generates new channel key. This is used to create the initial channel key
3878 but also to re-generate new key for channel. If `key_len' is provided
3879 it is the bytes of the key length. */
3881 SilcBool silc_server_create_channel_key(SilcServer server,
3882 SilcChannelEntry channel,
3886 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3889 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3890 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3894 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3896 if (!channel->send_key)
3897 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3898 channel->send_key = NULL;
3901 if (!channel->receive_key)
3902 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3903 silc_cipher_free(channel->send_key);
3904 channel->send_key = channel->receive_key = NULL;
3910 else if (channel->key_len)
3911 len = channel->key_len / 8;
3913 len = silc_cipher_get_key_len(channel->send_key) / 8;
3915 /* Create channel key */
3916 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3919 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3920 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3922 /* Remove old key if exists */
3924 memset(channel->key, 0, channel->key_len / 8);
3925 silc_free(channel->key);
3929 channel->key_len = len * 8;
3930 channel->key = silc_memdup(channel_key, len);
3931 memset(channel_key, 0, sizeof(channel_key));
3933 /* Generate HMAC key from the channel key data and set it */
3935 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3936 memset(channel->key, 0, channel->key_len / 8);
3937 silc_free(channel->key);
3938 silc_cipher_free(channel->send_key);
3939 silc_cipher_free(channel->receive_key);
3940 channel->send_key = channel->receive_key = NULL;
3943 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3944 silc_hmac_set_key(channel->hmac, hash,
3945 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3946 memset(hash, 0, sizeof(hash));
3948 if (server->server_type == SILC_ROUTER) {
3949 if (!channel->rekey)
3950 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3951 channel->rekey->channel = channel;
3952 channel->rekey->key_len = key_len;
3953 if (channel->rekey->task)
3954 silc_schedule_task_del(server->schedule, channel->rekey->task);
3956 channel->rekey->task =
3957 silc_schedule_task_add_timeout(server->schedule,
3958 silc_server_channel_key_rekey,
3959 (void *)channel->rekey,
3960 server->config->channel_rekey_secs, 0);
3966 /* Saves the channel key found in the encoded `key_payload' buffer. This
3967 function is used when we receive Channel Key Payload and also when we're
3968 processing JOIN command reply. Returns entry to the channel. */
3970 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3971 SilcBuffer key_payload,
3972 SilcChannelEntry channel)
3974 SilcChannelKeyPayload payload = NULL;
3976 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3980 /* Decode channel key payload */
3981 payload = silc_channel_key_payload_parse(key_payload->data,
3982 silc_buffer_len(key_payload));
3984 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3989 /* Get the channel entry */
3992 /* Get channel ID */
3993 tmp = silc_channel_key_get_id(payload, &tmp_len);
3994 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3999 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4001 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4003 if (server->server_type == SILC_ROUTER)
4004 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4005 silc_id_render(&id, SILC_ID_CHANNEL)));
4011 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4013 tmp = silc_channel_key_get_key(payload, &tmp_len);
4019 cipher = silc_channel_key_get_cipher(payload, NULL);
4025 /* Remove old key if exists */
4027 memset(channel->key, 0, channel->key_len / 8);
4028 silc_free(channel->key);
4029 silc_cipher_free(channel->send_key);
4030 silc_cipher_free(channel->receive_key);
4033 /* Create new cipher */
4034 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4035 channel->send_key = NULL;
4039 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4040 silc_cipher_free(channel->send_key);
4041 channel->send_key = channel->receive_key = NULL;
4046 if (channel->cipher)
4047 silc_free(channel->cipher);
4048 channel->cipher = strdup(cipher);
4051 channel->key_len = tmp_len * 8;
4052 channel->key = silc_memdup(tmp, tmp_len);
4053 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4054 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4056 /* Generate HMAC key from the channel key data and set it */
4058 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
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);
4063 channel->send_key = channel->receive_key = NULL;
4066 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4067 silc_hmac_set_key(channel->hmac, hash,
4068 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4070 memset(hash, 0, sizeof(hash));
4071 memset(tmp, 0, tmp_len);
4073 if (server->server_type == SILC_ROUTER) {
4074 if (!channel->rekey)
4075 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4076 channel->rekey->channel = channel;
4077 if (channel->rekey->task)
4078 silc_schedule_task_del(server->schedule, channel->rekey->task);
4080 channel->rekey->task =
4081 silc_schedule_task_add_timeout(server->schedule,
4082 silc_server_channel_key_rekey,
4083 (void *)channel->rekey,
4084 server->config->channel_rekey_secs, 0);
4089 silc_channel_key_payload_free(payload);
4094 /* Returns assembled of all servers in the given ID list. The packet's
4095 form is dictated by the New ID payload. */
4097 static void silc_server_announce_get_servers(SilcServer server,
4098 SilcServerEntry remote,
4100 SilcBuffer *servers,
4101 unsigned long creation_time)
4104 SilcIDCacheEntry id_cache;
4105 SilcServerEntry entry;
4109 /* Go through all clients in the list */
4110 if (silc_idcache_get_all(id_list->servers, &list)) {
4111 silc_list_start(list);
4112 while ((id_cache = silc_list_get(list))) {
4113 entry = (SilcServerEntry)id_cache->context;
4115 /* Do not announce the one we've sending our announcements and
4116 do not announce ourself. Also check the creation time if it's
4118 if ((entry == remote) || (entry == server->id_entry) ||
4119 (creation_time && entry->data.created < creation_time))
4122 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4124 tmp = silc_buffer_realloc(*servers,
4126 silc_buffer_truelen((*servers)) +
4127 silc_buffer_len(idp) :
4128 silc_buffer_len(idp)));
4132 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4133 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4134 silc_buffer_pull(*servers, silc_buffer_len(idp));
4135 silc_buffer_free(idp);
4141 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4147 p = silc_notify_payload_encode(notify, argc, ap);
4153 /* This function is used by router to announce existing servers to our
4154 primary router when we've connected to it. If `creation_time' is non-zero
4155 then only the servers that has been created after the `creation_time'
4156 will be announced. */
4158 void silc_server_announce_servers(SilcServer server, SilcBool global,
4159 unsigned long creation_time,
4160 SilcPacketStream remote)
4162 SilcBuffer servers = NULL;
4164 SILC_LOG_DEBUG(("Announcing servers"));
4166 /* Get servers in local list */
4167 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4168 server->local_list, &servers,
4172 /* Get servers in global list */
4173 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4174 server->global_list, &servers,
4178 silc_buffer_push(servers, servers->data - servers->head);
4179 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4181 /* Send the packet */
4182 silc_server_packet_send(server, remote,
4183 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4184 servers->data, silc_buffer_len(servers));
4186 silc_buffer_free(servers);
4190 /* Returns assembled packet of all clients in the given ID list. The
4191 packet's form is dictated by the New ID Payload. */
4193 static void silc_server_announce_get_clients(SilcServer server,
4195 SilcBuffer *clients,
4197 unsigned long creation_time)
4200 SilcIDCacheEntry id_cache;
4201 SilcClientEntry client;
4204 unsigned char mode[4];
4207 /* Go through all clients in the list */
4208 if (silc_idcache_get_all(id_list->clients, &list)) {
4209 silc_list_start(list);
4210 while ((id_cache = silc_list_get(list))) {
4211 client = (SilcClientEntry)id_cache->context;
4213 if (creation_time && client->data.created < creation_time)
4215 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4217 if (!client->connection && !client->router)
4220 SILC_LOG_DEBUG(("Announce Client ID %s",
4221 silc_id_render(client->id, SILC_ID_CLIENT)));
4223 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4227 tmp2 = silc_buffer_realloc(*clients,
4229 silc_buffer_truelen((*clients)) +
4230 silc_buffer_len(idp) :
4231 silc_buffer_len(idp)));
4235 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4236 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4237 silc_buffer_pull(*clients, silc_buffer_len(idp));
4239 SILC_PUT32_MSB(client->mode, mode);
4241 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4242 2, idp->data, silc_buffer_len(idp),
4244 tmp2 = silc_buffer_realloc(*umodes,
4246 silc_buffer_truelen((*umodes)) +
4247 silc_buffer_len(tmp) :
4248 silc_buffer_len(tmp)));
4252 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4253 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4254 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4255 silc_buffer_free(tmp);
4257 silc_buffer_free(idp);
4262 /* This function is used to announce our existing clients to our router
4263 when we've connected to it. If `creation_time' is non-zero then only
4264 the clients that has been created after the `creation_time' will be
4267 void silc_server_announce_clients(SilcServer server,
4268 unsigned long creation_time,
4269 SilcPacketStream remote)
4271 SilcBuffer clients = NULL;
4272 SilcBuffer umodes = NULL;
4274 SILC_LOG_DEBUG(("Announcing clients"));
4276 /* Get clients in local list */
4277 silc_server_announce_get_clients(server, server->local_list,
4278 &clients, &umodes, creation_time);
4280 /* As router we announce our global list as well */
4281 if (server->server_type == SILC_ROUTER)
4282 silc_server_announce_get_clients(server, server->global_list,
4283 &clients, &umodes, creation_time);
4286 silc_buffer_push(clients, clients->data - clients->head);
4287 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4289 /* Send the packet */
4290 silc_server_packet_send(server, remote,
4291 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4292 clients->data, silc_buffer_len(clients));
4294 silc_buffer_free(clients);
4298 silc_buffer_push(umodes, umodes->data - umodes->head);
4299 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4301 /* Send the packet */
4302 silc_server_packet_send(server, remote,
4303 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4304 umodes->data, silc_buffer_len(umodes));
4306 silc_buffer_free(umodes);
4310 /* Returns channel's topic for announcing it */
4312 void silc_server_announce_get_channel_topic(SilcServer server,
4313 SilcChannelEntry channel,
4318 if (channel->topic) {
4319 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4320 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4322 silc_buffer_len(chidp),
4324 strlen(channel->topic));
4325 silc_buffer_free(chidp);
4329 /* Returns channel's invite and ban lists */
4331 void silc_server_announce_get_inviteban(SilcServer server,
4332 SilcChannelEntry channel,
4336 SilcBuffer list, idp, idp2, tmp2;
4339 SilcHashTableList htl;
4340 const unsigned char a[1] = { 0x03 };
4342 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4344 /* Encode invite list */
4345 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4346 list = silc_buffer_alloc_size(2);
4347 type = silc_hash_table_count(channel->invite_list);
4348 SILC_PUT16_MSB(type, list->data);
4349 silc_hash_table_list(channel->invite_list, &htl);
4350 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4351 list = silc_argument_payload_encode_one(list, tmp2->data,
4352 silc_buffer_len(tmp2),
4353 SILC_PTR_TO_32(ptype));
4354 silc_hash_table_list_reset(&htl);
4356 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4358 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4359 idp->data, silc_buffer_len(idp),
4360 channel->channel_name,
4361 strlen(channel->channel_name),
4362 idp2->data, silc_buffer_len(idp2),
4364 list->data, silc_buffer_len(list));
4365 silc_buffer_free(idp2);
4366 silc_buffer_free(list);
4369 /* Encode ban list */
4370 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4371 list = silc_buffer_alloc_size(2);
4372 type = silc_hash_table_count(channel->ban_list);
4373 SILC_PUT16_MSB(type, list->data);
4374 silc_hash_table_list(channel->ban_list, &htl);
4375 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4376 list = silc_argument_payload_encode_one(list, tmp2->data,
4377 silc_buffer_len(tmp2),
4378 SILC_PTR_TO_32(ptype));
4379 silc_hash_table_list_reset(&htl);
4382 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4383 idp->data, silc_buffer_len(idp),
4385 list->data, silc_buffer_len(list));
4386 silc_buffer_free(list);
4389 silc_buffer_free(idp);
4392 /* Returns assembled packets for channel users of the `channel'. */
4394 void silc_server_announce_get_channel_users(SilcServer server,
4395 SilcChannelEntry channel,
4396 SilcBuffer *channel_modes,
4397 SilcBuffer *channel_users,
4398 SilcBuffer *channel_users_modes)
4400 SilcChannelClientEntry chl;
4401 SilcHashTableList htl;
4402 SilcBuffer chidp, clidp, csidp;
4403 SilcBuffer tmp, fkey = NULL, chpklist;
4405 unsigned char mode[4], ulimit[4];
4409 SILC_LOG_DEBUG(("Start"));
4411 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4412 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4413 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4416 SILC_PUT32_MSB(channel->mode, mode);
4417 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4418 SILC_PUT32_MSB(channel->user_limit, ulimit);
4419 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4420 if (channel->founder_key)
4421 fkey = silc_public_key_payload_encode(channel->founder_key);
4423 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4425 silc_buffer_len(csidp),
4428 hmac, hmac ? strlen(hmac) : 0,
4429 channel->passphrase,
4430 channel->passphrase ?
4431 strlen(channel->passphrase) : 0,
4432 fkey ? fkey->data : NULL,
4433 fkey ? silc_buffer_len(fkey) : 0,
4434 chpklist ? chpklist->data : NULL,
4436 silc_buffer_len(chpklist) : 0,
4438 SILC_CHANNEL_MODE_ULIMIT ?
4441 SILC_CHANNEL_MODE_ULIMIT ?
4442 sizeof(ulimit) : 0));
4443 len = silc_buffer_len(tmp);
4445 silc_buffer_realloc(*channel_modes,
4447 silc_buffer_truelen((*channel_modes)) + len : len));
4450 *channel_modes = tmp2;
4451 silc_buffer_pull_tail(*channel_modes,
4452 ((*channel_modes)->end -
4453 (*channel_modes)->data));
4454 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4455 silc_buffer_pull(*channel_modes, len);
4456 silc_buffer_free(tmp);
4457 silc_buffer_free(fkey);
4460 /* Now find all users on the channel */
4461 silc_hash_table_list(channel->user_list, &htl);
4462 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4463 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4465 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4469 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4471 silc_buffer_len(clidp),
4473 silc_buffer_len(chidp));
4474 len = silc_buffer_len(tmp);
4476 silc_buffer_realloc(*channel_users,
4478 silc_buffer_truelen((*channel_users)) + len : len));
4481 *channel_users = tmp2;
4482 silc_buffer_pull_tail(*channel_users,
4483 ((*channel_users)->end -
4484 (*channel_users)->data));
4486 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4487 silc_buffer_pull(*channel_users, len);
4488 silc_buffer_free(tmp);
4490 /* CUMODE notify for mode change on the channel */
4491 SILC_PUT32_MSB(chl->mode, mode);
4492 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4493 fkey = silc_public_key_payload_encode(channel->founder_key);
4494 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4496 silc_buffer_len(csidp),
4499 silc_buffer_len(clidp),
4500 fkey ? fkey->data : NULL,
4501 fkey ? silc_buffer_len(fkey) : 0);
4502 len = silc_buffer_len(tmp);
4504 silc_buffer_realloc(*channel_users_modes,
4505 (*channel_users_modes ?
4506 silc_buffer_truelen((*channel_users_modes)) +
4510 *channel_users_modes = tmp2;
4511 silc_buffer_pull_tail(*channel_users_modes,
4512 ((*channel_users_modes)->end -
4513 (*channel_users_modes)->data));
4515 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4516 silc_buffer_pull(*channel_users_modes, len);
4517 silc_buffer_free(tmp);
4518 silc_buffer_free(fkey);
4520 silc_buffer_free(clidp);
4522 silc_hash_table_list_reset(&htl);
4523 silc_buffer_free(chidp);
4524 silc_buffer_free(csidp);
4527 /* Returns assembled packets for all channels and users on those channels
4528 from the given ID List. The packets are in the form dictated by the
4529 New Channel and New Channel User payloads. */
4531 void silc_server_announce_get_channels(SilcServer server,
4533 SilcBuffer *channels,
4534 SilcBuffer **channel_modes,
4535 SilcBuffer *channel_users,
4536 SilcBuffer **channel_users_modes,
4537 SilcUInt32 *channel_users_modes_c,
4538 SilcBuffer **channel_topics,
4539 SilcBuffer **channel_invites,
4540 SilcBuffer **channel_bans,
4541 SilcChannelID ***channel_ids,
4542 unsigned long creation_time)
4545 SilcIDCacheEntry id_cache;
4546 SilcChannelEntry channel;
4547 unsigned char cid[32];
4549 SilcUInt16 name_len;
4551 int i = *channel_users_modes_c;
4555 SILC_LOG_DEBUG(("Start"));
4557 /* Go through all channels in the list */
4558 if (silc_idcache_get_all(id_list->channels, &list)) {
4559 silc_list_start(list);
4560 while ((id_cache = silc_list_get(list))) {
4561 channel = (SilcChannelEntry)id_cache->context;
4563 if (creation_time && channel->created < creation_time)
4568 SILC_LOG_DEBUG(("Announce Channel ID %s",
4569 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4571 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4572 name_len = strlen(channel->channel_name);
4575 len = 4 + name_len + id_len + 4;
4577 silc_buffer_realloc(*channels,
4579 silc_buffer_truelen((*channels)) +
4585 silc_buffer_pull_tail(*channels,
4586 ((*channels)->end - (*channels)->data));
4587 silc_buffer_format(*channels,
4588 SILC_STR_UI_SHORT(name_len),
4589 SILC_STR_UI_XNSTRING(channel->channel_name,
4591 SILC_STR_UI_SHORT(id_len),
4592 SILC_STR_UI_XNSTRING(cid, id_len),
4593 SILC_STR_UI_INT(channel->mode),
4595 silc_buffer_pull(*channels, len);
4598 if (creation_time && channel->updated < creation_time)
4604 /* Channel user modes */
4605 tmp = silc_realloc(*channel_users_modes,
4606 sizeof(**channel_users_modes) * (i + 1));
4609 *channel_users_modes = tmp;
4610 (*channel_users_modes)[i] = NULL;
4611 tmp = silc_realloc(*channel_modes,
4612 sizeof(**channel_modes) * (i + 1));
4615 *channel_modes = tmp;
4616 (*channel_modes)[i] = NULL;
4617 tmp = silc_realloc(*channel_ids,
4618 sizeof(**channel_ids) * (i + 1));
4622 (*channel_ids)[i] = NULL;
4623 silc_server_announce_get_channel_users(server, channel,
4624 &(*channel_modes)[i],
4626 &(*channel_users_modes)[i]);
4627 (*channel_ids)[i] = channel->id;
4629 /* Channel's topic */
4630 tmp = silc_realloc(*channel_topics,
4631 sizeof(**channel_topics) * (i + 1));
4634 *channel_topics = tmp;
4635 (*channel_topics)[i] = NULL;
4636 silc_server_announce_get_channel_topic(server, channel,
4637 &(*channel_topics)[i]);
4639 /* Channel's invite and ban list */
4640 tmp = silc_realloc(*channel_invites,
4641 sizeof(**channel_invites) * (i + 1));
4644 *channel_invites = tmp;
4645 (*channel_invites)[i] = NULL;
4646 tmp = silc_realloc(*channel_bans,
4647 sizeof(**channel_bans) * (i + 1));
4650 *channel_bans = tmp;
4651 (*channel_bans)[i] = NULL;
4652 silc_server_announce_get_inviteban(server, channel,
4653 &(*channel_invites)[i],
4654 &(*channel_bans)[i]);
4656 (*channel_users_modes_c)++;
4664 /* This function is used to announce our existing channels to our router
4665 when we've connected to it. This also announces the users on the
4666 channels to the router. If the `creation_time' is non-zero only the
4667 channels that was created after the `creation_time' are announced.
4668 Note that the channel users are still announced even if the `creation_time'
4671 void silc_server_announce_channels(SilcServer server,
4672 unsigned long creation_time,
4673 SilcPacketStream remote)
4675 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4676 SilcBuffer *channel_users_modes = NULL;
4677 SilcBuffer *channel_topics = NULL;
4678 SilcBuffer *channel_invites = NULL;
4679 SilcBuffer *channel_bans = NULL;
4680 SilcUInt32 channel_users_modes_c = 0;
4681 SilcChannelID **channel_ids = NULL;
4683 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4685 /* Get channels and channel users in local list */
4686 silc_server_announce_get_channels(server, server->local_list,
4687 &channels, &channel_modes,
4689 &channel_users_modes,
4690 &channel_users_modes_c,
4694 &channel_ids, creation_time);
4696 /* Get channels and channel users in global list */
4697 if (server->server_type != SILC_SERVER)
4698 silc_server_announce_get_channels(server, server->global_list,
4699 &channels, &channel_modes,
4701 &channel_users_modes,
4702 &channel_users_modes_c,
4706 &channel_ids, creation_time);
4709 silc_buffer_push(channels, channels->data - channels->head);
4710 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4712 /* Send the packet */
4713 silc_server_packet_send(server, remote,
4714 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4715 channels->data, silc_buffer_len(channels));
4717 silc_buffer_free(channels);
4720 if (channel_users) {
4721 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4722 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4723 silc_buffer_len(channel_users));
4725 /* Send the packet */
4726 silc_server_packet_send(server, remote,
4727 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4728 channel_users->data, silc_buffer_len(channel_users));
4730 silc_buffer_free(channel_users);
4733 if (channel_modes) {
4736 for (i = 0; i < channel_users_modes_c; i++) {
4737 if (!channel_modes[i])
4739 silc_buffer_push(channel_modes[i],
4740 channel_modes[i]->data -
4741 channel_modes[i]->head);
4742 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4743 silc_buffer_len(channel_modes[i]));
4744 silc_server_packet_send_dest(server, remote,
4745 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4746 channel_ids[i], SILC_ID_CHANNEL,
4747 channel_modes[i]->data,
4748 silc_buffer_len(channel_modes[i]));
4749 silc_buffer_free(channel_modes[i]);
4751 silc_free(channel_modes);
4754 if (channel_users_modes) {
4757 for (i = 0; i < channel_users_modes_c; i++) {
4758 if (!channel_users_modes[i])
4760 silc_buffer_push(channel_users_modes[i],
4761 channel_users_modes[i]->data -
4762 channel_users_modes[i]->head);
4763 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4764 silc_buffer_len(channel_users_modes[i]));
4765 silc_server_packet_send_dest(server, remote,
4766 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4767 channel_ids[i], SILC_ID_CHANNEL,
4768 channel_users_modes[i]->data,
4769 silc_buffer_len(channel_users_modes[i]));
4770 silc_buffer_free(channel_users_modes[i]);
4772 silc_free(channel_users_modes);
4775 if (channel_topics) {
4778 for (i = 0; i < channel_users_modes_c; i++) {
4779 if (!channel_topics[i])
4782 silc_buffer_push(channel_topics[i],
4783 channel_topics[i]->data -
4784 channel_topics[i]->head);
4785 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4786 silc_buffer_len(channel_topics[i]));
4787 silc_server_packet_send_dest(server, remote,
4788 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4789 channel_ids[i], SILC_ID_CHANNEL,
4790 channel_topics[i]->data,
4791 silc_buffer_len(channel_topics[i]));
4792 silc_buffer_free(channel_topics[i]);
4794 silc_free(channel_topics);
4797 if (channel_invites) {
4800 for (i = 0; i < channel_users_modes_c; i++) {
4801 if (!channel_invites[i])
4804 silc_buffer_push(channel_invites[i],
4805 channel_invites[i]->data -
4806 channel_invites[i]->head);
4807 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4808 silc_buffer_len(channel_invites[i]));
4809 silc_server_packet_send_dest(server, remote,
4810 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4811 channel_ids[i], SILC_ID_CHANNEL,
4812 channel_invites[i]->data,
4813 silc_buffer_len(channel_invites[i]));
4814 silc_buffer_free(channel_invites[i]);
4816 silc_free(channel_invites);
4822 for (i = 0; i < channel_users_modes_c; i++) {
4823 if (!channel_bans[i])
4826 silc_buffer_push(channel_bans[i],
4827 channel_bans[i]->data -
4828 channel_bans[i]->head);
4829 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4830 silc_buffer_len(channel_bans[i]));
4831 silc_server_packet_send_dest(server, remote,
4832 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4833 channel_ids[i], SILC_ID_CHANNEL,
4834 channel_bans[i]->data,
4835 silc_buffer_len(channel_bans[i]));
4836 silc_buffer_free(channel_bans[i]);
4838 silc_free(channel_bans);
4841 silc_free(channel_ids);
4844 /* Announces WATCH list. */
4846 void silc_server_announce_watches(SilcServer server,
4847 SilcPacketStream remote)
4849 SilcHashTableList htl;
4850 SilcBuffer buffer, idp, args, pkp;
4851 SilcClientEntry client;
4854 SILC_LOG_DEBUG(("Announcing watch list"));
4856 /* XXX because way we save the nicks (hash) we cannot announce them. */
4858 /* XXX we should send all public keys in one command if client is
4859 watching more than one key */
4860 silc_hash_table_list(server->watcher_list_pk, &htl);
4861 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4862 if (!client || !client->id)
4865 server->stat.commands_sent++;
4867 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4868 args = silc_buffer_alloc_size(2);
4869 silc_buffer_format(args,
4870 SILC_STR_UI_SHORT(1),
4872 pkp = silc_public_key_payload_encode(key);
4873 args = silc_argument_payload_encode_one(args, pkp->data,
4874 silc_buffer_len(pkp), 0x00);
4875 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4876 ++server->cmd_ident, 2,
4877 1, idp->data, silc_buffer_len(idp),
4879 silc_buffer_len(args));
4882 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4883 buffer->data, silc_buffer_len(buffer));
4885 silc_buffer_free(pkp);
4886 silc_buffer_free(args);
4887 silc_buffer_free(idp);
4888 silc_buffer_free(buffer);
4890 silc_hash_table_list_reset(&htl);
4893 /* Assembles user list and users mode list from the `channel'. */
4895 SilcBool silc_server_get_users_on_channel(SilcServer server,
4896 SilcChannelEntry channel,
4897 SilcBuffer *user_list,
4898 SilcBuffer *mode_list,
4899 SilcUInt32 *user_count)
4901 SilcChannelClientEntry chl;
4902 SilcHashTableList htl;
4903 SilcBuffer client_id_list;
4904 SilcBuffer client_mode_list;
4906 SilcUInt32 list_count = 0, len = 0;
4908 if (!silc_hash_table_count(channel->user_list))
4911 silc_hash_table_list(channel->user_list, &htl);
4912 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4913 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4914 silc_hash_table_list_reset(&htl);
4916 client_id_list = silc_buffer_alloc(len);
4918 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4919 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4920 silc_buffer_pull_tail(client_mode_list,
4921 silc_buffer_truelen(client_mode_list));
4923 silc_hash_table_list(channel->user_list, &htl);
4924 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4926 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4927 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4928 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4929 silc_buffer_free(idp);
4931 /* Client's mode on channel */
4932 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4933 silc_buffer_pull(client_mode_list, 4);
4937 silc_hash_table_list_reset(&htl);
4938 silc_buffer_push(client_id_list,
4939 client_id_list->data - client_id_list->head);
4940 silc_buffer_push(client_mode_list,
4941 client_mode_list->data - client_mode_list->head);
4943 *user_list = client_id_list;
4944 *mode_list = client_mode_list;
4945 *user_count = list_count;
4949 /* Saves users and their modes to the `channel'. */
4951 void silc_server_save_users_on_channel(SilcServer server,
4952 SilcPacketStream sock,
4953 SilcChannelEntry channel,
4954 SilcClientID *noadd,
4955 SilcBuffer user_list,
4956 SilcBuffer mode_list,
4957 SilcUInt32 user_count)
4963 SilcClientEntry client;
4964 SilcIDCacheEntry cache;
4965 SilcChannelClientEntry chl;
4967 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4968 channel->channel_name));
4970 for (i = 0; i < user_count; i++) {
4972 SILC_GET16_MSB(idp_len, user_list->data + 2);
4974 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4976 silc_buffer_pull(user_list, idp_len);
4979 SILC_GET32_MSB(mode, mode_list->data);
4980 silc_buffer_pull(mode_list, 4);
4982 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4987 /* Check if we have this client cached already. */
4988 client = silc_idlist_find_client_by_id(server->local_list,
4990 server->server_type, &cache);
4992 client = silc_idlist_find_client_by_id(server->global_list,
4994 server->server_type, &cache);
4996 /* If router did not find such Client ID in its lists then this must
4997 be bogus client or some router in the net is buggy. */
4998 if (server->server_type != SILC_SERVER)
5001 /* We don't have that client anywhere, add it. The client is added
5002 to global list since server didn't have it in the lists so it must be
5004 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5005 silc_id_dup(&id.u.client_id,
5007 silc_packet_get_context(sock),
5010 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5014 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5017 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5018 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5019 "%s", channel->channel_name));
5023 if (!silc_server_client_on_channel(client, channel, &chl)) {
5024 /* Client was not on the channel, add it. */
5025 chl = silc_calloc(1, sizeof(*chl));
5026 chl->client = client;
5028 chl->channel = channel;
5029 silc_hash_table_add(channel->user_list, chl->client, chl);
5030 silc_hash_table_add(client->channels, chl->channel, chl);
5031 channel->user_count++;
5039 /* Saves channels and channels user modes to the `client'. Removes
5040 the client from those channels that are not sent in the list but
5043 void silc_server_save_user_channels(SilcServer server,
5044 SilcPacketStream sock,
5045 SilcClientEntry client,
5046 SilcBuffer channels,
5047 SilcBuffer channels_user_modes)
5050 SilcUInt32 *chumodes;
5051 SilcChannelPayload entry;
5052 SilcChannelEntry channel;
5053 SilcChannelID channel_id;
5054 SilcChannelClientEntry chl;
5055 SilcHashTable ht = NULL;
5056 SilcHashTableList htl;
5060 if (!channels || !channels_user_modes ||
5061 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5064 ch = silc_channel_payload_parse_list(channels->data,
5065 silc_buffer_len(channels));
5066 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5068 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5069 NULL, NULL, NULL, TRUE);
5070 silc_dlist_start(ch);
5071 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5072 /* Check if we have this channel, and add it if we don't have it.
5073 Also add the client on the channel unless it is there already. */
5074 if (!silc_channel_get_id_parse(entry, &channel_id))
5076 channel = silc_idlist_find_channel_by_id(server->local_list,
5079 channel = silc_idlist_find_channel_by_id(server->global_list,
5082 if (server->server_type != SILC_SERVER) {
5087 /* We don't have that channel anywhere, add it. */
5088 name = silc_channel_get_name(entry, NULL);
5089 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5090 silc_id_dup(&channel_id,
5092 server->router, NULL, NULL, 0);
5099 channel->mode = silc_channel_get_mode(entry);
5101 /* Add the client on the channel */
5102 if (!silc_server_client_on_channel(client, channel, &chl)) {
5103 chl = silc_calloc(1, sizeof(*chl));
5104 chl->client = client;
5105 chl->mode = chumodes[i++];
5106 chl->channel = channel;
5107 silc_hash_table_add(channel->user_list, chl->client, chl);
5108 silc_hash_table_add(client->channels, chl->channel, chl);
5109 channel->user_count++;
5112 chl->mode = chumodes[i++];
5115 silc_hash_table_add(ht, channel, channel);
5117 silc_channel_payload_list_free(ch);
5118 silc_free(chumodes);
5122 /* Go through the list again and remove client from channels that
5123 are no part of the list. */
5125 silc_hash_table_list(client->channels, &htl);
5126 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5127 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5128 silc_hash_table_del(chl->channel->user_list, chl->client);
5129 silc_hash_table_del(chl->client->channels, chl->channel);
5133 silc_hash_table_list_reset(&htl);
5134 silc_hash_table_free(ht);
5136 silc_hash_table_list(client->channels, &htl);
5137 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5138 silc_hash_table_del(chl->channel->user_list, chl->client);
5139 silc_hash_table_del(chl->client->channels, chl->channel);
5142 silc_hash_table_list_reset(&htl);
5146 /* Lookups route to the client indicated by the `id_data'. The connection
5147 object and internal data object is returned. Returns NULL if route
5148 could not be found to the client. If the `client_id' is specified then
5149 it is used and the `id_data' is ignored. */
5152 silc_server_get_client_route(SilcServer server,
5153 unsigned char *id_data,
5155 SilcClientID *client_id,
5156 SilcIDListData *idata,
5157 SilcClientEntry *client_entry)
5159 SilcClientID *id, clid;
5160 SilcClientEntry client;
5162 SILC_LOG_DEBUG(("Start"));
5165 *client_entry = NULL;
5167 /* Decode destination Client ID */
5169 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5171 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5173 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5176 /* If the destination belongs to our server we don't have to route
5177 the packet anywhere but to send it to the local destination. */
5178 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5182 /* If we are router and the client has router then the client is in
5183 our cell but not directly connected to us. */
5184 if (server->server_type == SILC_ROUTER && client->router) {
5185 /* We are of course in this case the client's router thus the route
5186 to the client is the server who owns the client. So, we will send
5187 the packet to that server. */
5189 *idata = (SilcIDListData)client->router;
5190 return client->router->connection;
5193 /* Seems that client really is directly connected to us */
5195 *idata = (SilcIDListData)client;
5197 *client_entry = client;
5198 return client->connection;
5201 /* Destination belongs to someone not in this server. If we are normal
5202 server our action is to send the packet to our router. */
5203 if (server->server_type != SILC_ROUTER && !server->standalone) {
5206 *idata = (SilcIDListData)server->router;
5207 return SILC_PRIMARY_ROUTE(server);
5210 /* We are router and we will perform route lookup for the destination
5211 and send the packet to fastest route. */
5212 if (server->server_type == SILC_ROUTER && !server->standalone) {
5213 /* Check first that the ID is valid */
5214 client = silc_idlist_find_client_by_id(server->global_list, id,
5217 SilcPacketStream dst_sock;
5219 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5222 if (idata && dst_sock)
5223 *idata = silc_packet_get_context(dst_sock);
5232 /* Encodes and returns channel list of channels the `client' has joined.
5233 Secret channels are not put to the list. */
5235 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5236 SilcClientEntry client,
5237 SilcBool get_private,
5238 SilcBool get_secret,
5239 SilcBuffer *user_mode_list)
5241 SilcBuffer buffer = NULL;
5242 SilcChannelEntry channel;
5243 SilcChannelClientEntry chl;
5244 SilcHashTableList htl;
5245 unsigned char cid[32];
5247 SilcUInt16 name_len;
5251 *user_mode_list = NULL;
5253 silc_hash_table_list(client->channels, &htl);
5254 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5255 channel = chl->channel;
5257 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5259 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5262 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5263 name_len = strlen(channel->channel_name);
5265 len = 4 + name_len + id_len + 4;
5266 buffer = silc_buffer_realloc(buffer,
5268 silc_buffer_truelen(buffer) + len : len));
5269 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5270 silc_buffer_format(buffer,
5271 SILC_STR_UI_SHORT(name_len),
5272 SILC_STR_DATA(channel->channel_name, name_len),
5273 SILC_STR_UI_SHORT(id_len),
5274 SILC_STR_DATA(cid, id_len),
5275 SILC_STR_UI_INT(chl->channel->mode),
5277 silc_buffer_pull(buffer, len);
5279 if (user_mode_list) {
5281 silc_buffer_realloc(*user_mode_list,
5283 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5284 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5285 (*user_mode_list)->data));
5286 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5287 silc_buffer_pull(*user_mode_list, 4);
5290 silc_hash_table_list_reset(&htl);
5293 silc_buffer_push(buffer, buffer->data - buffer->head);
5294 if (user_mode_list && *user_mode_list)
5295 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5296 (*user_mode_list)->head));
5301 /* Task callback used to retrieve network statistical information from
5302 router server once in a while. */
5304 SILC_TASK_CALLBACK(silc_server_get_stats)
5306 SilcServer server = (SilcServer)context;
5307 SilcBuffer idp, packet;
5309 if (!server->standalone) {
5310 SILC_LOG_DEBUG(("Retrieving stats from router"));
5311 server->stat.commands_sent++;
5312 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5314 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5315 ++server->cmd_ident, 1,
5317 silc_buffer_len(idp));
5318 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5319 SILC_PACKET_COMMAND, 0, packet->data,
5320 silc_buffer_len(packet));
5321 silc_buffer_free(packet);
5322 silc_buffer_free(idp);
5326 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,