5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /************************* Types and definitions ****************************/
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
28 SILC_TASK_CALLBACK(silc_server_do_rekey);
29 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
30 static void silc_server_accept_new_connection(SilcNetStatus status,
33 static void silc_server_packet_parse_type(SilcServer server,
34 SilcPacketStream sock,
36 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
40 /************************ Static utility functions **************************/
42 /* SKE public key verification callback */
45 silc_server_verify_key(SilcSKE ske,
46 SilcPublicKey public_key,
48 SilcSKEVerifyCbCompletion completion,
49 void *completion_context)
51 SilcPacketStream sock = context;
52 SilcUnknownEntry entry = silc_packet_get_context(sock);
54 SILC_LOG_DEBUG(("Verifying public key"));
56 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
57 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
58 entry->hostname, entry->ip, entry->port,
59 silc_pkcs_get_type(public_key)));
60 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
65 /* We accept all keys without explicit verification */
66 completion(ske, SILC_SKE_STATUS_OK, completion_context);
70 /************************ Packet engine callbacks ***************************/
72 /* Packet engine callback to receive a packet */
74 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
75 SilcPacketStream stream,
77 void *callback_context,
80 SilcServer server = callback_context;
81 SilcIDListData idata = stream_context;
86 /* Packets we do not handle */
87 switch (packet->type) {
88 case SILC_PACKET_HEARTBEAT:
89 case SILC_PACKET_SUCCESS:
90 case SILC_PACKET_FAILURE:
91 case SILC_PACKET_REJECT:
92 case SILC_PACKET_KEY_EXCHANGE:
93 case SILC_PACKET_KEY_EXCHANGE_1:
94 case SILC_PACKET_KEY_EXCHANGE_2:
95 case SILC_PACKET_REKEY_DONE:
96 case SILC_PACKET_CONNECTION_AUTH:
101 /* Only specific packets can come without source ID present. */
102 if ((!packet->src_id ||
103 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
104 packet->type != SILC_PACKET_NEW_CLIENT &&
105 packet->type != SILC_PACKET_NEW_SERVER &&
106 packet->type != SILC_PACKET_RESUME_CLIENT &&
107 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
108 packet->type != SILC_PACKET_DISCONNECT)
111 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and
112 for unregistered connection. */
113 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
114 packet->type == SILC_PACKET_NEW_SERVER) &&
115 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
118 /* Ignore packets from disabled connection */
119 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
120 packet->type != SILC_PACKET_HEARTBEAT &&
121 packet->type != SILC_PACKET_RESUME_ROUTER &&
122 packet->type != SILC_PACKET_REKEY)
125 /* Check that the the current client ID is same as in the client's packet. */
126 if (idata->conn_type == SILC_CONN_CLIENT) {
127 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
128 SilcClientID client_id;
130 if (client->id && packet->src_id &&
131 silc_id_str2id(packet->src_id, packet->src_id_len,
132 packet->src_id_type, &client_id, sizeof(client_id))) {
133 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
134 SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
135 silc_get_packet_name(packet->type)));
141 if (server->server_type == SILC_ROUTER) {
142 /* Route the packet if it is not destined to us. Other ID types but
143 server are handled separately after processing them. */
144 if (packet->dst_id &&
145 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
146 packet->dst_id_type == SILC_ID_SERVER &&
147 idata->conn_type != SILC_CONN_CLIENT &&
148 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
149 SilcPacketStream conn;
150 SilcServerID server_id;
152 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
153 &server_id, sizeof(server_id));
155 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
157 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
158 silc_id_render(&server_id, SILC_ID_SERVER)));
162 silc_server_packet_route(server, conn, packet);
163 silc_packet_free(packet);
168 /* Broadcast packet if it is marked as broadcast packet and it is
169 originated from router and we are router. */
170 if (server->server_type == SILC_ROUTER &&
171 idata->conn_type == SILC_CONN_ROUTER &&
172 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
173 /* Broadcast to our primary route */
174 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
176 /* If we have backup routers then we need to feed all broadcast
177 data to those servers. */
178 silc_server_backup_broadcast(server, stream, packet);
182 silc_server_packet_parse_type(server, stream, packet);
187 /* Packet engine callback to indicate end of stream */
189 static void silc_server_packet_eos(SilcPacketEngine engine,
190 SilcPacketStream stream,
191 void *callback_context,
192 void *stream_context)
194 SilcServer server = callback_context;
195 SilcIDListData idata = silc_packet_get_context(stream);
197 SILC_LOG_DEBUG(("End of stream received, sock %p", stream));
202 if (server->router_conn && server->router_conn->sock == stream &&
203 !server->router && server->standalone) {
204 if (idata->sconn && idata->sconn->callback)
205 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
206 silc_server_create_connections(server);
207 silc_server_free_sock_user_data(server, stream, NULL);
209 /* If backup disconnected then mark that resuming will not be allowed */
210 if (server->server_type == SILC_ROUTER && !server->backup_router &&
211 idata->conn_type == SILC_CONN_SERVER) {
212 SilcServerEntry server_entry = (SilcServerEntry)idata;
213 if (server_entry->server_type == SILC_BACKUP_ROUTER)
214 server->backup_closed = TRUE;
217 if (idata->sconn && idata->sconn->callback)
218 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
219 silc_server_free_sock_user_data(server, stream, NULL);
222 silc_server_close_connection(server, stream);
225 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
227 SilcServer server = app_context;
228 SilcPacketStream stream = context;
229 SilcIDListData idata = silc_packet_get_context(stream);
234 if (server->router_conn && server->router_conn->sock == stream &&
235 !server->router && server->standalone) {
236 silc_server_create_connections(server);
238 /* If backup disconnected then mark that resuming will not be allowed */
239 if (server->server_type == SILC_ROUTER && !server->backup_router &&
240 idata->conn_type == SILC_CONN_SERVER) {
241 SilcServerEntry server_entry = (SilcServerEntry)idata;
242 if (server_entry->server_type == SILC_BACKUP_ROUTER)
243 server->backup_closed = TRUE;
246 if (idata->sconn && idata->sconn->callback)
247 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
248 silc_server_free_sock_user_data(server, stream, NULL);
251 silc_server_close_connection(server, stream);
254 /* Packet engine callback to indicate error */
256 static void silc_server_packet_error(SilcPacketEngine engine,
257 SilcPacketStream stream,
258 SilcPacketError error,
259 void *callback_context,
260 void *stream_context)
262 SilcServer server = callback_context;
263 SilcIDListData idata = silc_packet_get_context(stream);
264 SilcStream sock = silc_packet_stream_get_stream(stream);
268 SILC_LOG_DEBUG(("Packet error, sock %p", stream));
273 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
276 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
277 SILC_CONNTYPE_STRING(idata->conn_type),
278 silc_packet_error_string(error)));
280 if (!silc_packet_stream_is_valid(stream))
283 silc_schedule_task_add_timeout(server->schedule,
284 silc_server_packet_error_timeout,
288 /* Packet stream callbacks */
289 static SilcPacketCallbacks silc_server_stream_cbs =
291 silc_server_packet_receive,
292 silc_server_packet_eos,
293 silc_server_packet_error
296 /* Parses the packet type and calls what ever routines the packet type
297 requires. This is done for all incoming packets. */
299 static void silc_server_packet_parse_type(SilcServer server,
300 SilcPacketStream sock,
303 SilcPacketType type = packet->type;
304 SilcIDListData idata = silc_packet_get_context(sock);
306 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
307 silc_get_packet_name(type), packet->flags));
309 /* Parse the packet type */
311 case SILC_PACKET_NOTIFY:
313 * Received notify packet. Server can receive notify packets from
314 * router. Server then relays the notify messages to clients if needed.
316 if (packet->flags & SILC_PACKET_FLAG_LIST)
317 silc_server_notify_list(server, sock, packet);
319 silc_server_notify(server, sock, packet);
323 * Private Message packets
325 case SILC_PACKET_PRIVATE_MESSAGE:
327 * Received private message packet. The packet is coming from either
330 if (packet->flags & SILC_PACKET_FLAG_LIST)
332 idata->last_receive = time(NULL);
333 silc_server_private_message(server, sock, packet);
339 case SILC_PACKET_CHANNEL_MESSAGE:
341 * Received channel message. Channel messages are special packets
342 * (although probably most common ones) thus they are handled
345 if (packet->flags & SILC_PACKET_FLAG_LIST)
347 idata->last_receive = time(NULL);
348 silc_server_channel_message(server, sock, packet);
354 case SILC_PACKET_COMMAND:
356 * Recived command. Processes the command request and allocates the
357 * command context and calls the command.
359 if (packet->flags & SILC_PACKET_FLAG_LIST)
361 server->stat.commands_received++;
362 silc_server_command_process(server, sock, packet);
365 case SILC_PACKET_COMMAND_REPLY:
367 * Received command reply packet. Received command reply to command. It
368 * may be reply to command sent by us or reply to command sent by client
369 * that we've routed further.
371 if (packet->flags & SILC_PACKET_FLAG_LIST)
373 server->stat.commands_received++;
374 silc_server_command_reply(server, sock, packet);
377 case SILC_PACKET_DISCONNECT:
380 char *message = NULL;
381 const char *hostname, *ip;
383 if (packet->flags & SILC_PACKET_FLAG_LIST)
385 if (silc_buffer_len(&packet->buffer) < 1)
388 status = (SilcStatus)packet->buffer.data[0];
389 if (silc_buffer_len(&packet->buffer) > 1 &&
390 silc_utf8_valid(packet->buffer.data + 1,
391 silc_buffer_len(&packet->buffer) - 1))
392 message = silc_memdup(packet->buffer.data + 1,
393 silc_buffer_len(&packet->buffer) - 1);
395 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
396 NULL, &hostname, &ip, NULL))
399 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
400 silc_get_status_message(status), status,
401 message ? message : ""));
405 /* Do not switch to backup in case of error */
406 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
408 /* If backup disconnected then mark that resuming will not be allowed */
409 if (server->server_type == SILC_ROUTER && !server->backup_router &&
410 idata->conn_type == SILC_CONN_SERVER) {
411 SilcServerEntry server_entry = (SilcServerEntry)idata;
412 if (server_entry->server_type == SILC_BACKUP_ROUTER)
413 server->backup_closed = TRUE;
416 /* Handle the disconnection from our end too */
417 if (SILC_IS_LOCAL(idata))
418 silc_server_free_sock_user_data(server, sock, NULL);
419 silc_server_close_connection(server, sock);
420 server->backup_noswitch = FALSE;
424 case SILC_PACKET_CHANNEL_KEY:
426 * Received key for channel. As channels are created by the router
427 * the keys are as well. We will distribute the key to all of our
428 * locally connected clients on the particular channel. Router
429 * never receives this channel and thus is ignored.
431 if (packet->flags & SILC_PACKET_FLAG_LIST)
433 silc_server_channel_key(server, sock, packet);
436 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
438 * Private message key packet.
440 if (packet->flags & SILC_PACKET_FLAG_LIST)
442 silc_server_private_message_key(server, sock, packet);
445 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
447 * Connection authentication request packet. When we receive this packet
448 * we will send to the other end information about our mandatory
449 * authentication method for the connection. This packet maybe received
452 if (packet->flags & SILC_PACKET_FLAG_LIST)
454 silc_server_connection_auth_request(server, sock, packet);
457 case SILC_PACKET_NEW_ID:
459 * Received New ID packet. This includes some new ID that has been
460 * created. It may be for client, server or channel. This is the way
461 * to distribute information about new registered entities in the
464 if (packet->flags & SILC_PACKET_FLAG_LIST)
465 silc_server_new_id_list(server, sock, packet);
467 silc_server_new_id(server, sock, packet);
470 case SILC_PACKET_NEW_CLIENT:
472 * Received new client packet. This includes client information that
473 * we will use to create initial client ID. After creating new
474 * ID we will send it to the client.
476 if (packet->flags & SILC_PACKET_FLAG_LIST)
478 silc_server_new_client(server, sock, packet);
481 case SILC_PACKET_NEW_SERVER:
483 * Received new server packet. This includes Server ID and some other
484 * information that we may save. This is received after server has
487 if (packet->flags & SILC_PACKET_FLAG_LIST)
489 silc_server_new_server(server, sock, packet);
492 case SILC_PACKET_NEW_CHANNEL:
494 * Received new channel packet. Information about new channel in the
495 * network are distributed using this packet.
497 if (packet->flags & SILC_PACKET_FLAG_LIST)
498 silc_server_new_channel_list(server, sock, packet);
500 silc_server_new_channel(server, sock, packet);
503 case SILC_PACKET_HEARTBEAT:
505 * Received heartbeat.
507 if (packet->flags & SILC_PACKET_FLAG_LIST)
511 case SILC_PACKET_KEY_AGREEMENT:
513 * Received heartbeat.
515 if (packet->flags & SILC_PACKET_FLAG_LIST)
517 silc_server_key_agreement(server, sock, packet);
520 case SILC_PACKET_REKEY:
522 * Received re-key packet. The sender wants to regenerate the session
525 if (packet->flags & SILC_PACKET_FLAG_LIST)
527 silc_server_rekey(server, sock, packet);
530 case SILC_PACKET_FTP:
532 if (packet->flags & SILC_PACKET_FLAG_LIST)
534 silc_server_ftp(server, sock, packet);
537 case SILC_PACKET_RESUME_CLIENT:
539 if (packet->flags & SILC_PACKET_FLAG_LIST)
541 silc_server_resume_client(server, sock, packet);
544 case SILC_PACKET_RESUME_ROUTER:
545 /* Resume router packet received. This packet is received for backup
546 router resuming protocol. */
547 if (packet->flags & SILC_PACKET_FLAG_LIST)
549 silc_server_backup_resume_router(server, sock, packet);
553 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
558 /****************************** Server API **********************************/
560 /* Allocates a new SILC server object. This has to be done before the server
561 can be used. After allocation one must call silc_server_init to initialize
562 the server. The new allocated server object is returned to the new_server
565 SilcBool silc_server_alloc(SilcServer *new_server)
569 SILC_LOG_DEBUG(("Allocating new server object"));
571 server = silc_calloc(1, sizeof(*server));
574 server->server_type = SILC_SERVER;
575 server->standalone = TRUE;
576 server->local_list = silc_calloc(1, sizeof(*server->local_list));
577 if (!server->local_list)
579 server->global_list = silc_calloc(1, sizeof(*server->global_list));
580 if (!server->global_list)
582 server->pending_commands = silc_dlist_init();
583 if (!server->pending_commands)
585 server->listeners = silc_dlist_init();
586 if (!server->listeners)
588 server->repository = silc_skr_alloc();
589 if (!server->repository)
591 server->conns = silc_dlist_init();
594 server->expired_clients = silc_dlist_init();
595 if (!server->expired_clients)
598 *new_server = server;
603 /* Free's the SILC server object. This is called at the very end before
606 void silc_server_free(SilcServer server)
609 SilcIDCacheEntry cache;
610 SilcIDListData idata;
612 SILC_LOG_DEBUG(("Free server %p", server));
617 silc_server_backup_free(server);
618 silc_server_config_unref(&server->config_ref);
620 silc_rng_free(server->rng);
621 if (server->public_key)
622 silc_pkcs_public_key_free(server->public_key);
623 if (server->private_key)
624 silc_pkcs_private_key_free(server->private_key);
625 if (server->pending_commands)
626 silc_dlist_uninit(server->pending_commands);
627 if (server->id_entry) {
628 if (server->id_entry->data.sconn)
629 silc_schedule_task_del_by_context(server->schedule,
630 server->id_entry->data.sconn->sock);
631 silc_idlist_del_server(server->local_list, server->id_entry);
634 /* Delete all channels */
635 if (silc_idcache_get_all(server->local_list->channels, &list)) {
636 silc_list_start(list);
637 while ((cache = silc_list_get(list)))
638 silc_idlist_del_channel(server->local_list, cache->context);
640 if (silc_idcache_get_all(server->global_list->channels, &list)) {
641 silc_list_start(list);
642 while ((cache = silc_list_get(list)))
643 silc_idlist_del_channel(server->global_list, cache->context);
646 /* Delete all clients */
647 if (silc_idcache_get_all(server->local_list->clients, &list)) {
648 silc_list_start(list);
649 while ((cache = silc_list_get(list))) {
650 silc_schedule_task_del_by_context(server->schedule, cache->context);
651 silc_idlist_del_client(server->local_list, cache->context);
654 if (silc_idcache_get_all(server->global_list->clients, &list)) {
655 silc_list_start(list);
656 while ((cache = silc_list_get(list))) {
657 silc_schedule_task_del_by_context(server->schedule, cache->context);
658 silc_idlist_del_client(server->global_list, cache->context);
662 /* Delete all servers */
663 if (silc_idcache_get_all(server->local_list->servers, &list)) {
664 silc_list_start(list);
665 while ((cache = silc_list_get(list))) {
666 idata = (SilcIDListData)cache->context;
668 silc_schedule_task_del_by_context(server->schedule,
670 silc_idlist_del_server(server->local_list, cache->context);
673 if (silc_idcache_get_all(server->global_list->servers, &list)) {
674 while ((cache = silc_list_get(list))) {
675 idata = (SilcIDListData)cache->context;
677 silc_schedule_task_del_by_context(server->schedule,
679 silc_idlist_del_server(server->global_list, cache->context);
683 silc_schedule_task_del_by_context(server->schedule, server);
684 silc_schedule_uninit(server->schedule);
685 server->schedule = NULL;
687 silc_idcache_free(server->local_list->clients);
688 silc_idcache_free(server->local_list->servers);
689 silc_idcache_free(server->local_list->channels);
690 silc_idcache_free(server->global_list->clients);
691 silc_idcache_free(server->global_list->servers);
692 silc_idcache_free(server->global_list->channels);
693 silc_hash_table_free(server->watcher_list);
694 silc_hash_table_free(server->watcher_list_pk);
695 silc_hash_free(server->md5hash);
696 silc_hash_free(server->sha1hash);
698 silc_dlist_uninit(server->listeners);
699 silc_dlist_uninit(server->conns);
700 silc_dlist_uninit(server->expired_clients);
701 silc_skr_free(server->repository);
702 silc_packet_engine_stop(server->packet_engine);
704 silc_schedule_task_del_by_context(server->schedule, server);
705 silc_schedule_uninit(server->schedule);
706 server->schedule = NULL;
708 silc_free(server->local_list);
709 silc_free(server->global_list);
710 silc_free(server->server_name);
713 silc_hmac_unregister_all();
714 silc_hash_unregister_all();
715 silc_cipher_unregister_all();
716 silc_pkcs_unregister_all();
719 /* Creates a new server listener. */
721 static SilcNetListener
722 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
724 SilcNetListener listener;
727 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
728 server->config->require_reverse_lookup,
730 silc_server_accept_new_connection, server);
732 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
740 /* Adds a secondary listener. */
742 SilcBool silc_server_init_secondary(SilcServer server)
744 SilcServerConfigServerInfoInterface *interface;
745 SilcNetListener listener;
747 for (interface = server->config->server_info->secondary; interface;
748 interface = interface->next) {
749 listener = silc_server_listen(server, interface->server_ip,
753 silc_dlist_add(server->listeners, listener);
759 /* Initializes the entire SILC server. This is called always before running
760 the server. This is called only once at the initialization of the program.
761 This binds the server to its listenning port. After this function returns
762 one should call silc_server_run to start the server. This returns TRUE
763 when everything is ok to run the server. Configuration file must be
764 read and parsed before calling this. */
766 SilcBool silc_server_init(SilcServer server)
769 SilcServerEntry id_entry;
770 SilcNetListener listener;
774 SILC_LOG_DEBUG(("Initializing server"));
776 server->starttime = time(NULL);
778 /* Take config object for us */
779 silc_server_config_ref(&server->config_ref, server->config,
783 /* Set debugging on if configured */
784 if (server->config->debug_string) {
785 silc_log_debug(TRUE);
786 silc_log_set_debug_string(server->config->debug_string);
788 #endif /* SILC_DEBUG */
790 /* Steal public and private key from the config object */
791 server->public_key = server->config->server_info->public_key;
792 server->private_key = server->config->server_info->private_key;
793 server->config->server_info->public_key = NULL;
794 server->config->server_info->private_key = NULL;
796 /* Register all configured ciphers, PKCS and hash functions. */
797 if (!silc_server_config_register_ciphers(server))
798 silc_cipher_register_default();
799 if (!silc_server_config_register_pkcs(server))
800 silc_pkcs_register_default();
801 if (!silc_server_config_register_hashfuncs(server))
802 silc_hash_register_default();
803 if (!silc_server_config_register_hmacs(server))
804 silc_hmac_register_default();
806 /* Initialize random number generator for the server. */
807 server->rng = silc_rng_alloc();
808 silc_rng_init(server->rng);
809 silc_rng_global_init(server->rng);
811 /* Initialize hash functions for server to use */
812 silc_hash_alloc("md5", &server->md5hash);
813 silc_hash_alloc("sha1", &server->sha1hash);
815 /* Initialize the scheduler */
816 server->schedule = silc_schedule_init(server->config->param.connections_max,
818 if (!server->schedule)
821 /* First, register log files configuration for error output */
822 silc_server_config_setlogfiles(server);
824 /* Initialize ID caches */
825 server->local_list->clients =
826 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
828 server->local_list->servers =
829 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
831 server->local_list->channels =
832 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
835 /* These are allocated for normal server as well as these hold some
836 global information that the server has fetched from its router. For
837 router these are used as they are supposed to be used on router. */
838 server->global_list->clients =
839 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
841 server->global_list->servers =
842 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
844 server->global_list->channels =
845 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
848 /* Init watcher lists */
849 server->watcher_list =
850 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
851 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
853 if (!server->watcher_list)
855 server->watcher_list_pk =
856 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
857 silc_hash_public_key_compare, NULL,
859 if (!server->watcher_list_pk)
862 /* Create TCP listener */
863 listener = silc_server_listen(
865 server->config->server_info->primary == NULL ? NULL :
866 server->config->server_info->primary->server_ip,
867 server->config->server_info->primary == NULL ? 0 :
868 server->config->server_info->primary->port);
871 silc_dlist_add(server->listeners, listener);
873 /* Create a Server ID for the server. */
874 port = silc_net_listener_get_port(listener, NULL);
875 ip = silc_net_listener_get_ip(listener, NULL);
876 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
877 server->config->server_info->primary->public_ip :
878 ip[0], port[0], server->rng, &id);
887 server->server_name = server->config->server_info->server_name;
888 server->config->server_info->server_name = NULL;
889 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
890 sizeof(server->id_string), &server->id_string_len);
892 /* Add ourselves to the server list. We don't have a router yet
893 beacuse we haven't established a route yet. It will be done later.
894 For now, NULL is sent as router. This allocates new entry to
897 silc_idlist_add_server(server->local_list, strdup(server->server_name),
899 silc_id_dup(server->id, SILC_ID_SERVER),
902 SILC_LOG_ERROR(("Could not add local server to cache"));
905 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
906 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
907 SILC_CONN_SERVER : SILC_CONN_ROUTER);
908 server->id_entry = id_entry;
910 /* Create secondary TCP listeners */
911 if (silc_server_init_secondary(server) == FALSE)
914 server->listenning = TRUE;
916 /* Create connections to configured routers. */
917 silc_server_create_connections(server);
919 /* If server connections has been configured then we must be router as
920 normal server cannot have server connections, only router connections. */
921 if (server->config->servers) {
922 SilcServerConfigServer *ptr = server->config->servers;
924 server->server_type = SILC_ROUTER;
926 if (ptr->backup_router) {
927 server->server_type = SILC_BACKUP_ROUTER;
928 server->backup_router = TRUE;
929 server->id_entry->server_type = SILC_BACKUP_ROUTER;
936 if (server->server_type != SILC_ROUTER) {
937 server->stat.servers = 1;
938 server->stat.cell_servers = 1;
940 server->stat.routers = 1;
942 /* If we are normal server we'll retrieve network statisticial information
943 once in a while from the router. */
944 if (server->server_type != SILC_ROUTER)
945 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
948 /* Start packet engine */
949 server->packet_engine =
950 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
951 &silc_server_stream_cbs, server);
952 if (!server->packet_engine)
955 /* Register client entry expiration timeout */
956 silc_schedule_task_add_timeout(server->schedule,
957 silc_server_purge_expired_clients, server,
960 /* Initialize HTTP server */
961 silc_server_http_init(server);
963 SILC_LOG_DEBUG(("Server initialized"));
965 /* We are done here, return succesfully */
969 silc_server_config_unref(&server->config_ref);
973 /* Task callback to close a socket connection after rehash */
975 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
977 SilcServer server = app_context;
978 SilcPacketStream sock = context;
979 SilcIDListData idata = silc_packet_get_context(sock);
980 const char *hostname;
983 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
984 NULL, &hostname, NULL, &port);
986 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
987 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
988 silc_schedule_task_del_by_context(server->schedule, sock);
989 silc_server_disconnect_remote(server, sock,
990 SILC_STATUS_ERR_BANNED_FROM_SERVER,
991 "This connection is removed from "
993 silc_server_free_sock_user_data(server, sock, NULL);
996 /* This function basically reads the config file again and switches the config
997 object pointed by the server object. After that, we have to fix various
998 things such as the server_name and the listening ports.
999 Keep in mind that we no longer have the root privileges at this point. */
1001 SilcBool silc_server_rehash(SilcServer server)
1003 SilcServerConfig newconfig;
1005 SILC_LOG_INFO(("Rehashing server"));
1007 /* Reset the logging system */
1008 silc_log_quick(TRUE);
1009 silc_log_flush_all();
1011 /* Start the main rehash phase (read again the config file) */
1012 newconfig = silc_server_config_alloc(server->config_file, server);
1014 SILC_LOG_ERROR(("Rehash FAILED."));
1018 /* Fix the server_name field */
1019 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1020 silc_free(server->server_name);
1022 /* Check server name */
1023 server->server_name =
1024 silc_identifier_check(newconfig->server_info->server_name,
1025 strlen(newconfig->server_info->server_name),
1026 SILC_STRING_LOCALE, 256, NULL);
1027 if (!server->server_name) {
1028 SILC_LOG_ERROR(("Malformed server name string '%s'",
1029 server->config->server_info->server_name));
1033 /* Update the idcache list with a fresh pointer */
1034 silc_free(server->id_entry->server_name);
1035 server->id_entry->server_name = strdup(server->server_name);
1036 silc_idcache_update_by_context(server->local_list->servers,
1037 server->id_entry, NULL,
1038 strdup(server->id_entry->server_name),
1043 silc_server_config_setlogfiles(server);
1045 /* Change new key pair if necessary */
1046 if (newconfig->server_info->public_key &&
1047 !silc_pkcs_public_key_compare(server->public_key,
1048 newconfig->server_info->public_key)) {
1049 silc_pkcs_public_key_free(server->public_key);
1050 silc_pkcs_private_key_free(server->private_key);
1051 server->public_key = newconfig->server_info->public_key;
1052 server->private_key = newconfig->server_info->private_key;
1053 newconfig->server_info->public_key = NULL;
1054 newconfig->server_info->private_key = NULL;
1057 /* Check for unconfigured server and router connections and close
1058 connections that were unconfigured. */
1060 if (server->config->routers) {
1061 SilcServerConfigRouter *ptr;
1062 SilcServerConfigRouter *newptr;
1065 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1068 /* Check whether new config has this one too */
1069 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1070 if (silc_string_compare(newptr->host, ptr->host) &&
1071 newptr->port == ptr->port &&
1072 newptr->initiator == ptr->initiator) {
1078 if (!found && ptr->host) {
1079 /* Remove this connection */
1080 SilcPacketStream sock;
1081 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1082 ptr->host, ptr->port);
1084 silc_schedule_task_add_timeout(server->schedule,
1085 silc_server_rehash_close_connection,
1091 if (server->config->servers) {
1092 SilcServerConfigServer *ptr;
1093 SilcServerConfigServer *newptr;
1096 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1099 /* Check whether new config has this one too */
1100 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1101 if (silc_string_compare(newptr->host, ptr->host)) {
1107 if (!found && ptr->host) {
1108 /* Remove this connection */
1109 SilcPacketStream sock;
1110 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1113 silc_schedule_task_add_timeout(server->schedule,
1114 silc_server_rehash_close_connection,
1120 if (server->config->clients) {
1121 SilcServerConfigClient *ptr;
1122 SilcServerConfigClient *newptr;
1125 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1128 /* Check whether new config has this one too */
1129 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1130 if (silc_string_compare(newptr->host, ptr->host)) {
1136 if (!found && ptr->host) {
1137 /* Remove this connection */
1138 SilcPacketStream sock;
1139 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1142 silc_schedule_task_add_timeout(server->schedule,
1143 silc_server_rehash_close_connection,
1149 /* Create connections after rehash */
1150 silc_server_create_connections(server);
1152 /* Check whether our router status has changed */
1153 if (newconfig->servers) {
1154 SilcServerConfigServer *ptr = newconfig->servers;
1156 server->server_type = SILC_ROUTER;
1158 if (ptr->backup_router) {
1159 server->server_type = SILC_BACKUP_ROUTER;
1160 server->backup_router = TRUE;
1161 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1168 /* Our old config is gone now. We'll unreference our reference made in
1169 silc_server_init and then destroy it since we are destroying it
1170 underneath the application (layer which called silc_server_init). */
1171 silc_server_config_unref(&server->config_ref);
1172 silc_server_config_destroy(server->config);
1174 /* Take new config context */
1175 server->config = newconfig;
1176 silc_server_config_ref(&server->config_ref, server->config, server->config);
1179 /* Set debugging on if configured */
1180 if (server->config->debug_string) {
1181 silc_log_debug(TRUE);
1182 silc_log_set_debug_string(server->config->debug_string);
1184 #endif /* SILC_DEBUG */
1186 SILC_LOG_DEBUG(("Server rehashed"));
1191 /* The heart of the server. This runs the scheduler thus runs the server.
1192 When this returns the server has been stopped and the program will
1195 void silc_server_run(SilcServer server)
1197 SILC_LOG_INFO(("SILC Server started"));
1199 /* Start the scheduler, the heart of the SILC server. When this returns
1200 the program will be terminated. */
1201 silc_schedule(server->schedule);
1204 /* Stops the SILC server. This function is used to shutdown the server.
1205 This is usually called after the scheduler has returned. After stopping
1206 the server one should call silc_server_free. */
1208 void silc_server_stop(SilcServer server)
1211 SilcPacketStream ps;
1212 SilcNetListener listener;
1214 SILC_LOG_INFO(("SILC Server shutting down"));
1216 server->server_shutdown = TRUE;
1218 /* Close all connections */
1219 if (server->packet_engine) {
1220 list = silc_packet_engine_get_streams(server->packet_engine);
1222 silc_dlist_start(list);
1223 while ((ps = silc_dlist_get(list))) {
1224 SilcIDListData idata = silc_packet_get_context(ps);
1226 if (!silc_packet_stream_is_valid(ps))
1230 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1232 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1233 "Server is shutting down");
1234 silc_server_free_sock_user_data(server, ps,
1235 "Server is shutting down");
1237 silc_packet_engine_free_streams_list(list);
1240 /* We are not connected to network anymore */
1241 server->standalone = TRUE;
1243 silc_dlist_start(server->listeners);
1244 while ((listener = silc_dlist_get(server->listeners)))
1245 silc_net_close_listener(listener);
1247 silc_server_http_uninit(server);
1249 /* Cancel any possible retry timeouts */
1250 silc_schedule_task_del_by_callback(server->schedule,
1251 silc_server_connect_router);
1252 silc_schedule_task_del_by_callback(server->schedule,
1253 silc_server_connect_to_router_retry);
1254 silc_schedule_task_del_by_callback(server->schedule,
1255 silc_server_connect_to_router);
1257 silc_schedule_stop(server->schedule);
1259 SILC_LOG_DEBUG(("Server stopped"));
1262 /* Purge expired client entries from the server */
1264 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1266 SilcServer server = context;
1267 SilcClientEntry client;
1269 SilcUInt64 curtime = silc_time();
1271 SILC_LOG_DEBUG(("Expire timeout"));
1273 silc_dlist_start(server->expired_clients);
1274 while ((client = silc_dlist_get(server->expired_clients))) {
1277 /* For unregistered clients the created timestamp is actually
1278 unregistered timestamp. Make sure client remains in history
1279 at least 500 seconds. */
1280 if (client->data.created && curtime - client->data.created < 500)
1283 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1284 server->local_list : server->global_list);
1286 silc_idlist_del_data(client);
1287 silc_idlist_del_client(id_list, client);
1288 silc_dlist_del(server->expired_clients, client);
1291 silc_schedule_task_add_timeout(server->schedule,
1292 silc_server_purge_expired_clients, server,
1297 /******************************* Connecting *********************************/
1299 /* Free connection context */
1301 void silc_server_connection_free(SilcServerConnection sconn)
1305 SILC_LOG_DEBUG(("Free connection %p", sconn));
1306 silc_dlist_del(sconn->server->conns, sconn);
1307 silc_server_config_unref(&sconn->conn);
1308 silc_free(sconn->remote_host);
1309 silc_free(sconn->backup_replace_ip);
1313 /* Creates connection to a remote router. */
1315 void silc_server_create_connection(SilcServer server,
1318 const char *remote_host, SilcUInt32 port,
1319 SilcServerConnectCallback callback,
1322 SilcServerConnection sconn;
1324 /* Allocate connection object for hold connection specific stuff. */
1325 sconn = silc_calloc(1, sizeof(*sconn));
1328 sconn->remote_host = strdup(remote_host);
1329 sconn->remote_port = port;
1330 sconn->no_reconnect = reconnect == FALSE;
1331 sconn->callback = callback;
1332 sconn->callback_context = context;
1333 sconn->no_conf = dynamic;
1334 sconn->server = server;
1336 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1337 remote_host, port));
1339 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1343 /* Connection authentication completion callback */
1346 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1349 SilcServerConnection sconn = context;
1350 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1351 SilcServer server = entry->server;
1352 SilcServerConfigServer *conn;
1353 SilcServerConfigConnParams *param;
1354 SilcIDListData idata;
1355 SilcServerEntry id_entry = NULL;
1356 unsigned char id[32];
1361 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1366 if (success == FALSE) {
1367 /* Authentication failed */
1369 /* Try reconnecting if configuration wants it */
1370 if (!sconn->no_reconnect) {
1371 silc_schedule_task_add_timeout(server->schedule,
1372 silc_server_connect_to_router_retry,
1374 silc_dlist_del(server->conns, sconn);
1378 if (sconn->callback)
1379 (*sconn->callback)(server, NULL, sconn->callback_context);
1380 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1384 /* XXX For now remote is router always */
1385 entry->data.conn_type = SILC_CONN_ROUTER;
1387 SILC_LOG_INFO(("Connected to %s %s",
1388 SILC_CONNTYPE_STRING(entry->data.conn_type),
1389 sconn->remote_host));
1391 /* Create the actual entry for remote entity */
1392 switch (entry->data.conn_type) {
1393 case SILC_CONN_SERVER:
1394 SILC_LOG_DEBUG(("Remote is SILC server"));
1396 /* Add new server. The server must register itself to us before it
1397 becomes registered to SILC network. */
1398 id_entry = silc_idlist_add_server(server->local_list,
1399 strdup(sconn->remote_host),
1400 SILC_SERVER, NULL, NULL, sconn->sock);
1402 silc_server_disconnect_remote(server, sconn->sock,
1403 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1404 if (sconn->callback)
1405 (*sconn->callback)(server, NULL, sconn->callback_context);
1406 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1411 server->stat.my_servers++;
1412 if (server->server_type == SILC_ROUTER)
1413 server->stat.servers++;
1414 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1416 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1419 case SILC_CONN_ROUTER:
1420 SILC_LOG_DEBUG(("Remote is SILC router"));
1422 /* Register to network */
1423 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1424 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1425 SILC_STR_UI_SHORT(id_len),
1426 SILC_STR_DATA(id, id_len),
1427 SILC_STR_UI_SHORT(strlen(server->server_name)),
1428 SILC_STR_DATA(server->server_name,
1429 strlen(server->server_name)),
1431 silc_server_disconnect_remote(server, sconn->sock,
1432 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1433 if (sconn->callback)
1434 (*sconn->callback)(server, NULL, sconn->callback_context);
1435 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1440 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1442 /* Check that we do not have this ID already */
1443 id_entry = silc_idlist_find_server_by_id(server->local_list,
1444 &remote_id.u.server_id,
1447 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1449 id_entry = silc_idlist_find_server_by_id(server->global_list,
1450 &remote_id.u.server_id,
1453 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1457 SILC_LOG_DEBUG(("New server id(%s)",
1458 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1460 /* Add the connected router to global server list. Router is sent
1461 as NULL since it's local to us. */
1462 id_entry = silc_idlist_add_server(server->global_list,
1463 strdup(sconn->remote_host),
1465 silc_id_dup(&remote_id.u.server_id,
1469 /* Try reconnecting if configuration wants it */
1470 if (!sconn->no_reconnect) {
1471 silc_schedule_task_add_timeout(server->schedule,
1472 silc_server_connect_to_router_retry,
1474 silc_dlist_del(server->conns, sconn);
1478 if (sconn->callback)
1479 (*sconn->callback)(server, NULL, sconn->callback_context);
1480 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1485 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1486 idata = (SilcIDListData)id_entry;
1487 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1488 SILC_IDLIST_STATUS_LOCAL);
1489 idata->sconn = sconn;
1490 idata->sconn->callback = NULL;
1493 server->stat.my_routers++;
1494 if (server->server_type == SILC_ROUTER)
1495 server->stat.routers++;
1496 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1498 if (!sconn->backup) {
1499 /* Mark this router our primary router if we're still standalone */
1500 if (server->standalone) {
1501 SILC_LOG_DEBUG(("This connection is our primary router"));
1502 server->id_entry->router = id_entry;
1503 server->router = id_entry;
1504 server->router->server_type = SILC_ROUTER;
1505 server->standalone = FALSE;
1506 server->backup_primary = FALSE;
1508 /* Announce data if we are not backup router (unless not as primary
1509 currently). Backup router announces later at the end of
1510 resuming protocol. */
1511 if (server->backup_router && server->server_type == SILC_ROUTER) {
1512 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1514 /* If we are router then announce our possible servers. Backup
1515 router announces also global servers. */
1516 if (server->server_type == SILC_ROUTER)
1517 silc_server_announce_servers(server,
1518 server->backup_router ? TRUE : FALSE,
1519 0, SILC_PRIMARY_ROUTE(server));
1521 /* Announce our clients and channels to the router */
1522 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1523 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1526 /* If we are backup router then this primary router is whom we are
1528 if (server->server_type == SILC_BACKUP_ROUTER) {
1529 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1531 NULL, NULL, &ip, NULL);
1532 silc_server_backup_add(server, server->id_entry, ip,
1533 sconn->remote_port, TRUE);
1538 /* We already have primary router. Disconnect this connection */
1539 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1540 silc_idlist_del_server(server->global_list, id_entry);
1541 silc_server_disconnect_remote(server, sconn->sock,
1542 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1543 if (sconn->callback)
1544 (*sconn->callback)(server, NULL, sconn->callback_context);
1545 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1546 silc_server_disconnect_remote(server, sconn->sock,
1547 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1552 /* Add this server to be our backup router */
1553 id_entry->server_type = SILC_BACKUP_ROUTER;
1554 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1555 sconn->backup_replace_port, FALSE);
1561 silc_server_disconnect_remote(server, sconn->sock,
1562 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1563 if (sconn->callback)
1564 (*sconn->callback)(server, NULL, sconn->callback_context);
1565 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1569 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1571 conn = sconn->conn.ref_ptr;
1572 param = &server->config->param;
1573 if (conn && conn->param)
1574 param = conn->param;
1576 /* Register rekey timeout */
1577 sconn->rekey_timeout = param->key_exchange_rekey;
1578 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1579 sconn->sock, sconn->rekey_timeout, 0);
1581 /* Set the entry as packet stream context */
1582 silc_packet_set_context(sconn->sock, id_entry);
1584 /* Call the completion callback to indicate that we've connected to
1586 if (sconn && sconn->callback)
1587 (*sconn->callback)(server, id_entry, sconn->callback_context);
1589 if (sconn == server->router_conn)
1590 server->router_conn = NULL;
1595 /* SKE completion callback */
1597 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1598 SilcSKESecurityProperties prop,
1599 SilcSKEKeyMaterial keymat,
1600 SilcSKERekeyMaterial rekey,
1603 SilcPacketStream sock = context;
1604 SilcUnknownEntry entry = silc_packet_get_context(sock);
1605 SilcServerConnection sconn;
1607 SilcServerConfigRouter *conn;
1608 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1609 void *auth_data = NULL;
1610 SilcUInt32 auth_data_len = 0;
1611 SilcConnAuth connauth;
1612 SilcCipher send_key, receive_key;
1613 SilcHmac hmac_send, hmac_receive;
1616 server = entry->server;
1617 sconn = entry->data.sconn;
1618 conn = sconn->conn.ref_ptr;
1621 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1623 if (status != SILC_SKE_STATUS_OK) {
1625 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1626 silc_ske_map_status(status), entry->hostname, entry->ip));
1629 /* Try reconnecting if configuration wants it */
1630 if (!sconn->no_reconnect) {
1631 silc_schedule_task_add_timeout(server->schedule,
1632 silc_server_connect_to_router_retry,
1634 silc_dlist_del(server->conns, sconn);
1638 if (sconn->callback)
1639 (*sconn->callback)(server, NULL, sconn->callback_context);
1640 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1644 SILC_LOG_DEBUG(("Setting keys into use"));
1646 /* Set the keys into use. The data will be encrypted after this. */
1647 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1648 &hmac_send, &hmac_receive, &hash)) {
1651 /* Try reconnecting if configuration wants it */
1652 if (!sconn->no_reconnect) {
1653 silc_schedule_task_add_timeout(server->schedule,
1654 silc_server_connect_to_router_retry,
1656 silc_dlist_del(server->conns, sconn);
1660 /* Error setting keys */
1661 silc_server_disconnect_remote(server, sconn->sock,
1662 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1663 if (sconn->callback)
1664 (*sconn->callback)(server, NULL, sconn->callback_context);
1665 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1668 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1669 hmac_receive, FALSE);
1671 SILC_LOG_DEBUG(("Starting connection authentication"));
1673 connauth = silc_connauth_alloc(server->schedule, ske,
1674 server->config->conn_auth_timeout);
1678 /* Try reconnecting if configuration wants it */
1679 if (!sconn->no_reconnect) {
1680 silc_schedule_task_add_timeout(server->schedule,
1681 silc_server_connect_to_router_retry,
1683 silc_dlist_del(server->conns, sconn);
1687 /** Error allocating auth protocol */
1688 silc_server_disconnect_remote(server, sconn->sock,
1689 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1690 if (sconn->callback)
1691 (*sconn->callback)(server, NULL, sconn->callback_context);
1692 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1696 /* Get authentication method */
1698 if (conn->passphrase) {
1699 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1700 auth_meth = SILC_AUTH_PUBLIC_KEY;
1701 auth_data = server->private_key;
1703 auth_meth = SILC_AUTH_PASSWORD;
1704 auth_data = conn->passphrase;
1705 auth_data_len = conn->passphrase_len;
1708 auth_meth = SILC_AUTH_PUBLIC_KEY;
1709 auth_data = server->private_key;
1713 entry->data.rekey = rekey;
1715 /* Start connection authentication */
1717 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1718 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1719 auth_data, auth_data_len,
1720 silc_server_ke_auth_compl, sconn);
1723 /* Function that is called when the network connection to a router has
1724 been established. This will continue with the key exchange protocol
1725 with the remote router. */
1727 void silc_server_start_key_exchange(SilcServerConnection sconn)
1729 SilcServer server = sconn->server;
1730 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1731 SilcUnknownEntry entry;
1732 SilcSKEParamsStruct params;
1735 /* Cancel any possible retry timeouts */
1736 silc_schedule_task_del_by_context(server->schedule, sconn);
1738 /* Create packet stream */
1739 sconn->sock = silc_packet_stream_create(server->packet_engine,
1740 server->schedule, sconn->stream);
1742 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1743 silc_stream_destroy(sconn->stream);
1745 /* Try reconnecting if configuration wants it */
1746 if (!sconn->no_reconnect) {
1747 silc_schedule_task_add_timeout(server->schedule,
1748 silc_server_connect_to_router_retry,
1750 silc_dlist_del(server->conns, sconn);
1754 if (sconn->callback)
1755 (*sconn->callback)(server, NULL, sconn->callback_context);
1756 silc_server_connection_free(sconn);
1759 server->stat.conn_num++;
1761 /* Set source ID to packet stream */
1762 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1764 silc_packet_stream_destroy(sconn->sock);
1766 /* Try reconnecting if configuration wants it */
1767 if (!sconn->no_reconnect) {
1768 silc_schedule_task_add_timeout(server->schedule,
1769 silc_server_connect_to_router_retry,
1771 silc_dlist_del(server->conns, sconn);
1775 if (sconn->callback)
1776 (*sconn->callback)(server, NULL, sconn->callback_context);
1777 silc_server_connection_free(sconn);
1781 /* Create entry for remote entity */
1782 entry = silc_calloc(1, sizeof(*entry));
1784 silc_packet_stream_destroy(sconn->sock);
1786 /* Try reconnecting if configuration wants it */
1787 if (!sconn->no_reconnect) {
1788 silc_schedule_task_add_timeout(server->schedule,
1789 silc_server_connect_to_router_retry,
1791 silc_dlist_del(server->conns, sconn);
1795 if (sconn->callback)
1796 (*sconn->callback)(server, NULL, sconn->callback_context);
1797 silc_server_connection_free(sconn);
1800 entry->server = server;
1801 entry->data.sconn = sconn;
1802 silc_packet_set_context(sconn->sock, entry);
1804 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1806 /* Set Key Exchange flags from configuration, but fall back to global
1808 memset(¶ms, 0, sizeof(params));
1809 SILC_GET_SKE_FLAGS(conn, params.flags);
1810 if (server->config->param.key_exchange_pfs)
1811 params.flags |= SILC_SKE_SP_FLAG_PFS;
1813 /* Start SILC Key Exchange protocol */
1814 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1815 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1816 server->public_key, server->private_key, sconn);
1819 silc_packet_stream_destroy(sconn->sock);
1821 /* Try reconnecting if configuration wants it */
1822 if (!sconn->no_reconnect) {
1823 silc_schedule_task_add_timeout(server->schedule,
1824 silc_server_connect_to_router_retry,
1826 silc_dlist_del(server->conns, sconn);
1830 if (sconn->callback)
1831 (*sconn->callback)(server, NULL, sconn->callback_context);
1832 silc_server_connection_free(sconn);
1835 silc_ske_set_callbacks(ske, silc_server_verify_key,
1836 silc_server_ke_completed, sconn->sock);
1838 /* Start key exchange protocol */
1839 params.version = silc_version_string;
1840 params.timeout_secs = server->config->key_exchange_timeout;
1841 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1844 /* Timeout callback that will be called to retry connecting to remote
1845 router. This is used by both normal and router server. This will wait
1846 before retrying the connecting. The timeout is generated by exponential
1847 backoff algorithm. */
1849 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1851 SilcServerConnection sconn = context;
1852 SilcServer server = sconn->server;
1853 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1854 SilcServerConfigConnParams *param =
1855 (conn->param ? conn->param : &server->config->param);
1857 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1858 sconn->remote_port));
1860 /* Calculate next timeout */
1861 if (sconn->retry_count >= 1) {
1862 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1863 if (sconn->retry_timeout > param->reconnect_interval_max)
1864 sconn->retry_timeout = param->reconnect_interval_max;
1866 sconn->retry_timeout = param->reconnect_interval;
1868 sconn->retry_count++;
1869 sconn->retry_timeout = sconn->retry_timeout +
1870 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1872 /* If we've reached max retry count, give up. */
1873 if ((sconn->retry_count > param->reconnect_count) &&
1874 sconn->no_reconnect) {
1875 SILC_LOG_ERROR(("Could not connect, giving up"));
1877 if (sconn->callback)
1878 (*sconn->callback)(server, NULL, sconn->callback_context);
1879 silc_server_connection_free(sconn);
1883 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1885 /* We will lookup a fresh pointer later */
1886 silc_server_config_unref(&sconn->conn);
1888 /* Wait before retrying */
1889 silc_schedule_task_del_by_context(server->schedule, sconn);
1890 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1891 sconn, sconn->retry_timeout, 0);
1894 /* Callback for async connection to remote router */
1896 static void silc_server_connection_established(SilcNetStatus status,
1900 SilcServerConnection sconn = context;
1901 SilcServer server = sconn->server;
1903 silc_schedule_task_del_by_context(server->schedule, sconn);
1908 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1909 sconn->remote_host, sconn->remote_port));
1911 /* Continue with key exchange protocol */
1912 sconn->stream = stream;
1913 silc_server_start_key_exchange(sconn);
1916 case SILC_NET_UNKNOWN_IP:
1917 case SILC_NET_UNKNOWN_HOST:
1918 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1919 sconn->remote_host, sconn->remote_port,
1920 silc_net_get_error_string(status)));
1921 if (!sconn->no_reconnect) {
1922 silc_schedule_task_add_timeout(sconn->server->schedule,
1923 silc_server_connect_to_router_retry,
1925 silc_dlist_del(server->conns, sconn);
1927 if (sconn->callback)
1928 (*sconn->callback)(server, NULL, sconn->callback_context);
1929 silc_server_connection_free(sconn);
1934 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1935 sconn->remote_host, sconn->remote_port,
1936 silc_net_get_error_string(status)));
1937 if (!sconn->no_reconnect) {
1938 silc_schedule_task_add_timeout(sconn->server->schedule,
1939 silc_server_connect_to_router_retry,
1941 silc_dlist_del(server->conns, sconn);
1943 if (sconn->callback)
1944 (*sconn->callback)(server, NULL, sconn->callback_context);
1945 silc_server_connection_free(sconn);
1951 /* Generic routine to use connect to a router. */
1953 SILC_TASK_CALLBACK(silc_server_connect_router)
1955 SilcServerConnection sconn = context;
1956 SilcServer server = sconn->server;
1957 SilcServerConfigRouter *rconn;
1959 silc_schedule_task_del_by_context(server->schedule, sconn);
1961 /* Don't connect if we are shutting down. */
1962 if (server->server_shutdown) {
1963 if (sconn->callback)
1964 (*sconn->callback)(server, NULL, sconn->callback_context);
1965 silc_server_connection_free(sconn);
1969 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1970 (sconn->backup ? "backup router" : "router"),
1971 sconn->remote_host, sconn->remote_port));
1973 if (!sconn->no_conf) {
1974 /* Find connection configuration */
1975 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1976 sconn->remote_port);
1978 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1979 (sconn->backup ? "backup router" : "router"),
1980 sconn->remote_host, sconn->remote_port));
1981 if (sconn->callback)
1982 (*sconn->callback)(server, NULL, sconn->callback_context);
1983 silc_server_connection_free(sconn);
1986 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1989 /* Connect to remote host */
1991 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1992 server->config->server_info->primary->server_ip),
1993 sconn->remote_host, sconn->remote_port,
1994 server->schedule, silc_server_connection_established,
1997 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1998 sconn->remote_host, sconn->remote_port));
1999 if (sconn->callback)
2000 (*sconn->callback)(server, NULL, sconn->callback_context);
2001 silc_server_connection_free(sconn);
2005 /* Add to connection list */
2006 silc_dlist_add(server->conns, sconn);
2009 /* This function connects to our primary router or if we are a router this
2010 establishes all our primary routes. This is called at the start of the
2011 server to do authentication and key exchange with our router - called
2014 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2016 SilcServer server = context;
2017 SilcServerConnection sconn;
2018 SilcServerConfigRouter *ptr;
2019 SilcServerConfigConnParams *param;
2021 /* Don't connect if we are shutting down. */
2022 if (server->server_shutdown)
2025 SILC_LOG_DEBUG(("We are %s",
2026 (server->server_type == SILC_SERVER ?
2027 "normal server" : server->server_type == SILC_ROUTER ?
2028 "router" : "backup router/normal server")));
2030 if (!server->config->routers) {
2031 /* There wasn't a configured router, we will continue but we don't
2032 have a connection to outside world. We will be standalone server. */
2033 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2034 server->standalone = TRUE;
2038 /* Cancel any possible retry timeouts */
2039 silc_schedule_task_del_by_callback(server->schedule,
2040 silc_server_connect_router);
2041 silc_schedule_task_del_by_callback(server->schedule,
2042 silc_server_connect_to_router_retry);
2044 /* Create the connections to all our routes */
2045 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2047 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2048 ptr->backup_router ? "Backup router" : "Router",
2049 ptr->initiator ? "Initiator" : "Responder",
2050 ptr->host, ptr->port));
2052 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2053 ptr->initiator == FALSE && !server->backup_router &&
2054 !silc_server_config_get_backup_router(server))
2055 server->wait_backup = TRUE;
2057 if (!ptr->initiator)
2059 if (ptr->dynamic_connection)
2062 /* Check whether we are connecting or connected to this host already */
2063 if (silc_server_num_sockets_by_remote(server,
2064 silc_net_is_ip(ptr->host) ?
2066 silc_net_is_ip(ptr->host) ?
2067 NULL : ptr->host, ptr->port,
2068 SILC_CONN_ROUTER)) {
2069 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2070 ptr->host, ptr->port));
2072 /* If we don't have primary router and this connection is our
2073 primary router we are in desync. Reconnect to the primary. */
2074 if (server->standalone && !server->router) {
2076 SilcPacketStream sock;
2077 SilcServerConfigRouter *primary =
2078 silc_server_config_get_primary_router(server);
2081 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2082 ptr->host, ptr->port);
2085 server->backup_noswitch = TRUE;
2086 silc_server_free_sock_user_data(server, sock, NULL);
2087 silc_server_disconnect_remote(server, sock, 0, NULL);
2088 server->backup_noswitch = FALSE;
2089 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2095 param = (ptr->param ? ptr->param : &server->config->param);
2097 /* Allocate connection object for hold connection specific stuff. */
2098 sconn = silc_calloc(1, sizeof(*sconn));
2101 sconn->server = server;
2102 sconn->remote_host = strdup(ptr->host);
2103 sconn->remote_port = ptr->port;
2104 sconn->backup = ptr->backup_router;
2105 if (sconn->backup) {
2106 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2107 sconn->backup_replace_port = ptr->backup_replace_port;
2109 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2111 SILC_LOG_DEBUG(("Created connection %p", sconn));
2112 if (!server->router_conn && !sconn->backup)
2113 server->router_conn = sconn;
2116 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2122 /************************ Accepting new connection **************************/
2124 /* After this is called, server don't wait for backup router anymore.
2125 This gets called automatically even after we have backup router
2126 connection established. */
2128 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2130 SilcServer server = context;
2131 server->wait_backup = FALSE;
2134 /* Authentication data callback */
2137 silc_server_accept_get_auth(SilcConnAuth connauth,
2138 SilcConnectionType conn_type,
2139 unsigned char **passphrase,
2140 SilcUInt32 *passphrase_len,
2141 SilcSKR *repository,
2144 SilcPacketStream sock = context;
2145 SilcUnknownEntry entry = silc_packet_get_context(sock);
2146 SilcServer server = entry->server;
2148 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2150 /* Remote end is client */
2151 if (conn_type == SILC_CONN_CLIENT) {
2152 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2156 *passphrase = cconfig->passphrase;
2157 *passphrase_len = cconfig->passphrase_len;
2158 if (cconfig->publickeys)
2159 *repository = server->repository;
2161 if (cconfig->publickeys) {
2162 if (server->config->prefer_passphrase_auth) {
2166 *passphrase_len = 0;
2170 entry->conn_type = conn_type;
2174 /* Remote end is server */
2175 if (conn_type == SILC_CONN_SERVER) {
2176 SilcServerConfigServer *sconfig;
2178 /* If we are normal server, don't accept the connection */
2179 if (server->server_type == SILC_SERVER)
2182 sconfig = entry->sconfig.ref_ptr;
2186 *passphrase = sconfig->passphrase;
2187 *passphrase_len = sconfig->passphrase_len;
2188 if (sconfig->publickeys)
2189 *repository = server->repository;
2191 if (sconfig->publickeys) {
2192 if (server->config->prefer_passphrase_auth) {
2196 *passphrase_len = 0;
2200 entry->conn_type = conn_type;
2204 /* Remote end is router */
2205 if (conn_type == SILC_CONN_ROUTER) {
2206 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2210 *passphrase = rconfig->passphrase;
2211 *passphrase_len = rconfig->passphrase_len;
2212 if (rconfig->publickeys)
2213 *repository = server->repository;
2215 if (rconfig->publickeys) {
2216 if (server->config->prefer_passphrase_auth) {
2220 *passphrase_len = 0;
2224 entry->conn_type = conn_type;
2231 /* Authentication completion callback. */
2234 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2237 SilcPacketStream sock = context;
2238 SilcUnknownEntry entry = silc_packet_get_context(sock);
2239 SilcIDListData idata = (SilcIDListData)entry;
2240 SilcServer server = entry->server;
2241 SilcServerConfigConnParams *param = &server->config->param;
2242 SilcServerConnection sconn;
2244 const char *hostname, *ip;
2248 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2249 NULL, &hostname, &ip, &port);
2251 if (success == FALSE) {
2252 /* Authentication failed */
2253 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2254 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2255 server->stat.auth_failures++;
2256 silc_server_disconnect_remote(server, sock,
2257 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2258 silc_server_config_unref(&entry->cconfig);
2259 silc_server_config_unref(&entry->sconfig);
2260 silc_server_config_unref(&entry->rconfig);
2261 silc_server_free_sock_user_data(server, sock, NULL);
2265 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2267 switch (entry->conn_type) {
2268 case SILC_CONN_CLIENT:
2270 SilcClientEntry client;
2271 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2273 /* Verify whether this connection is after all allowed to connect */
2274 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2275 &server->config->param,
2277 silc_connauth_get_ske(connauth))) {
2278 server->stat.auth_failures++;
2282 /* If we are primary router and we have backup router configured
2283 but it has not connected to use yet, do not accept any other
2285 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2286 !server->backup_router) {
2287 SilcServerConfigRouter *router;
2288 router = silc_server_config_get_backup_router(server);
2289 if (router && strcmp(server->config->server_info->primary->server_ip,
2291 silc_server_find_socket_by_host(server,
2293 router->backup_replace_ip, 0)) {
2294 SILC_LOG_INFO(("Will not accept connections because we do "
2295 "not have backup router connection established"));
2296 silc_server_disconnect_remote(server, sock,
2297 SILC_STATUS_ERR_PERM_DENIED,
2298 "We do not have connection to backup "
2299 "router established, try later");
2300 silc_server_config_unref(&entry->cconfig);
2301 silc_server_config_unref(&entry->sconfig);
2302 silc_server_config_unref(&entry->rconfig);
2303 silc_server_free_sock_user_data(server, sock, NULL);
2304 server->stat.auth_failures++;
2306 /* From here on, wait 20 seconds for the backup router to appear. */
2307 silc_schedule_task_add_timeout(server->schedule,
2308 silc_server_backup_router_wait,
2309 (void *)server, 20, 0);
2314 SILC_LOG_DEBUG(("Remote host is client"));
2315 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2318 /* Add the client to the client ID cache. The nickname and Client ID
2319 and other information is created after we have received NEW_CLIENT
2320 packet from client. */
2321 client = silc_idlist_add_client(server->local_list,
2322 NULL, NULL, NULL, NULL, NULL, sock);
2324 SILC_LOG_ERROR(("Could not add new client to cache"));
2325 server->stat.auth_failures++;
2326 silc_server_disconnect_remote(server, sock,
2327 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2328 silc_server_config_unref(&entry->cconfig);
2329 silc_server_config_unref(&entry->sconfig);
2330 silc_server_config_unref(&entry->rconfig);
2331 silc_server_free_sock_user_data(server, sock, NULL);
2334 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2335 entry->data.conn_type = SILC_CONN_CLIENT;
2338 server->stat.my_clients++;
2339 server->stat.clients++;
2340 server->stat.cell_clients++;
2342 /* Get connection parameters */
2344 param = conn->param;
2346 if (!param->keepalive_secs)
2347 param->keepalive_secs = server->config->param.keepalive_secs;
2349 if (!param->qos && server->config->param.qos) {
2350 param->qos = server->config->param.qos;
2351 param->qos_rate_limit = server->config->param.qos_rate_limit;
2352 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2353 param->qos_limit_sec = server->config->param.qos_limit_sec;
2354 param->qos_limit_usec = server->config->param.qos_limit_usec;
2357 /* Check if to be anonymous connection */
2358 if (param->anonymous)
2359 client->mode |= SILC_UMODE_ANONYMOUS;
2362 /* Add public key to repository */
2363 SILC_LOG_DEBUG(("Add client public key to repository"));
2364 if (!silc_server_get_public_key_by_client(server, client, NULL))
2365 silc_skr_add_public_key_simple(server->repository,
2366 entry->data.public_key,
2367 SILC_SKR_USAGE_IDENTIFICATION, client,
2370 id_entry = (void *)client;
2374 case SILC_CONN_SERVER:
2375 case SILC_CONN_ROUTER:
2377 SilcServerEntry new_server;
2378 SilcBool initiator = FALSE;
2379 SilcBool backup_local = FALSE;
2380 SilcBool backup_router = FALSE;
2381 char *backup_replace_ip = NULL;
2382 SilcUInt16 backup_replace_port = 0;
2383 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2384 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2386 /* If we are backup router and this is incoming server connection
2387 and we do not have connection to primary router, do not allow
2389 if (server->server_type == SILC_BACKUP_ROUTER &&
2390 entry->conn_type == SILC_CONN_SERVER &&
2391 !SILC_PRIMARY_ROUTE(server)) {
2392 SILC_LOG_INFO(("Will not accept server connection because we do "
2393 "not have primary router connection established"));
2394 silc_server_disconnect_remote(server, sock,
2395 SILC_STATUS_ERR_PERM_DENIED,
2396 "We do not have connection to primary "
2397 "router established, try later");
2398 silc_server_config_unref(&entry->cconfig);
2399 silc_server_config_unref(&entry->sconfig);
2400 silc_server_config_unref(&entry->rconfig);
2401 silc_server_free_sock_user_data(server, sock, NULL);
2402 server->stat.auth_failures++;
2406 if (entry->conn_type == SILC_CONN_ROUTER) {
2407 /* Verify whether this connection is after all allowed to connect */
2408 if (!silc_server_connection_allowed(server, sock,
2410 &server->config->param,
2411 rconn ? rconn->param : NULL,
2412 silc_connauth_get_ske(connauth))) {
2413 silc_server_config_unref(&entry->cconfig);
2414 silc_server_config_unref(&entry->sconfig);
2415 silc_server_config_unref(&entry->rconfig);
2416 server->stat.auth_failures++;
2422 param = rconn->param;
2424 if (!param->keepalive_secs)
2425 param->keepalive_secs = server->config->param.keepalive_secs;
2427 if (!param->qos && server->config->param.qos) {
2428 param->qos = server->config->param.qos;
2429 param->qos_rate_limit = server->config->param.qos_rate_limit;
2430 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2431 param->qos_limit_sec = server->config->param.qos_limit_sec;
2432 param->qos_limit_usec = server->config->param.qos_limit_usec;
2436 initiator = rconn->initiator;
2437 backup_local = rconn->backup_local;
2438 backup_router = rconn->backup_router;
2439 backup_replace_ip = rconn->backup_replace_ip;
2440 backup_replace_port = rconn->backup_replace_port;
2444 if (entry->conn_type == SILC_CONN_SERVER) {
2445 /* Verify whether this connection is after all allowed to connect */
2446 if (!silc_server_connection_allowed(server, sock,
2448 &server->config->param,
2449 srvconn ? srvconn->param : NULL,
2450 silc_connauth_get_ske(connauth))) {
2451 server->stat.auth_failures++;
2455 if (srvconn->param) {
2456 param = srvconn->param;
2458 if (!param->keepalive_secs)
2459 param->keepalive_secs = server->config->param.keepalive_secs;
2461 if (!param->qos && server->config->param.qos) {
2462 param->qos = server->config->param.qos;
2463 param->qos_rate_limit = server->config->param.qos_rate_limit;
2464 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2465 param->qos_limit_sec = server->config->param.qos_limit_sec;
2466 param->qos_limit_usec = server->config->param.qos_limit_usec;
2470 backup_router = srvconn->backup_router;
2474 /* If we are primary router and we have backup router configured
2475 but it has not connected to use yet, do not accept any other
2477 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2478 !server->backup_router && !backup_router) {
2479 SilcServerConfigRouter *router;
2480 router = silc_server_config_get_backup_router(server);
2481 if (router && strcmp(server->config->server_info->primary->server_ip,
2483 silc_server_find_socket_by_host(server,
2485 router->backup_replace_ip, 0)) {
2486 SILC_LOG_INFO(("Will not accept connections because we do "
2487 "not have backup router connection established"));
2488 silc_server_disconnect_remote(server, sock,
2489 SILC_STATUS_ERR_PERM_DENIED,
2490 "We do not have connection to backup "
2491 "router established, try later");
2492 silc_server_config_unref(&entry->cconfig);
2493 silc_server_config_unref(&entry->sconfig);
2494 silc_server_config_unref(&entry->rconfig);
2495 silc_server_free_sock_user_data(server, sock, NULL);
2496 server->stat.auth_failures++;
2498 /* From here on, wait 20 seconds for the backup router to appear. */
2499 silc_schedule_task_add_timeout(server->schedule,
2500 silc_server_backup_router_wait,
2501 (void *)server, 20, 0);
2506 SILC_LOG_DEBUG(("Remote host is %s",
2507 entry->conn_type == SILC_CONN_SERVER ?
2508 "server" : (backup_router ?
2509 "backup router" : "router")));
2510 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2511 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2512 "server" : (backup_router ?
2513 "backup router" : "router")));
2515 /* Add the server into server cache. The server name and Server ID
2516 is updated after we have received NEW_SERVER packet from the
2517 server. We mark ourselves as router for this server if we really
2520 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2521 server->local_list : (backup_router ?
2522 server->local_list :
2523 server->global_list)),
2525 (entry->conn_type == SILC_CONN_SERVER ?
2526 SILC_SERVER : SILC_ROUTER),
2528 (entry->conn_type == SILC_CONN_SERVER ?
2529 server->id_entry : (backup_router ?
2530 server->id_entry : NULL)),
2533 SILC_LOG_ERROR(("Could not add new server to cache"));
2534 silc_server_disconnect_remote(server, sock,
2535 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2536 silc_server_config_unref(&entry->cconfig);
2537 silc_server_config_unref(&entry->sconfig);
2538 silc_server_config_unref(&entry->rconfig);
2539 silc_server_free_sock_user_data(server, sock, NULL);
2540 server->stat.auth_failures++;
2543 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2544 entry->data.conn_type = entry->conn_type;
2546 id_entry = (void *)new_server;
2548 /* If the incoming connection is router and marked as backup router
2549 then add it to be one of our backups */
2550 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2551 /* Change it back to SERVER type since that's what it really is. */
2553 entry->data.conn_type = SILC_CONN_SERVER;
2554 new_server->server_type = SILC_BACKUP_ROUTER;
2556 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2557 ("Backup router %s is now online",
2560 /* Remove the backup waiting with timeout */
2561 silc_schedule_task_add_timeout(server->schedule,
2562 silc_server_backup_router_wait,
2563 (void *)server, 10, 0);
2567 if (entry->data.conn_type == SILC_CONN_SERVER) {
2568 server->stat.my_servers++;
2569 server->stat.servers++;
2570 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2572 server->stat.my_routers++;
2573 server->stat.routers++;
2574 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2577 /* Check whether this connection is to be our primary router connection
2578 if we do not already have the primary route. */
2579 if (!backup_router &&
2580 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2581 if (silc_server_config_is_primary_route(server) && !initiator)
2584 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2585 server->standalone = FALSE;
2586 if (!server->id_entry->router) {
2587 server->id_entry->router = id_entry;
2588 server->router = id_entry;
2600 /* Add connection to server->conns so that we know we have connection
2602 sconn = silc_calloc(1, sizeof(*sconn));
2603 sconn->server = server;
2605 sconn->remote_host = strdup(hostname);
2606 sconn->remote_port = port;
2607 silc_dlist_add(server->conns, sconn);
2608 idata->sconn = sconn;
2609 idata->sconn->callback = NULL;
2610 idata->last_receive = time(NULL);
2612 /* Add the common data structure to the ID entry. */
2613 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2614 silc_packet_set_context(sock, id_entry);
2616 /* Connection has been fully established now. Everything is ok. */
2617 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2619 /* Perform Quality of Service */
2621 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2622 param->qos_rate_limit, param->qos_bytes_limit,
2623 param->qos_limit_sec, param->qos_limit_usec);
2625 silc_server_config_unref(&entry->cconfig);
2626 silc_server_config_unref(&entry->sconfig);
2627 silc_server_config_unref(&entry->rconfig);
2631 silc_ske_free(silc_connauth_get_ske(connauth));
2632 silc_connauth_free(connauth);
2635 /* SKE completion callback. We set the new keys into use here. */
2638 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2639 SilcSKESecurityProperties prop,
2640 SilcSKEKeyMaterial keymat,
2641 SilcSKERekeyMaterial rekey,
2644 SilcPacketStream sock = context;
2645 SilcUnknownEntry entry = silc_packet_get_context(sock);
2646 SilcIDListData idata = (SilcIDListData)entry;
2647 SilcServer server = entry->server;
2648 SilcConnAuth connauth;
2649 SilcCipher send_key, receive_key;
2650 SilcHmac hmac_send, hmac_receive;
2657 if (status != SILC_SKE_STATUS_OK) {
2659 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2660 silc_ske_map_status(status), entry->hostname, entry->ip));
2662 silc_server_disconnect_remote(server, sock,
2663 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2664 silc_server_config_unref(&entry->cconfig);
2665 silc_server_config_unref(&entry->sconfig);
2666 silc_server_config_unref(&entry->rconfig);
2667 silc_server_free_sock_user_data(server, sock, NULL);
2671 SILC_LOG_DEBUG(("Setting keys into use"));
2673 /* Set the keys into use. The data will be encrypted after this. */
2674 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2675 &hmac_send, &hmac_receive, &hash)) {
2676 /* Error setting keys */
2678 silc_server_disconnect_remote(server, sock,
2679 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2680 silc_server_free_sock_user_data(server, sock, NULL);
2683 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2684 hmac_receive, FALSE);
2686 idata->rekey = rekey;
2687 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2688 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2689 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2691 silc_hash_alloc(silc_hash_get_name(prop->hash), &idata->hash);
2693 SILC_LOG_DEBUG(("Starting connection authentication"));
2694 server->stat.auth_attempts++;
2696 connauth = silc_connauth_alloc(server->schedule, ske,
2697 server->config->conn_auth_timeout);
2699 /** Error allocating auth protocol */
2701 silc_server_disconnect_remote(server, sock,
2702 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2703 silc_server_config_unref(&entry->cconfig);
2704 silc_server_config_unref(&entry->sconfig);
2705 silc_server_config_unref(&entry->rconfig);
2706 silc_server_free_sock_user_data(server, sock, NULL);
2710 /* Start connection authentication */
2712 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2713 silc_server_accept_auth_compl, sock);
2716 /* Accept new TCP connection */
2718 static void silc_server_accept_new_connection(SilcNetStatus status,
2722 SilcServer server = context;
2723 SilcPacketStream packet_stream;
2724 SilcServerConfigClient *cconfig = NULL;
2725 SilcServerConfigServer *sconfig = NULL;
2726 SilcServerConfigRouter *rconfig = NULL;
2727 SilcServerConfigDeny *deny;
2728 SilcUnknownEntry entry;
2730 SilcSKEParamsStruct params;
2731 char *hostname, *ip;
2734 SILC_LOG_DEBUG(("Accepting new connection"));
2736 /* Check for maximum allowed connections */
2737 server->stat.conn_attempts++;
2738 if (silc_dlist_count(server->conns) >
2739 server->config->param.connections_max) {
2740 SILC_LOG_ERROR(("Refusing connection, server is full"));
2741 server->stat.conn_failures++;
2742 silc_stream_destroy(stream);
2746 /* Get hostname, IP and port */
2747 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2748 (const char **)&ip, &port)) {
2749 /* Bad socket stream */
2750 server->stat.conn_failures++;
2751 silc_stream_destroy(stream);
2755 /* Create packet stream */
2756 packet_stream = silc_packet_stream_create(server->packet_engine,
2757 server->schedule, stream);
2758 if (!packet_stream) {
2759 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2760 server->stat.conn_failures++;
2761 silc_stream_destroy(stream);
2764 server->stat.conn_num++;
2766 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2768 /* Set source ID to packet stream */
2769 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2772 server->stat.conn_failures++;
2773 silc_packet_stream_destroy(packet_stream);
2777 /* Check whether this connection is denied to connect to us. */
2778 deny = silc_server_config_find_denied(server, ip);
2780 deny = silc_server_config_find_denied(server, hostname);
2782 /* The connection is denied */
2783 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2784 silc_server_disconnect_remote(server, packet_stream,
2785 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2787 silc_server_free_sock_user_data(server, packet_stream, NULL);
2791 /* Check whether we have configured this sort of connection at all. We
2792 have to check all configurations since we don't know what type of
2793 connection this is. */
2794 if (!(cconfig = silc_server_config_find_client(server, ip)))
2795 cconfig = silc_server_config_find_client(server, hostname);
2796 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2797 sconfig = silc_server_config_find_server_conn(server, hostname);
2798 if (server->server_type == SILC_ROUTER)
2799 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2800 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2801 if (!cconfig && !sconfig && !rconfig) {
2802 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2803 server->stat.conn_failures++;
2804 silc_server_disconnect_remote(server, packet_stream,
2805 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2806 silc_server_free_sock_user_data(server, packet_stream, NULL);
2810 /* The connection is allowed */
2811 entry = silc_calloc(1, sizeof(*entry));
2813 server->stat.conn_failures++;
2814 silc_server_disconnect_remote(server, packet_stream,
2815 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2816 silc_server_free_sock_user_data(server, packet_stream, NULL);
2819 entry->hostname = hostname;
2822 entry->server = server;
2823 entry->data.conn_type = SILC_CONN_UNKNOWN;
2824 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2825 silc_packet_set_context(packet_stream, entry);
2827 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2829 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2830 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2831 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2833 /* Take flags for key exchange. Since we do not know what type of connection
2834 this is, we go through all found configurations and use the global ones
2835 as well. This will result always into strictest key exchange flags. */
2836 memset(¶ms, 0, sizeof(params));
2837 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2838 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2839 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2840 if (server->config->param.key_exchange_pfs)
2841 params.flags |= SILC_SKE_SP_FLAG_PFS;
2843 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2844 server->stat.conn_attempts++;
2846 /* Start SILC Key Exchange protocol */
2847 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2848 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2849 server->public_key, server->private_key,
2852 server->stat.conn_failures++;
2853 silc_server_disconnect_remote(server, packet_stream,
2854 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2855 silc_server_free_sock_user_data(server, packet_stream, NULL);
2858 silc_ske_set_callbacks(ske, silc_server_verify_key,
2859 silc_server_accept_completed, packet_stream);
2861 /* Start key exchange protocol */
2862 params.version = silc_version_string;
2863 params.timeout_secs = server->config->key_exchange_timeout;
2864 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2868 /********************************** Rekey ***********************************/
2870 /* Initiator rekey completion callback */
2872 static void silc_server_rekey_completion(SilcSKE ske,
2873 SilcSKEStatus status,
2874 const SilcSKESecurityProperties prop,
2875 const SilcSKEKeyMaterial keymat,
2876 SilcSKERekeyMaterial rekey,
2879 SilcPacketStream sock = context;
2880 SilcIDListData idata = silc_packet_get_context(sock);
2881 SilcServer server = idata->sconn->server;
2883 idata->sconn->op = NULL;
2884 if (status != SILC_SKE_STATUS_OK) {
2885 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2886 idata->sconn->remote_host));
2890 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2891 idata->sconn->remote_host, idata->sconn->remote_port,
2892 SILC_CONNTYPE_STRING(idata->conn_type)));
2894 /* Save rekey data for next rekey */
2895 idata->rekey = rekey;
2897 /* Register new rekey timeout */
2898 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2899 sock, idata->sconn->rekey_timeout, 0);
2902 /* Rekey callback. Start rekey as initiator */
2904 SILC_TASK_CALLBACK(silc_server_do_rekey)
2906 SilcServer server = app_context;
2907 SilcPacketStream sock = context;
2908 SilcIDListData idata = silc_packet_get_context(sock);
2911 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2913 /* Do not execute rekey with disabled connections */
2914 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2917 /* If another protocol is active do not start rekey */
2918 if (idata->sconn->op) {
2919 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2920 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2925 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2926 idata->sconn->remote_host, idata->sconn->remote_port,
2927 SILC_CONNTYPE_STRING(idata->conn_type)));
2930 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2931 server->public_key, NULL, sock);
2935 /* Set SKE callbacks */
2936 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2939 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2942 /* Responder rekey completion callback */
2945 silc_server_rekey_resp_completion(SilcSKE ske,
2946 SilcSKEStatus status,
2947 const SilcSKESecurityProperties prop,
2948 const SilcSKEKeyMaterial keymat,
2949 SilcSKERekeyMaterial rekey,
2952 SilcPacketStream sock = context;
2953 SilcIDListData idata = silc_packet_get_context(sock);
2955 idata->sconn->op = NULL;
2956 if (status != SILC_SKE_STATUS_OK) {
2957 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2958 idata->sconn->remote_host));
2962 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2963 idata->sconn->remote_host, idata->sconn->remote_port,
2964 SILC_CONNTYPE_STRING(idata->conn_type)));
2966 /* Save rekey data for next rekey */
2967 idata->rekey = rekey;
2970 /* Start rekey as responder */
2972 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2975 SilcIDListData idata = silc_packet_get_context(sock);
2978 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
2979 idata->sconn->remote_host, idata->sconn->remote_port,
2980 SILC_CONNTYPE_STRING(idata->conn_type), sock));
2983 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2984 server->public_key, NULL, sock);
2986 silc_packet_free(packet);
2990 /* Set SKE callbacks */
2991 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2994 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2999 /****************************** Disconnection *******************************/
3001 /* Destroys packet stream. */
3003 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3005 silc_packet_stream_unref(context);
3008 /* Closes connection to socket connection */
3010 void silc_server_close_connection(SilcServer server,
3011 SilcPacketStream sock)
3013 SilcIDListData idata = silc_packet_get_context(sock);
3015 const char *hostname;
3018 if (!silc_packet_stream_is_valid(sock))
3019 memset(tmp, 0, sizeof(tmp));
3020 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3021 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3022 NULL, &hostname, NULL, &port);
3023 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3024 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3025 tmp[0] ? tmp : ""));
3027 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3029 if (idata && idata->sconn) {
3030 silc_server_connection_free(idata->sconn);
3031 idata->sconn = NULL;
3034 /* Take a reference and then destroy the stream. The last reference
3035 is released later in a timeout callback. */
3036 silc_packet_stream_ref(sock);
3037 silc_packet_stream_destroy(sock);
3039 /* Close connection with timeout */
3040 server->stat.conn_num--;
3041 silc_schedule_task_del_by_all(server->schedule, 0,
3042 silc_server_close_connection_final, sock);
3043 silc_schedule_task_add_timeout(server->schedule,
3044 silc_server_close_connection_final,
3048 /* Sends disconnect message to remote connection and disconnects the
3051 void silc_server_disconnect_remote(SilcServer server,
3052 SilcPacketStream sock,
3053 SilcStatus status, ...)
3055 unsigned char buf[512];
3062 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock));
3064 va_start(ap, status);
3065 cp = va_arg(ap, char *);
3067 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3070 /* Send SILC_PACKET_DISCONNECT */
3071 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3072 SILC_STR_UI_CHAR(status),
3073 SILC_STR_UI8_STRING(cp ? buf : NULL),
3076 /* Close connection */
3077 silc_server_close_connection(server, sock);
3080 /* Frees client data and notifies about client's signoff. */
3082 void silc_server_free_client_data(SilcServer server,
3083 SilcPacketStream sock,
3084 SilcClientEntry client,
3086 const char *signoff)
3088 SILC_LOG_DEBUG(("Freeing client %p data", client));
3091 /* Check if anyone is watching this nickname */
3092 if (server->server_type == SILC_ROUTER)
3093 silc_server_check_watcher_list(server, client, NULL,
3094 SILC_NOTIFY_TYPE_SIGNOFF);
3096 /* Send SIGNOFF notify to routers. */
3098 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3099 SILC_BROADCAST(server), client->id,
3103 /* Remove client from all channels */
3105 silc_server_remove_from_channels(server, NULL, client,
3106 TRUE, (char *)signoff, TRUE, FALSE);
3108 silc_server_remove_from_channels(server, NULL, client,
3109 FALSE, NULL, FALSE, FALSE);
3111 /* Remove this client from watcher list if it is */
3112 silc_server_del_from_watcher_list(server, client);
3114 /* Remove client's public key from repository, this will free it too. */
3115 if (client->data.public_key) {
3116 silc_skr_del_public_key(server->repository, client->data.public_key,
3118 client->data.public_key = NULL;
3121 /* Update statistics */
3122 server->stat.my_clients--;
3123 server->stat.clients--;
3124 if (server->stat.cell_clients)
3125 server->stat.cell_clients--;
3126 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3127 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3128 silc_schedule_task_del_by_context(server->schedule, client);
3130 if (client->data.sconn) {
3131 silc_server_connection_free(client->data.sconn);
3132 client->data.sconn = NULL;
3135 /* We will not delete the client entry right away. We will take it
3136 into history (for WHOWAS command) for 5 minutes, unless we're
3137 shutting down server. */
3138 if (!server->server_shutdown) {
3139 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3141 client->router = NULL;
3142 client->connection = NULL;
3143 client->data.created = silc_time();
3144 silc_dlist_del(server->expired_clients, client);
3145 silc_dlist_add(server->expired_clients, client);
3147 /* Delete directly since we're shutting down server */
3148 SILC_LOG_DEBUG(("Delete client directly"));
3149 silc_idlist_del_data(client);
3150 silc_idlist_del_client(server->local_list, client);
3154 /* Frees user_data pointer from socket connection object. This also sends
3155 appropriate notify packets to the network to inform about leaving
3158 void silc_server_free_sock_user_data(SilcServer server,
3159 SilcPacketStream sock,
3160 const char *signoff_message)
3162 SilcIDListData idata;
3169 SILC_LOG_DEBUG(("Start, sock %p", sock));
3171 idata = silc_packet_get_context(sock);
3175 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3178 /* Cancel active protocols */
3180 if (idata->sconn && idata->sconn->op) {
3181 SILC_LOG_DEBUG(("Abort active protocol"));
3182 silc_async_abort(idata->sconn->op, NULL, NULL);
3184 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3185 ((SilcUnknownEntry)idata)->op) {
3186 SILC_LOG_DEBUG(("Abort active protocol"));
3187 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3191 switch (idata->conn_type) {
3192 case SILC_CONN_CLIENT:
3194 SilcClientEntry client_entry = (SilcClientEntry)idata;
3195 silc_server_free_client_data(server, sock, client_entry, TRUE,
3197 silc_packet_set_context(sock, NULL);
3201 case SILC_CONN_SERVER:
3202 case SILC_CONN_ROUTER:
3204 SilcServerEntry user_data = (SilcServerEntry)idata;
3205 SilcServerEntry backup_router = NULL;
3207 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3210 backup_router = silc_server_backup_get(server, user_data->id);
3212 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3213 backup_router == server->id_entry &&
3214 idata->conn_type != SILC_CONN_ROUTER)
3215 backup_router = NULL;
3217 if (server->server_shutdown || server->backup_noswitch)
3218 backup_router = NULL;
3220 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3221 NULL, NULL, &ip, &port);
3223 /* If this was our primary router connection then we're lost to
3224 the outside world. */
3225 if (server->router == user_data) {
3226 /* Check whether we have a backup router connection */
3227 if (!backup_router || backup_router == user_data) {
3228 if (!server->no_reconnect)
3229 silc_server_create_connections(server);
3230 server->id_entry->router = NULL;
3231 server->router = NULL;
3232 server->standalone = TRUE;
3233 server->backup_primary = FALSE;
3234 backup_router = NULL;
3236 if (server->id_entry != backup_router) {
3237 SILC_LOG_INFO(("New primary router is backup router %s",
3238 backup_router->server_name));
3239 server->id_entry->router = backup_router;
3240 server->router = backup_router;
3241 server->router_connect = time(0);
3242 server->backup_primary = TRUE;
3243 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3245 /* Send START_USE to backup router to indicate we have switched */
3246 silc_server_backup_send_start_use(server,
3247 backup_router->connection,
3250 SILC_LOG_INFO(("We are now new primary router in this cell"));
3251 server->id_entry->router = NULL;
3252 server->router = NULL;
3253 server->standalone = TRUE;
3256 /* We stop here to take a breath */
3259 if (server->backup_router) {
3260 server->server_type = SILC_ROUTER;
3262 /* We'll need to constantly try to reconnect to the primary
3263 router so that we'll see when it comes back online. */
3264 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3265 silc_server_backup_connected,
3269 /* Mark this connection as replaced */
3270 silc_server_backup_replaced_add(server, user_data->id,
3273 } else if (backup_router) {
3274 SILC_LOG_INFO(("Enabling the use of backup router %s",
3275 backup_router->server_name));
3277 /* Mark this connection as replaced */
3278 silc_server_backup_replaced_add(server, user_data->id,
3280 } else if (server->server_type == SILC_SERVER &&
3281 idata->conn_type == SILC_CONN_ROUTER) {
3282 /* Reconnect to the router (backup) */
3283 if (!server->no_reconnect)
3284 silc_server_create_connections(server);
3287 if (user_data->server_name)
3288 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3289 ("Server %s signoff", user_data->server_name));
3291 if (!backup_router) {
3292 /* Remove all servers that are originated from this server, and
3293 remove the clients of those servers too. */
3294 silc_server_remove_servers_by_server(server, user_data, TRUE);
3297 /* Remove the clients that this server owns as they will become
3298 invalid now too. For backup router the server is actually
3299 coming from the primary router, so mark that as the owner
3301 if (server->server_type == SILC_BACKUP_ROUTER &&
3302 sock->type == SILC_CONN_SERVER)
3303 silc_server_remove_clients_by_server(server, server->router,
3307 silc_server_remove_clients_by_server(server, user_data,
3310 /* Remove channels owned by this server */
3311 if (server->server_type == SILC_SERVER)
3312 silc_server_remove_channels_by_server(server, user_data);
3314 /* Enable local server connections that may be disabled */
3315 silc_server_local_servers_toggle_enabled(server, TRUE);
3317 /* Update the client entries of this server to the new backup
3318 router. If we are the backup router we also resolve the real
3319 servers for the clients. After updating is over this also
3320 removes the clients that this server explicitly owns. */
3321 silc_server_update_clients_by_server(server, user_data,
3322 backup_router, TRUE);
3324 /* If we are router and just lost our primary router (now standlaone)
3325 we remove everything that was behind it, since we don't know
3327 if (server->server_type == SILC_ROUTER && server->standalone)
3328 /* Remove all servers that are originated from this server, and
3329 remove the clients of those servers too. */
3330 silc_server_remove_servers_by_server(server, user_data, TRUE);
3332 /* Finally remove the clients that are explicitly owned by this
3333 server. They go down with the server. */
3334 silc_server_remove_clients_by_server(server, user_data,
3337 /* Update our server cache to use the new backup router too. */
3338 silc_server_update_servers_by_server(server, user_data, backup_router);
3339 if (server->server_type == SILC_SERVER)
3340 silc_server_update_channels_by_server(server, user_data,
3343 /* Send notify about primary router going down to local operators */
3344 if (server->backup_router)
3345 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3346 SILC_NOTIFY_TYPE_NONE,
3347 ("%s switched to backup router %s "
3348 "(we are primary router now)",
3349 server->server_name, server->server_name));
3350 else if (server->router)
3351 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3352 SILC_NOTIFY_TYPE_NONE,
3353 ("%s switched to backup router %s",
3354 server->server_name,
3355 server->router->server_name));
3357 server->backup_noswitch = FALSE;
3360 silc_server_connection_free(idata->sconn);
3361 idata->sconn = NULL;
3365 if (idata->conn_type == SILC_CONN_SERVER) {
3366 server->stat.my_servers--;
3367 server->stat.servers--;
3368 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3369 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3370 server->stat.my_routers--;
3371 server->stat.routers--;
3372 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3374 if (server->server_type == SILC_ROUTER)
3375 server->stat.cell_servers--;
3377 /* Free the server entry */
3378 silc_server_backup_del(server, user_data);
3379 silc_server_backup_replaced_del(server, user_data);
3380 silc_idlist_del_data(user_data);
3381 if (!silc_idlist_del_server(server->local_list, user_data))
3382 silc_idlist_del_server(server->global_list, user_data);
3384 if (backup_router && backup_router != server->id_entry) {
3385 /* Announce all of our stuff that was created about 5 minutes ago.
3386 The backup router knows all the other stuff already. */
3387 if (server->server_type == SILC_ROUTER)
3388 silc_server_announce_servers(server, FALSE, time(0) - 300,
3389 backup_router->connection);
3391 /* Announce our clients and channels to the router */
3392 silc_server_announce_clients(server, time(0) - 300,
3393 backup_router->connection);
3394 silc_server_announce_channels(server, time(0) - 300,
3395 backup_router->connection);
3398 silc_packet_set_context(sock, NULL);
3404 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3406 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3409 if (server->router_conn == idata->sconn) {
3410 if (!server->no_reconnect)
3411 silc_server_create_connections(server);
3412 server->router_conn = NULL;
3415 silc_server_connection_free(idata->sconn);
3416 idata->sconn = NULL;
3418 silc_idlist_del_data(idata);
3420 silc_packet_set_context(sock, NULL);
3426 /* Removes client from all channels it has joined. This is used when client
3427 connection is disconnected. If the client on a channel is last, the
3428 channel is removed as well. This sends the SIGNOFF notify types. */
3430 void silc_server_remove_from_channels(SilcServer server,
3431 SilcPacketStream sock,
3432 SilcClientEntry client,
3434 const char *signoff_message,
3438 SilcChannelEntry channel;
3439 SilcChannelClientEntry chl;
3440 SilcHashTableList htl;
3441 SilcBuffer clidp = NULL;
3446 if (notify && !client->id)
3449 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3450 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3453 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3458 /* Remove the client from all channels. The client is removed from
3459 the channels' user list. */
3460 silc_hash_table_list(client->channels, &htl);
3461 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3462 channel = chl->channel;
3464 /* Remove channel if this is last client leaving the channel, unless
3465 the channel is permanent. */
3466 if (server->server_type != SILC_SERVER &&
3467 silc_hash_table_count(channel->user_list) < 2) {
3468 silc_server_channel_delete(server, channel);
3472 silc_hash_table_del(client->channels, channel);
3473 silc_hash_table_del(channel->user_list, client);
3474 channel->user_count--;
3476 /* If there is no global users on the channel anymore mark the channel
3477 as local channel. Do not check if the removed client is local client. */
3478 if (server->server_type == SILC_SERVER && channel->global_users &&
3479 chl->client->router && !silc_server_channel_has_global(channel))
3480 channel->global_users = FALSE;
3482 memset(chl, 'A', sizeof(*chl));
3485 /* Update statistics */
3486 if (SILC_IS_LOCAL(client))
3487 server->stat.my_chanclients--;
3488 if (server->server_type == SILC_ROUTER) {
3489 server->stat.cell_chanclients--;
3490 server->stat.chanclients--;
3493 /* If there is not at least one local user on the channel then we don't
3494 need the channel entry anymore, we can remove it safely, unless the
3495 channel is permanent channel */
3496 if (server->server_type == SILC_SERVER &&
3497 !silc_server_channel_has_local(channel)) {
3498 /* Notify about leaving client if this channel has global users. */
3499 if (notify && channel->global_users)
3500 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3501 SILC_NOTIFY_TYPE_SIGNOFF,
3502 signoff_message ? 2 : 1,
3503 clidp->data, silc_buffer_len(clidp),
3504 signoff_message, signoff_message ?
3505 strlen(signoff_message) : 0);
3507 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3508 silc_server_channel_delete(server, channel);
3512 /* Send notify to channel about client leaving SILC and channel too */
3514 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3515 SILC_NOTIFY_TYPE_SIGNOFF,
3516 signoff_message ? 2 : 1,
3517 clidp->data, silc_buffer_len(clidp),
3518 signoff_message, signoff_message ?
3519 strlen(signoff_message) : 0);
3521 if (killed && clidp) {
3522 /* Remove the client from channel's invite list */
3523 if (channel->invite_list &&
3524 silc_hash_table_count(channel->invite_list)) {
3526 SilcArgumentPayload iargs;
3527 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3528 silc_buffer_len(clidp), 3);
3529 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3530 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3531 silc_buffer_free(ab);
3532 silc_argument_payload_free(iargs);
3536 /* Don't create keys if we are shutting down */
3537 if (server->server_shutdown)
3540 /* Re-generate channel key if needed */
3541 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3542 if (!silc_server_create_channel_key(server, channel, 0))
3545 /* Send the channel key to the channel. The key of course is not sent
3546 to the client who was removed from the channel. */
3547 silc_server_send_channel_key(server, client->connection, channel,
3548 server->server_type == SILC_ROUTER ?
3549 FALSE : !server->standalone);
3553 silc_hash_table_list_reset(&htl);
3555 silc_buffer_free(clidp);
3558 /* Removes client from one channel. This is used for example when client
3559 calls LEAVE command to remove itself from the channel. Returns TRUE
3560 if channel still exists and FALSE if the channel is removed when
3561 last client leaves the channel. If `notify' is FALSE notify messages
3564 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3565 SilcPacketStream sock,
3566 SilcChannelEntry channel,
3567 SilcClientEntry client,
3570 SilcChannelClientEntry chl;
3573 SILC_LOG_DEBUG(("Removing %s from channel %s",
3574 silc_id_render(client->id, SILC_ID_CLIENT),
3575 channel->channel_name));
3577 /* Get the entry to the channel, if this client is not on the channel
3579 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3582 /* Remove channel if this is last client leaving the channel, unless
3583 the channel is permanent. */
3584 if (server->server_type != SILC_SERVER &&
3585 silc_hash_table_count(channel->user_list) < 2) {
3586 silc_server_channel_delete(server, channel);
3590 silc_hash_table_del(client->channels, channel);
3591 silc_hash_table_del(channel->user_list, client);
3592 channel->user_count--;
3594 /* If there is no global users on the channel anymore mark the channel
3595 as local channel. Do not check if the client is local client. */
3596 if (server->server_type == SILC_SERVER && channel->global_users &&
3597 chl->client->router && !silc_server_channel_has_global(channel))
3598 channel->global_users = FALSE;
3600 memset(chl, 'O', sizeof(*chl));
3603 /* Update statistics */
3604 if (SILC_IS_LOCAL(client))
3605 server->stat.my_chanclients--;
3606 if (server->server_type == SILC_ROUTER) {
3607 server->stat.cell_chanclients--;
3608 server->stat.chanclients--;
3611 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3615 /* If there is not at least one local user on the channel then we don't
3616 need the channel entry anymore, we can remove it safely, unless the
3617 channel is permanent channel */
3618 if (server->server_type == SILC_SERVER &&
3619 !silc_server_channel_has_local(channel)) {
3620 /* Notify about leaving client if this channel has global users. */
3621 if (notify && channel->global_users)
3622 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3623 SILC_NOTIFY_TYPE_LEAVE, 1,
3624 clidp->data, silc_buffer_len(clidp));
3626 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3627 silc_server_channel_delete(server, channel);
3628 silc_buffer_free(clidp);
3632 /* Send notify to channel about client leaving the channel */
3634 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3635 SILC_NOTIFY_TYPE_LEAVE, 1,
3636 clidp->data, silc_buffer_len(clidp));
3638 silc_buffer_free(clidp);
3642 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3643 function may be used only by router. In real SILC network all channels
3644 are created by routers thus this function is never used by normal
3647 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3648 SilcServerID *router_id,
3654 SilcChannelID *channel_id;
3655 SilcChannelEntry entry;
3656 SilcCipher send_key, receive_key;
3659 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3662 cipher = SILC_DEFAULT_CIPHER;
3664 hmac = SILC_DEFAULT_HMAC;
3666 /* Allocate cipher */
3667 if (!silc_cipher_alloc(cipher, &send_key))
3669 if (!silc_cipher_alloc(cipher, &receive_key)) {
3670 silc_cipher_free(send_key);
3675 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3676 silc_cipher_free(send_key);
3677 silc_cipher_free(receive_key);
3681 channel_name = strdup(channel_name);
3683 /* Create the channel ID */
3684 if (!silc_id_create_channel_id(server, router_id, server->rng,
3686 silc_free(channel_name);
3687 silc_cipher_free(send_key);
3688 silc_cipher_free(receive_key);
3689 silc_hmac_free(newhmac);
3693 /* Create the channel */
3694 entry = silc_idlist_add_channel(server->local_list, channel_name,
3695 SILC_CHANNEL_MODE_NONE, channel_id,
3696 NULL, send_key, receive_key, newhmac);
3698 silc_free(channel_name);
3699 silc_cipher_free(send_key);
3700 silc_cipher_free(receive_key);
3701 silc_hmac_free(newhmac);
3702 silc_free(channel_id);
3706 entry->cipher = strdup(cipher);
3707 entry->hmac_name = strdup(hmac);
3709 /* Now create the actual key material */
3710 if (!silc_server_create_channel_key(server, entry,
3711 silc_cipher_get_key_len(send_key) / 8)) {
3712 silc_idlist_del_channel(server->local_list, entry);
3716 /* Notify other routers about the new channel. We send the packet
3717 to our primary route. */
3719 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3720 channel_name, entry->id,
3721 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3724 /* Distribute to backup routers */
3725 if (broadcast && server->server_type == SILC_ROUTER) {
3727 unsigned char cid[32];
3728 SilcUInt32 name_len = strlen(channel_name);
3731 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3732 packet = silc_channel_payload_encode(channel_name, name_len,
3733 cid, id_len, entry->mode);
3734 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3735 packet->data, silc_buffer_len(packet), FALSE,
3737 silc_buffer_free(packet);
3740 server->stat.my_channels++;
3741 if (server->server_type == SILC_ROUTER) {
3742 server->stat.channels++;
3743 server->stat.cell_channels++;
3744 entry->users_resolved = TRUE;
3750 /* Same as above but creates the channel with Channel ID `channel_id. */
3753 silc_server_create_new_channel_with_id(SilcServer server,
3757 SilcChannelID *channel_id,
3760 SilcChannelEntry entry;
3761 SilcCipher send_key, receive_key;
3764 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3767 cipher = SILC_DEFAULT_CIPHER;
3769 hmac = SILC_DEFAULT_HMAC;
3771 /* Allocate cipher */
3772 if (!silc_cipher_alloc(cipher, &send_key))
3774 if (!silc_cipher_alloc(cipher, &receive_key)) {
3775 silc_cipher_free(send_key);
3780 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3781 silc_cipher_free(send_key);
3782 silc_cipher_free(receive_key);
3786 channel_name = strdup(channel_name);
3788 /* Create the channel */
3789 entry = silc_idlist_add_channel(server->local_list, channel_name,
3790 SILC_CHANNEL_MODE_NONE, channel_id,
3791 NULL, send_key, receive_key, newhmac);
3793 silc_cipher_free(send_key);
3794 silc_cipher_free(receive_key);
3795 silc_hmac_free(newhmac);
3796 silc_free(channel_name);
3800 /* Now create the actual key material */
3801 if (!silc_server_create_channel_key(server, entry,
3802 silc_cipher_get_key_len(send_key) / 8)) {
3803 silc_idlist_del_channel(server->local_list, entry);
3807 /* Notify other routers about the new channel. We send the packet
3808 to our primary route. */
3810 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3811 channel_name, entry->id,
3812 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3815 /* Distribute to backup routers */
3816 if (broadcast && server->server_type == SILC_ROUTER) {
3818 unsigned char cid[32];
3819 SilcUInt32 name_len = strlen(channel_name);
3822 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3823 packet = silc_channel_payload_encode(channel_name, name_len,
3824 cid, id_len, entry->mode);
3825 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3826 packet->data, silc_buffer_len(packet), FALSE,
3828 silc_buffer_free(packet);
3831 server->stat.my_channels++;
3832 if (server->server_type == SILC_ROUTER) {
3833 server->stat.channels++;
3834 server->stat.cell_channels++;
3835 entry->users_resolved = TRUE;
3841 /* Channel's key re-key timeout callback. */
3843 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3845 SilcServer server = app_context;
3846 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3850 /* Return now if we are shutting down */
3851 if (server->server_shutdown)
3854 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3857 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3860 /* Generates new channel key. This is used to create the initial channel key
3861 but also to re-generate new key for channel. If `key_len' is provided
3862 it is the bytes of the key length. */
3864 SilcBool silc_server_create_channel_key(SilcServer server,
3865 SilcChannelEntry channel,
3869 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3872 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3873 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3877 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3879 if (!channel->send_key)
3880 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3881 channel->send_key = NULL;
3884 if (!channel->receive_key)
3885 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3886 silc_cipher_free(channel->send_key);
3887 channel->send_key = channel->receive_key = NULL;
3893 else if (channel->key_len)
3894 len = channel->key_len / 8;
3896 len = silc_cipher_get_key_len(channel->send_key) / 8;
3898 /* Create channel key */
3899 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3902 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3903 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3905 /* Remove old key if exists */
3907 memset(channel->key, 0, channel->key_len / 8);
3908 silc_free(channel->key);
3912 channel->key_len = len * 8;
3913 channel->key = silc_memdup(channel_key, len);
3914 memset(channel_key, 0, sizeof(channel_key));
3916 /* Generate HMAC key from the channel key data and set it */
3918 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3919 memset(channel->key, 0, channel->key_len / 8);
3920 silc_free(channel->key);
3921 silc_cipher_free(channel->send_key);
3922 silc_cipher_free(channel->receive_key);
3923 channel->send_key = channel->receive_key = NULL;
3926 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3927 silc_hmac_set_key(channel->hmac, hash,
3928 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3929 memset(hash, 0, sizeof(hash));
3931 if (server->server_type == SILC_ROUTER) {
3932 if (!channel->rekey)
3933 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3934 channel->rekey->channel = channel;
3935 channel->rekey->key_len = key_len;
3936 if (channel->rekey->task)
3937 silc_schedule_task_del(server->schedule, channel->rekey->task);
3939 channel->rekey->task =
3940 silc_schedule_task_add_timeout(server->schedule,
3941 silc_server_channel_key_rekey,
3942 (void *)channel->rekey,
3943 server->config->channel_rekey_secs, 0);
3949 /* Saves the channel key found in the encoded `key_payload' buffer. This
3950 function is used when we receive Channel Key Payload and also when we're
3951 processing JOIN command reply. Returns entry to the channel. */
3953 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3954 SilcBuffer key_payload,
3955 SilcChannelEntry channel)
3957 SilcChannelKeyPayload payload = NULL;
3959 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3963 /* Decode channel key payload */
3964 payload = silc_channel_key_payload_parse(key_payload->data,
3965 silc_buffer_len(key_payload));
3967 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3972 /* Get the channel entry */
3975 /* Get channel ID */
3976 tmp = silc_channel_key_get_id(payload, &tmp_len);
3977 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3982 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3984 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3986 if (server->server_type == SILC_ROUTER)
3987 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3988 silc_id_render(&id, SILC_ID_CHANNEL)));
3994 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3996 tmp = silc_channel_key_get_key(payload, &tmp_len);
4002 cipher = silc_channel_key_get_cipher(payload, NULL);
4008 /* Remove old key if exists */
4010 memset(channel->key, 0, channel->key_len / 8);
4011 silc_free(channel->key);
4012 silc_cipher_free(channel->send_key);
4013 silc_cipher_free(channel->receive_key);
4016 /* Create new cipher */
4017 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4018 channel->send_key = NULL;
4022 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4023 silc_cipher_free(channel->send_key);
4024 channel->send_key = channel->receive_key = NULL;
4029 if (channel->cipher)
4030 silc_free(channel->cipher);
4031 channel->cipher = strdup(cipher);
4034 channel->key_len = tmp_len * 8;
4035 channel->key = silc_memdup(tmp, tmp_len);
4036 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4037 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4039 /* Generate HMAC key from the channel key data and set it */
4041 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4042 memset(channel->key, 0, channel->key_len / 8);
4043 silc_free(channel->key);
4044 silc_cipher_free(channel->send_key);
4045 silc_cipher_free(channel->receive_key);
4046 channel->send_key = channel->receive_key = NULL;
4049 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4050 silc_hmac_set_key(channel->hmac, hash,
4051 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4053 memset(hash, 0, sizeof(hash));
4054 memset(tmp, 0, tmp_len);
4056 if (server->server_type == SILC_ROUTER) {
4057 if (!channel->rekey)
4058 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4059 channel->rekey->channel = channel;
4060 if (channel->rekey->task)
4061 silc_schedule_task_del(server->schedule, channel->rekey->task);
4063 channel->rekey->task =
4064 silc_schedule_task_add_timeout(server->schedule,
4065 silc_server_channel_key_rekey,
4066 (void *)channel->rekey,
4067 server->config->channel_rekey_secs, 0);
4072 silc_channel_key_payload_free(payload);
4077 /* Returns assembled of all servers in the given ID list. The packet's
4078 form is dictated by the New ID payload. */
4080 static void silc_server_announce_get_servers(SilcServer server,
4081 SilcServerEntry remote,
4083 SilcBuffer *servers,
4084 unsigned long creation_time)
4087 SilcIDCacheEntry id_cache;
4088 SilcServerEntry entry;
4092 /* Go through all clients in the list */
4093 if (silc_idcache_get_all(id_list->servers, &list)) {
4094 silc_list_start(list);
4095 while ((id_cache = silc_list_get(list))) {
4096 entry = (SilcServerEntry)id_cache->context;
4098 /* Do not announce the one we've sending our announcements and
4099 do not announce ourself. Also check the creation time if it's
4101 if ((entry == remote) || (entry == server->id_entry) ||
4102 (creation_time && entry->data.created < creation_time))
4105 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4107 tmp = silc_buffer_realloc(*servers,
4109 silc_buffer_truelen((*servers)) +
4110 silc_buffer_len(idp) :
4111 silc_buffer_len(idp)));
4115 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4116 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4117 silc_buffer_pull(*servers, silc_buffer_len(idp));
4118 silc_buffer_free(idp);
4124 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4130 p = silc_notify_payload_encode(notify, argc, ap);
4136 /* This function is used by router to announce existing servers to our
4137 primary router when we've connected to it. If `creation_time' is non-zero
4138 then only the servers that has been created after the `creation_time'
4139 will be announced. */
4141 void silc_server_announce_servers(SilcServer server, SilcBool global,
4142 unsigned long creation_time,
4143 SilcPacketStream remote)
4145 SilcBuffer servers = NULL;
4147 SILC_LOG_DEBUG(("Announcing servers"));
4149 /* Get servers in local list */
4150 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4151 server->local_list, &servers,
4155 /* Get servers in global list */
4156 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4157 server->global_list, &servers,
4161 silc_buffer_push(servers, servers->data - servers->head);
4162 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4164 /* Send the packet */
4165 silc_server_packet_send(server, remote,
4166 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4167 servers->data, silc_buffer_len(servers));
4169 silc_buffer_free(servers);
4173 /* Returns assembled packet of all clients in the given ID list. The
4174 packet's form is dictated by the New ID Payload. */
4176 static void silc_server_announce_get_clients(SilcServer server,
4178 SilcBuffer *clients,
4180 unsigned long creation_time)
4183 SilcIDCacheEntry id_cache;
4184 SilcClientEntry client;
4187 unsigned char mode[4];
4190 /* Go through all clients in the list */
4191 if (silc_idcache_get_all(id_list->clients, &list)) {
4192 silc_list_start(list);
4193 while ((id_cache = silc_list_get(list))) {
4194 client = (SilcClientEntry)id_cache->context;
4196 if (creation_time && client->data.created < creation_time)
4198 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4200 if (!client->connection && !client->router)
4203 SILC_LOG_DEBUG(("Announce Client ID %s",
4204 silc_id_render(client->id, SILC_ID_CLIENT)));
4206 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4210 tmp2 = silc_buffer_realloc(*clients,
4212 silc_buffer_truelen((*clients)) +
4213 silc_buffer_len(idp) :
4214 silc_buffer_len(idp)));
4218 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4219 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4220 silc_buffer_pull(*clients, silc_buffer_len(idp));
4222 SILC_PUT32_MSB(client->mode, mode);
4224 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4225 2, idp->data, silc_buffer_len(idp),
4227 tmp2 = silc_buffer_realloc(*umodes,
4229 silc_buffer_truelen((*umodes)) +
4230 silc_buffer_len(tmp) :
4231 silc_buffer_len(tmp)));
4235 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4236 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4237 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4238 silc_buffer_free(tmp);
4240 silc_buffer_free(idp);
4245 /* This function is used to announce our existing clients to our router
4246 when we've connected to it. If `creation_time' is non-zero then only
4247 the clients that has been created after the `creation_time' will be
4250 void silc_server_announce_clients(SilcServer server,
4251 unsigned long creation_time,
4252 SilcPacketStream remote)
4254 SilcBuffer clients = NULL;
4255 SilcBuffer umodes = NULL;
4257 SILC_LOG_DEBUG(("Announcing clients"));
4259 /* Get clients in local list */
4260 silc_server_announce_get_clients(server, server->local_list,
4261 &clients, &umodes, creation_time);
4263 /* As router we announce our global list as well */
4264 if (server->server_type == SILC_ROUTER)
4265 silc_server_announce_get_clients(server, server->global_list,
4266 &clients, &umodes, creation_time);
4269 silc_buffer_push(clients, clients->data - clients->head);
4270 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4272 /* Send the packet */
4273 silc_server_packet_send(server, remote,
4274 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4275 clients->data, silc_buffer_len(clients));
4277 silc_buffer_free(clients);
4281 silc_buffer_push(umodes, umodes->data - umodes->head);
4282 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4284 /* Send the packet */
4285 silc_server_packet_send(server, remote,
4286 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4287 umodes->data, silc_buffer_len(umodes));
4289 silc_buffer_free(umodes);
4293 /* Returns channel's topic for announcing it */
4295 void silc_server_announce_get_channel_topic(SilcServer server,
4296 SilcChannelEntry channel,
4301 if (channel->topic) {
4302 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4303 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4305 silc_buffer_len(chidp),
4307 strlen(channel->topic));
4308 silc_buffer_free(chidp);
4312 /* Returns channel's invite and ban lists */
4314 void silc_server_announce_get_inviteban(SilcServer server,
4315 SilcChannelEntry channel,
4319 SilcBuffer list, idp, idp2, tmp2;
4322 SilcHashTableList htl;
4323 const unsigned char a[1] = { 0x03 };
4325 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4327 /* Encode invite list */
4328 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4329 list = silc_buffer_alloc_size(2);
4330 type = silc_hash_table_count(channel->invite_list);
4331 SILC_PUT16_MSB(type, list->data);
4332 silc_hash_table_list(channel->invite_list, &htl);
4333 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4334 list = silc_argument_payload_encode_one(list, tmp2->data,
4335 silc_buffer_len(tmp2),
4336 SILC_PTR_TO_32(ptype));
4337 silc_hash_table_list_reset(&htl);
4339 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4341 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4342 idp->data, silc_buffer_len(idp),
4343 channel->channel_name,
4344 strlen(channel->channel_name),
4345 idp2->data, silc_buffer_len(idp2),
4347 list->data, silc_buffer_len(list));
4348 silc_buffer_free(idp2);
4349 silc_buffer_free(list);
4352 /* Encode ban list */
4353 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4354 list = silc_buffer_alloc_size(2);
4355 type = silc_hash_table_count(channel->ban_list);
4356 SILC_PUT16_MSB(type, list->data);
4357 silc_hash_table_list(channel->ban_list, &htl);
4358 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4359 list = silc_argument_payload_encode_one(list, tmp2->data,
4360 silc_buffer_len(tmp2),
4361 SILC_PTR_TO_32(ptype));
4362 silc_hash_table_list_reset(&htl);
4365 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4366 idp->data, silc_buffer_len(idp),
4368 list->data, silc_buffer_len(list));
4369 silc_buffer_free(list);
4372 silc_buffer_free(idp);
4375 /* Returns assembled packets for channel users of the `channel'. */
4377 void silc_server_announce_get_channel_users(SilcServer server,
4378 SilcChannelEntry channel,
4379 SilcBuffer *channel_modes,
4380 SilcBuffer *channel_users,
4381 SilcBuffer *channel_users_modes)
4383 SilcChannelClientEntry chl;
4384 SilcHashTableList htl;
4385 SilcBuffer chidp, clidp, csidp;
4386 SilcBuffer tmp, fkey = NULL, chpklist;
4388 unsigned char mode[4], ulimit[4];
4392 SILC_LOG_DEBUG(("Start"));
4394 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4395 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4396 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4399 SILC_PUT32_MSB(channel->mode, mode);
4400 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4401 SILC_PUT32_MSB(channel->user_limit, ulimit);
4402 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4403 if (channel->founder_key)
4404 fkey = silc_public_key_payload_encode(channel->founder_key);
4406 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4408 silc_buffer_len(csidp),
4411 hmac, hmac ? strlen(hmac) : 0,
4412 channel->passphrase,
4413 channel->passphrase ?
4414 strlen(channel->passphrase) : 0,
4415 fkey ? fkey->data : NULL,
4416 fkey ? silc_buffer_len(fkey) : 0,
4417 chpklist ? chpklist->data : NULL,
4419 silc_buffer_len(chpklist) : 0,
4421 SILC_CHANNEL_MODE_ULIMIT ?
4424 SILC_CHANNEL_MODE_ULIMIT ?
4425 sizeof(ulimit) : 0));
4426 len = silc_buffer_len(tmp);
4428 silc_buffer_realloc(*channel_modes,
4430 silc_buffer_truelen((*channel_modes)) + len : len));
4433 *channel_modes = tmp2;
4434 silc_buffer_pull_tail(*channel_modes,
4435 ((*channel_modes)->end -
4436 (*channel_modes)->data));
4437 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4438 silc_buffer_pull(*channel_modes, len);
4439 silc_buffer_free(tmp);
4440 silc_buffer_free(fkey);
4443 /* Now find all users on the channel */
4444 silc_hash_table_list(channel->user_list, &htl);
4445 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4446 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4448 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4452 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4454 silc_buffer_len(clidp),
4456 silc_buffer_len(chidp));
4457 len = silc_buffer_len(tmp);
4459 silc_buffer_realloc(*channel_users,
4461 silc_buffer_truelen((*channel_users)) + len : len));
4464 *channel_users = tmp2;
4465 silc_buffer_pull_tail(*channel_users,
4466 ((*channel_users)->end -
4467 (*channel_users)->data));
4469 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4470 silc_buffer_pull(*channel_users, len);
4471 silc_buffer_free(tmp);
4473 /* CUMODE notify for mode change on the channel */
4474 SILC_PUT32_MSB(chl->mode, mode);
4475 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4476 fkey = silc_public_key_payload_encode(channel->founder_key);
4477 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4479 silc_buffer_len(csidp),
4482 silc_buffer_len(clidp),
4483 fkey ? fkey->data : NULL,
4484 fkey ? silc_buffer_len(fkey) : 0);
4485 len = silc_buffer_len(tmp);
4487 silc_buffer_realloc(*channel_users_modes,
4488 (*channel_users_modes ?
4489 silc_buffer_truelen((*channel_users_modes)) +
4493 *channel_users_modes = tmp2;
4494 silc_buffer_pull_tail(*channel_users_modes,
4495 ((*channel_users_modes)->end -
4496 (*channel_users_modes)->data));
4498 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4499 silc_buffer_pull(*channel_users_modes, len);
4500 silc_buffer_free(tmp);
4501 silc_buffer_free(fkey);
4503 silc_buffer_free(clidp);
4505 silc_hash_table_list_reset(&htl);
4506 silc_buffer_free(chidp);
4507 silc_buffer_free(csidp);
4510 /* Returns assembled packets for all channels and users on those channels
4511 from the given ID List. The packets are in the form dictated by the
4512 New Channel and New Channel User payloads. */
4514 void silc_server_announce_get_channels(SilcServer server,
4516 SilcBuffer *channels,
4517 SilcBuffer **channel_modes,
4518 SilcBuffer *channel_users,
4519 SilcBuffer **channel_users_modes,
4520 SilcUInt32 *channel_users_modes_c,
4521 SilcBuffer **channel_topics,
4522 SilcBuffer **channel_invites,
4523 SilcBuffer **channel_bans,
4524 SilcChannelID ***channel_ids,
4525 unsigned long creation_time)
4528 SilcIDCacheEntry id_cache;
4529 SilcChannelEntry channel;
4530 unsigned char cid[32];
4532 SilcUInt16 name_len;
4534 int i = *channel_users_modes_c;
4538 SILC_LOG_DEBUG(("Start"));
4540 /* Go through all channels in the list */
4541 if (silc_idcache_get_all(id_list->channels, &list)) {
4542 silc_list_start(list);
4543 while ((id_cache = silc_list_get(list))) {
4544 channel = (SilcChannelEntry)id_cache->context;
4546 if (creation_time && channel->created < creation_time)
4551 SILC_LOG_DEBUG(("Announce Channel ID %s",
4552 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4554 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4555 name_len = strlen(channel->channel_name);
4558 len = 4 + name_len + id_len + 4;
4560 silc_buffer_realloc(*channels,
4562 silc_buffer_truelen((*channels)) +
4568 silc_buffer_pull_tail(*channels,
4569 ((*channels)->end - (*channels)->data));
4570 silc_buffer_format(*channels,
4571 SILC_STR_UI_SHORT(name_len),
4572 SILC_STR_UI_XNSTRING(channel->channel_name,
4574 SILC_STR_UI_SHORT(id_len),
4575 SILC_STR_UI_XNSTRING(cid, id_len),
4576 SILC_STR_UI_INT(channel->mode),
4578 silc_buffer_pull(*channels, len);
4581 if (creation_time && channel->updated < creation_time)
4587 /* Channel user modes */
4588 tmp = silc_realloc(*channel_users_modes,
4589 sizeof(**channel_users_modes) * (i + 1));
4592 *channel_users_modes = tmp;
4593 (*channel_users_modes)[i] = NULL;
4594 tmp = silc_realloc(*channel_modes,
4595 sizeof(**channel_modes) * (i + 1));
4598 *channel_modes = tmp;
4599 (*channel_modes)[i] = NULL;
4600 tmp = silc_realloc(*channel_ids,
4601 sizeof(**channel_ids) * (i + 1));
4605 (*channel_ids)[i] = NULL;
4606 silc_server_announce_get_channel_users(server, channel,
4607 &(*channel_modes)[i],
4609 &(*channel_users_modes)[i]);
4610 (*channel_ids)[i] = channel->id;
4612 /* Channel's topic */
4613 tmp = silc_realloc(*channel_topics,
4614 sizeof(**channel_topics) * (i + 1));
4617 *channel_topics = tmp;
4618 (*channel_topics)[i] = NULL;
4619 silc_server_announce_get_channel_topic(server, channel,
4620 &(*channel_topics)[i]);
4622 /* Channel's invite and ban list */
4623 tmp = silc_realloc(*channel_invites,
4624 sizeof(**channel_invites) * (i + 1));
4627 *channel_invites = tmp;
4628 (*channel_invites)[i] = NULL;
4629 tmp = silc_realloc(*channel_bans,
4630 sizeof(**channel_bans) * (i + 1));
4633 *channel_bans = tmp;
4634 (*channel_bans)[i] = NULL;
4635 silc_server_announce_get_inviteban(server, channel,
4636 &(*channel_invites)[i],
4637 &(*channel_bans)[i]);
4639 (*channel_users_modes_c)++;
4647 /* This function is used to announce our existing channels to our router
4648 when we've connected to it. This also announces the users on the
4649 channels to the router. If the `creation_time' is non-zero only the
4650 channels that was created after the `creation_time' are announced.
4651 Note that the channel users are still announced even if the `creation_time'
4654 void silc_server_announce_channels(SilcServer server,
4655 unsigned long creation_time,
4656 SilcPacketStream remote)
4658 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4659 SilcBuffer *channel_users_modes = NULL;
4660 SilcBuffer *channel_topics = NULL;
4661 SilcBuffer *channel_invites = NULL;
4662 SilcBuffer *channel_bans = NULL;
4663 SilcUInt32 channel_users_modes_c = 0;
4664 SilcChannelID **channel_ids = NULL;
4666 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4668 /* Get channels and channel users in local list */
4669 silc_server_announce_get_channels(server, server->local_list,
4670 &channels, &channel_modes,
4672 &channel_users_modes,
4673 &channel_users_modes_c,
4677 &channel_ids, creation_time);
4679 /* Get channels and channel users in global list */
4680 if (server->server_type != SILC_SERVER)
4681 silc_server_announce_get_channels(server, server->global_list,
4682 &channels, &channel_modes,
4684 &channel_users_modes,
4685 &channel_users_modes_c,
4689 &channel_ids, creation_time);
4692 silc_buffer_push(channels, channels->data - channels->head);
4693 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4695 /* Send the packet */
4696 silc_server_packet_send(server, remote,
4697 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4698 channels->data, silc_buffer_len(channels));
4700 silc_buffer_free(channels);
4703 if (channel_users) {
4704 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4705 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4706 silc_buffer_len(channel_users));
4708 /* Send the packet */
4709 silc_server_packet_send(server, remote,
4710 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4711 channel_users->data, silc_buffer_len(channel_users));
4713 silc_buffer_free(channel_users);
4716 if (channel_modes) {
4719 for (i = 0; i < channel_users_modes_c; i++) {
4720 if (!channel_modes[i])
4722 silc_buffer_push(channel_modes[i],
4723 channel_modes[i]->data -
4724 channel_modes[i]->head);
4725 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4726 silc_buffer_len(channel_modes[i]));
4727 silc_server_packet_send_dest(server, remote,
4728 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4729 channel_ids[i], SILC_ID_CHANNEL,
4730 channel_modes[i]->data,
4731 silc_buffer_len(channel_modes[i]));
4732 silc_buffer_free(channel_modes[i]);
4734 silc_free(channel_modes);
4737 if (channel_users_modes) {
4740 for (i = 0; i < channel_users_modes_c; i++) {
4741 if (!channel_users_modes[i])
4743 silc_buffer_push(channel_users_modes[i],
4744 channel_users_modes[i]->data -
4745 channel_users_modes[i]->head);
4746 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4747 silc_buffer_len(channel_users_modes[i]));
4748 silc_server_packet_send_dest(server, remote,
4749 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4750 channel_ids[i], SILC_ID_CHANNEL,
4751 channel_users_modes[i]->data,
4752 silc_buffer_len(channel_users_modes[i]));
4753 silc_buffer_free(channel_users_modes[i]);
4755 silc_free(channel_users_modes);
4758 if (channel_topics) {
4761 for (i = 0; i < channel_users_modes_c; i++) {
4762 if (!channel_topics[i])
4765 silc_buffer_push(channel_topics[i],
4766 channel_topics[i]->data -
4767 channel_topics[i]->head);
4768 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4769 silc_buffer_len(channel_topics[i]));
4770 silc_server_packet_send_dest(server, remote,
4771 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4772 channel_ids[i], SILC_ID_CHANNEL,
4773 channel_topics[i]->data,
4774 silc_buffer_len(channel_topics[i]));
4775 silc_buffer_free(channel_topics[i]);
4777 silc_free(channel_topics);
4780 if (channel_invites) {
4783 for (i = 0; i < channel_users_modes_c; i++) {
4784 if (!channel_invites[i])
4787 silc_buffer_push(channel_invites[i],
4788 channel_invites[i]->data -
4789 channel_invites[i]->head);
4790 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4791 silc_buffer_len(channel_invites[i]));
4792 silc_server_packet_send_dest(server, remote,
4793 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4794 channel_ids[i], SILC_ID_CHANNEL,
4795 channel_invites[i]->data,
4796 silc_buffer_len(channel_invites[i]));
4797 silc_buffer_free(channel_invites[i]);
4799 silc_free(channel_invites);
4805 for (i = 0; i < channel_users_modes_c; i++) {
4806 if (!channel_bans[i])
4809 silc_buffer_push(channel_bans[i],
4810 channel_bans[i]->data -
4811 channel_bans[i]->head);
4812 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4813 silc_buffer_len(channel_bans[i]));
4814 silc_server_packet_send_dest(server, remote,
4815 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4816 channel_ids[i], SILC_ID_CHANNEL,
4817 channel_bans[i]->data,
4818 silc_buffer_len(channel_bans[i]));
4819 silc_buffer_free(channel_bans[i]);
4821 silc_free(channel_bans);
4824 silc_free(channel_ids);
4827 /* Announces WATCH list. */
4829 void silc_server_announce_watches(SilcServer server,
4830 SilcPacketStream remote)
4832 SilcHashTableList htl;
4833 SilcBuffer buffer, idp, args, pkp;
4834 SilcClientEntry client;
4837 SILC_LOG_DEBUG(("Announcing watch list"));
4839 /* XXX because way we save the nicks (hash) we cannot announce them. */
4841 /* XXX we should send all public keys in one command if client is
4842 watching more than one key */
4843 silc_hash_table_list(server->watcher_list_pk, &htl);
4844 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4845 if (!client || !client->id)
4848 server->stat.commands_sent++;
4850 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4851 args = silc_buffer_alloc_size(2);
4852 silc_buffer_format(args,
4853 SILC_STR_UI_SHORT(1),
4855 pkp = silc_public_key_payload_encode(key);
4856 args = silc_argument_payload_encode_one(args, pkp->data,
4857 silc_buffer_len(pkp), 0x00);
4858 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4859 ++server->cmd_ident, 2,
4860 1, idp->data, silc_buffer_len(idp),
4862 silc_buffer_len(args));
4865 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4866 buffer->data, silc_buffer_len(buffer));
4868 silc_buffer_free(pkp);
4869 silc_buffer_free(args);
4870 silc_buffer_free(idp);
4871 silc_buffer_free(buffer);
4873 silc_hash_table_list_reset(&htl);
4876 /* Assembles user list and users mode list from the `channel'. */
4878 SilcBool silc_server_get_users_on_channel(SilcServer server,
4879 SilcChannelEntry channel,
4880 SilcBuffer *user_list,
4881 SilcBuffer *mode_list,
4882 SilcUInt32 *user_count)
4884 SilcChannelClientEntry chl;
4885 SilcHashTableList htl;
4886 SilcBuffer client_id_list;
4887 SilcBuffer client_mode_list;
4889 SilcUInt32 list_count = 0, len = 0;
4891 if (!silc_hash_table_count(channel->user_list))
4894 silc_hash_table_list(channel->user_list, &htl);
4895 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4896 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4897 silc_hash_table_list_reset(&htl);
4899 client_id_list = silc_buffer_alloc(len);
4901 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4902 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4903 silc_buffer_pull_tail(client_mode_list,
4904 silc_buffer_truelen(client_mode_list));
4906 silc_hash_table_list(channel->user_list, &htl);
4907 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4909 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4910 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4911 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4912 silc_buffer_free(idp);
4914 /* Client's mode on channel */
4915 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4916 silc_buffer_pull(client_mode_list, 4);
4920 silc_hash_table_list_reset(&htl);
4921 silc_buffer_push(client_id_list,
4922 client_id_list->data - client_id_list->head);
4923 silc_buffer_push(client_mode_list,
4924 client_mode_list->data - client_mode_list->head);
4926 *user_list = client_id_list;
4927 *mode_list = client_mode_list;
4928 *user_count = list_count;
4932 /* Saves users and their modes to the `channel'. */
4934 void silc_server_save_users_on_channel(SilcServer server,
4935 SilcPacketStream sock,
4936 SilcChannelEntry channel,
4937 SilcClientID *noadd,
4938 SilcBuffer user_list,
4939 SilcBuffer mode_list,
4940 SilcUInt32 user_count)
4946 SilcClientEntry client;
4947 SilcIDCacheEntry cache;
4948 SilcChannelClientEntry chl;
4950 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4951 channel->channel_name));
4953 for (i = 0; i < user_count; i++) {
4955 SILC_GET16_MSB(idp_len, user_list->data + 2);
4957 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4959 silc_buffer_pull(user_list, idp_len);
4962 SILC_GET32_MSB(mode, mode_list->data);
4963 silc_buffer_pull(mode_list, 4);
4965 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4970 /* Check if we have this client cached already. */
4971 client = silc_idlist_find_client_by_id(server->local_list,
4973 server->server_type, &cache);
4975 client = silc_idlist_find_client_by_id(server->global_list,
4977 server->server_type, &cache);
4979 /* If router did not find such Client ID in its lists then this must
4980 be bogus client or some router in the net is buggy. */
4981 if (server->server_type != SILC_SERVER)
4984 /* We don't have that client anywhere, add it. The client is added
4985 to global list since server didn't have it in the lists so it must be
4987 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4988 silc_id_dup(&id.u.client_id,
4990 silc_packet_get_context(sock),
4993 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4997 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5000 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5001 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5002 "%s", channel->channel_name));
5006 if (!silc_server_client_on_channel(client, channel, &chl)) {
5007 /* Client was not on the channel, add it. */
5008 chl = silc_calloc(1, sizeof(*chl));
5009 chl->client = client;
5011 chl->channel = channel;
5012 silc_hash_table_add(channel->user_list, chl->client, chl);
5013 silc_hash_table_add(client->channels, chl->channel, chl);
5014 channel->user_count++;
5022 /* Saves channels and channels user modes to the `client'. Removes
5023 the client from those channels that are not sent in the list but
5026 void silc_server_save_user_channels(SilcServer server,
5027 SilcPacketStream sock,
5028 SilcClientEntry client,
5029 SilcBuffer channels,
5030 SilcBuffer channels_user_modes)
5033 SilcUInt32 *chumodes;
5034 SilcChannelPayload entry;
5035 SilcChannelEntry channel;
5036 SilcChannelID channel_id;
5037 SilcChannelClientEntry chl;
5038 SilcHashTable ht = NULL;
5039 SilcHashTableList htl;
5043 if (!channels || !channels_user_modes ||
5044 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5047 ch = silc_channel_payload_parse_list(channels->data,
5048 silc_buffer_len(channels));
5049 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5051 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5052 NULL, NULL, NULL, TRUE);
5053 silc_dlist_start(ch);
5054 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5055 /* Check if we have this channel, and add it if we don't have it.
5056 Also add the client on the channel unless it is there already. */
5057 if (!silc_channel_get_id_parse(entry, &channel_id))
5059 channel = silc_idlist_find_channel_by_id(server->local_list,
5062 channel = silc_idlist_find_channel_by_id(server->global_list,
5065 if (server->server_type != SILC_SERVER) {
5070 /* We don't have that channel anywhere, add it. */
5071 name = silc_channel_get_name(entry, NULL);
5072 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5073 silc_id_dup(&channel_id,
5075 server->router, NULL, NULL, 0);
5082 channel->mode = silc_channel_get_mode(entry);
5084 /* Add the client on the channel */
5085 if (!silc_server_client_on_channel(client, channel, &chl)) {
5086 chl = silc_calloc(1, sizeof(*chl));
5087 chl->client = client;
5088 chl->mode = chumodes[i++];
5089 chl->channel = channel;
5090 silc_hash_table_add(channel->user_list, chl->client, chl);
5091 silc_hash_table_add(client->channels, chl->channel, chl);
5092 channel->user_count++;
5095 chl->mode = chumodes[i++];
5098 silc_hash_table_add(ht, channel, channel);
5100 silc_channel_payload_list_free(ch);
5101 silc_free(chumodes);
5105 /* Go through the list again and remove client from channels that
5106 are no part of the list. */
5108 silc_hash_table_list(client->channels, &htl);
5109 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5110 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5111 silc_hash_table_del(chl->channel->user_list, chl->client);
5112 silc_hash_table_del(chl->client->channels, chl->channel);
5116 silc_hash_table_list_reset(&htl);
5117 silc_hash_table_free(ht);
5119 silc_hash_table_list(client->channels, &htl);
5120 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5121 silc_hash_table_del(chl->channel->user_list, chl->client);
5122 silc_hash_table_del(chl->client->channels, chl->channel);
5125 silc_hash_table_list_reset(&htl);
5129 /* Lookups route to the client indicated by the `id_data'. The connection
5130 object and internal data object is returned. Returns NULL if route
5131 could not be found to the client. If the `client_id' is specified then
5132 it is used and the `id_data' is ignored. */
5135 silc_server_get_client_route(SilcServer server,
5136 unsigned char *id_data,
5138 SilcClientID *client_id,
5139 SilcIDListData *idata,
5140 SilcClientEntry *client_entry)
5142 SilcClientID *id, clid;
5143 SilcClientEntry client;
5145 SILC_LOG_DEBUG(("Start"));
5148 *client_entry = NULL;
5150 /* Decode destination Client ID */
5152 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5154 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5156 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5159 /* If the destination belongs to our server we don't have to route
5160 the packet anywhere but to send it to the local destination. */
5161 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5165 /* If we are router and the client has router then the client is in
5166 our cell but not directly connected to us. */
5167 if (server->server_type == SILC_ROUTER && client->router) {
5168 /* We are of course in this case the client's router thus the route
5169 to the client is the server who owns the client. So, we will send
5170 the packet to that server. */
5172 *idata = (SilcIDListData)client->router;
5173 return client->router->connection;
5176 /* Seems that client really is directly connected to us */
5178 *idata = (SilcIDListData)client;
5180 *client_entry = client;
5181 return client->connection;
5184 /* Destination belongs to someone not in this server. If we are normal
5185 server our action is to send the packet to our router. */
5186 if (server->server_type != SILC_ROUTER && !server->standalone) {
5189 *idata = (SilcIDListData)server->router;
5190 return SILC_PRIMARY_ROUTE(server);
5193 /* We are router and we will perform route lookup for the destination
5194 and send the packet to fastest route. */
5195 if (server->server_type == SILC_ROUTER && !server->standalone) {
5196 /* Check first that the ID is valid */
5197 client = silc_idlist_find_client_by_id(server->global_list, id,
5200 SilcPacketStream dst_sock;
5202 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5205 if (idata && dst_sock)
5206 *idata = silc_packet_get_context(dst_sock);
5215 /* Encodes and returns channel list of channels the `client' has joined.
5216 Secret channels are not put to the list. */
5218 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5219 SilcClientEntry client,
5220 SilcBool get_private,
5221 SilcBool get_secret,
5222 SilcBuffer *user_mode_list)
5224 SilcBuffer buffer = NULL;
5225 SilcChannelEntry channel;
5226 SilcChannelClientEntry chl;
5227 SilcHashTableList htl;
5228 unsigned char cid[32];
5230 SilcUInt16 name_len;
5234 *user_mode_list = NULL;
5236 silc_hash_table_list(client->channels, &htl);
5237 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5238 channel = chl->channel;
5240 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5242 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5245 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5246 name_len = strlen(channel->channel_name);
5248 len = 4 + name_len + id_len + 4;
5249 buffer = silc_buffer_realloc(buffer,
5251 silc_buffer_truelen(buffer) + len : len));
5252 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5253 silc_buffer_format(buffer,
5254 SILC_STR_UI_SHORT(name_len),
5255 SILC_STR_DATA(channel->channel_name, name_len),
5256 SILC_STR_UI_SHORT(id_len),
5257 SILC_STR_DATA(cid, id_len),
5258 SILC_STR_UI_INT(chl->channel->mode),
5260 silc_buffer_pull(buffer, len);
5262 if (user_mode_list) {
5264 silc_buffer_realloc(*user_mode_list,
5266 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5267 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5268 (*user_mode_list)->data));
5269 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5270 silc_buffer_pull(*user_mode_list, 4);
5273 silc_hash_table_list_reset(&htl);
5276 silc_buffer_push(buffer, buffer->data - buffer->head);
5277 if (user_mode_list && *user_mode_list)
5278 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5279 (*user_mode_list)->head));
5284 /* Task callback used to retrieve network statistical information from
5285 router server once in a while. */
5287 SILC_TASK_CALLBACK(silc_server_get_stats)
5289 SilcServer server = (SilcServer)context;
5290 SilcBuffer idp, packet;
5292 if (!server->standalone) {
5293 SILC_LOG_DEBUG(("Retrieving stats from router"));
5294 server->stat.commands_sent++;
5295 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5297 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5298 ++server->cmd_ident, 1,
5300 silc_buffer_len(idp));
5301 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5302 SILC_PACKET_COMMAND, 0, packet->data,
5303 silc_buffer_len(packet));
5304 silc_buffer_free(packet);
5305 silc_buffer_free(idp);
5309 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,