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_free(server->local_list);
705 silc_free(server->global_list);
706 silc_free(server->server_name);
707 silc_free(server->id);
710 silc_hmac_unregister_all();
711 silc_hash_unregister_all();
712 silc_cipher_unregister_all();
713 silc_pkcs_unregister_all();
716 /* Creates a new server listener. */
718 static SilcNetListener
719 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
721 SilcNetListener listener;
724 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
725 server->config->require_reverse_lookup,
727 silc_server_accept_new_connection, server);
729 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
737 /* Adds a secondary listener. */
739 SilcBool silc_server_init_secondary(SilcServer server)
741 SilcServerConfigServerInfoInterface *interface;
742 SilcNetListener listener;
744 for (interface = server->config->server_info->secondary; interface;
745 interface = interface->next) {
746 listener = silc_server_listen(server, interface->server_ip,
750 silc_dlist_add(server->listeners, listener);
756 /* Initializes the entire SILC server. This is called always before running
757 the server. This is called only once at the initialization of the program.
758 This binds the server to its listenning port. After this function returns
759 one should call silc_server_run to start the server. This returns TRUE
760 when everything is ok to run the server. Configuration file must be
761 read and parsed before calling this. */
763 SilcBool silc_server_init(SilcServer server)
766 SilcServerEntry id_entry;
767 SilcNetListener listener;
772 SILC_LOG_DEBUG(("Initializing server"));
774 server->starttime = time(NULL);
776 /* Take config object for us */
777 silc_server_config_ref(&server->config_ref, server->config,
781 /* Set debugging on if configured */
782 if (server->config->debug_string) {
783 silc_log_debug(TRUE);
784 silc_log_set_debug_string(server->config->debug_string);
786 #endif /* SILC_DEBUG */
788 /* Steal public and private key from the config object */
789 server->public_key = server->config->server_info->public_key;
790 server->private_key = server->config->server_info->private_key;
791 server->config->server_info->public_key = NULL;
792 server->config->server_info->private_key = NULL;
794 /* Register all configured ciphers, PKCS and hash functions. */
795 if (!silc_server_config_register_ciphers(server))
796 silc_cipher_register_default();
797 if (!silc_server_config_register_pkcs(server))
798 silc_pkcs_register_default();
799 if (!silc_server_config_register_hashfuncs(server))
800 silc_hash_register_default();
801 if (!silc_server_config_register_hmacs(server))
802 silc_hmac_register_default();
804 /* Initialize random number generator for the server. */
805 server->rng = silc_rng_alloc();
806 silc_rng_init(server->rng);
807 silc_rng_global_init(server->rng);
809 /* Initialize hash functions for server to use */
810 silc_hash_alloc("md5", &server->md5hash);
811 silc_hash_alloc("sha1", &server->sha1hash);
813 /* Initialize the scheduler */
814 server->schedule = silc_schedule_init(server->config->param.connections_max,
816 if (!server->schedule)
819 /* First, register log files configuration for error output */
820 silc_server_config_setlogfiles(server);
822 /* Initialize ID caches */
823 server->local_list->clients =
824 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
826 server->local_list->servers =
827 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
829 server->local_list->channels =
830 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
833 /* These are allocated for normal server as well as these hold some
834 global information that the server has fetched from its router. For
835 router these are used as they are supposed to be used on router. */
836 server->global_list->clients =
837 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
839 server->global_list->servers =
840 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
842 server->global_list->channels =
843 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
846 /* Init watcher lists */
847 server->watcher_list =
848 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
849 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
851 if (!server->watcher_list)
853 server->watcher_list_pk =
854 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
855 silc_hash_public_key_compare, NULL,
857 if (!server->watcher_list_pk)
860 /* Create TCP listener */
861 listener = silc_server_listen(
863 server->config->server_info->primary == NULL ? NULL :
864 server->config->server_info->primary->server_ip,
865 server->config->server_info->primary == NULL ? 0 :
866 server->config->server_info->primary->port);
869 silc_dlist_add(server->listeners, listener);
871 /* Create a Server ID for the server. */
872 port = silc_net_listener_get_port(listener, NULL);
873 ip = silc_net_listener_get_ip(listener, NULL);
874 external_ip = server->config->server_info->external_ip ?
875 server->config->server_info->external_ip :
876 server->config->server_info->primary->public_ip;
877 silc_id_create_server_id(external_ip ?
879 ip[0], port[0], server->rng, &id);
888 server->server_name = server->config->server_info->server_name;
889 server->config->server_info->server_name = NULL;
890 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
891 sizeof(server->id_string), &server->id_string_len);
893 /* Add ourselves to the server list. We don't have a router yet
894 beacuse we haven't established a route yet. It will be done later.
895 For now, NULL is sent as router. This allocates new entry to
898 silc_idlist_add_server(server->local_list, strdup(server->server_name),
900 silc_id_dup(server->id, SILC_ID_SERVER),
903 SILC_LOG_ERROR(("Could not add local server to cache"));
906 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
907 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
908 SILC_CONN_SERVER : SILC_CONN_ROUTER);
909 server->id_entry = id_entry;
911 /* Create secondary TCP listeners */
912 if (silc_server_init_secondary(server) == FALSE)
915 server->listenning = TRUE;
917 /* Create connections to configured routers. */
918 silc_server_create_connections(server);
920 /* If server connections has been configured then we must be router as
921 normal server cannot have server connections, only router connections. */
922 if (server->config->servers) {
923 SilcServerConfigServer *ptr = server->config->servers;
925 server->server_type = SILC_ROUTER;
927 if (ptr->backup_router) {
928 server->server_type = SILC_BACKUP_ROUTER;
929 server->backup_router = TRUE;
930 server->id_entry->server_type = SILC_BACKUP_ROUTER;
937 if (server->server_type != SILC_ROUTER) {
938 server->stat.servers = 1;
939 server->stat.cell_servers = 1;
941 server->stat.routers = 1;
944 /* If we are normal server we'll retrieve network statisticial information
945 once in a while from the router. */
946 if (server->server_type != SILC_ROUTER)
947 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
950 /* Start packet engine */
951 server->packet_engine =
952 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
953 &silc_server_stream_cbs, server);
954 if (!server->packet_engine)
957 /* Register client entry expiration timeout */
958 silc_schedule_task_add_timeout(server->schedule,
959 silc_server_purge_expired_clients, server,
962 /* Initialize HTTP server */
963 silc_server_http_init(server);
965 SILC_LOG_DEBUG(("Server initialized"));
967 /* We are done here, return succesfully */
971 silc_server_config_unref(&server->config_ref);
975 /* Task callback to close a socket connection after rehash */
977 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
979 SilcServer server = app_context;
980 SilcPacketStream sock = context;
981 SilcIDListData idata = silc_packet_get_context(sock);
982 const char *hostname;
985 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
986 NULL, &hostname, NULL, &port);
988 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
989 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
990 silc_schedule_task_del_by_context(server->schedule, sock);
991 silc_server_disconnect_remote(server, sock,
992 SILC_STATUS_ERR_BANNED_FROM_SERVER,
993 "This connection is removed from "
995 silc_server_free_sock_user_data(server, sock, NULL);
998 /* This function basically reads the config file again and switches the config
999 object pointed by the server object. After that, we have to fix various
1000 things such as the server_name and the listening ports.
1001 Keep in mind that we no longer have the root privileges at this point. */
1003 SilcBool silc_server_rehash(SilcServer server)
1005 SilcServerConfig newconfig;
1007 SILC_LOG_INFO(("Rehashing server"));
1009 /* Reset the logging system */
1010 silc_log_quick(TRUE);
1011 silc_log_flush_all();
1013 /* Start the main rehash phase (read again the config file) */
1014 newconfig = silc_server_config_alloc(server->config_file, server);
1016 SILC_LOG_ERROR(("Rehash FAILED."));
1020 /* Fix the server_name field */
1021 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1022 silc_free(server->server_name);
1024 /* Check server name */
1025 server->server_name =
1026 silc_identifier_check(newconfig->server_info->server_name,
1027 strlen(newconfig->server_info->server_name),
1028 SILC_STRING_LOCALE, 256, NULL);
1029 if (!server->server_name) {
1030 SILC_LOG_ERROR(("Malformed server name string '%s'",
1031 server->config->server_info->server_name));
1035 /* Update the idcache list with a fresh pointer */
1036 silc_free(server->id_entry->server_name);
1037 server->id_entry->server_name = strdup(server->server_name);
1038 silc_idcache_update_by_context(server->local_list->servers,
1039 server->id_entry, NULL,
1040 strdup(server->id_entry->server_name),
1045 silc_server_config_setlogfiles(server);
1047 /* Change new key pair if necessary */
1048 if (newconfig->server_info->public_key &&
1049 !silc_pkcs_public_key_compare(server->public_key,
1050 newconfig->server_info->public_key)) {
1051 silc_pkcs_public_key_free(server->public_key);
1052 silc_pkcs_private_key_free(server->private_key);
1053 server->public_key = newconfig->server_info->public_key;
1054 server->private_key = newconfig->server_info->private_key;
1055 newconfig->server_info->public_key = NULL;
1056 newconfig->server_info->private_key = NULL;
1059 /* Check for unconfigured server and router connections and close
1060 connections that were unconfigured. */
1062 if (server->config->routers) {
1063 SilcServerConfigRouter *ptr;
1064 SilcServerConfigRouter *newptr;
1067 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1070 /* Check whether new config has this one too */
1071 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1072 if (silc_string_compare(newptr->host, ptr->host) &&
1073 newptr->port == ptr->port &&
1074 newptr->initiator == ptr->initiator) {
1080 if (!found && ptr->host) {
1081 /* Remove this connection */
1082 SilcPacketStream sock;
1083 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1084 ptr->host, ptr->port);
1086 silc_schedule_task_add_timeout(server->schedule,
1087 silc_server_rehash_close_connection,
1093 if (server->config->servers) {
1094 SilcServerConfigServer *ptr;
1095 SilcServerConfigServer *newptr;
1098 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1101 /* Check whether new config has this one too */
1102 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1103 if (silc_string_compare(newptr->host, ptr->host)) {
1109 if (!found && ptr->host) {
1110 /* Remove this connection */
1111 SilcPacketStream sock;
1112 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1115 silc_schedule_task_add_timeout(server->schedule,
1116 silc_server_rehash_close_connection,
1122 if (server->config->clients) {
1123 SilcServerConfigClient *ptr;
1124 SilcServerConfigClient *newptr;
1127 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1130 /* Check whether new config has this one too */
1131 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1132 if (silc_string_compare(newptr->host, ptr->host)) {
1138 if (!found && ptr->host) {
1139 /* Remove this connection */
1140 SilcPacketStream sock;
1141 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1144 silc_schedule_task_add_timeout(server->schedule,
1145 silc_server_rehash_close_connection,
1151 /* Create connections after rehash */
1152 silc_server_create_connections(server);
1154 /* Check whether our router status has changed */
1155 if (newconfig->servers) {
1156 SilcServerConfigServer *ptr = newconfig->servers;
1158 server->server_type = SILC_ROUTER;
1160 if (ptr->backup_router) {
1161 server->server_type = SILC_BACKUP_ROUTER;
1162 server->backup_router = TRUE;
1163 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1170 /* Our old config is gone now. We'll unreference our reference made in
1171 silc_server_init and then destroy it since we are destroying it
1172 underneath the application (layer which called silc_server_init). */
1173 silc_server_config_unref(&server->config_ref);
1174 silc_server_config_destroy(server->config);
1176 /* Take new config context */
1177 server->config = newconfig;
1178 silc_server_config_ref(&server->config_ref, server->config, server->config);
1181 /* Set debugging on if configured */
1182 if (server->config->debug_string) {
1183 silc_log_debug(TRUE);
1184 silc_log_set_debug_string(server->config->debug_string);
1186 #endif /* SILC_DEBUG */
1188 SILC_LOG_DEBUG(("Server rehashed"));
1193 /* The heart of the server. This runs the scheduler thus runs the server.
1194 When this returns the server has been stopped and the program will
1197 void silc_server_run(SilcServer server)
1199 SILC_LOG_INFO(("SILC Server started"));
1201 /* Start the scheduler, the heart of the SILC server. When this returns
1202 the program will be terminated. */
1203 silc_schedule(server->schedule);
1206 /* Stops the SILC server. This function is used to shutdown the server.
1207 This is usually called after the scheduler has returned. After stopping
1208 the server one should call silc_server_free. */
1210 void silc_server_stop(SilcServer server)
1213 SilcPacketStream ps;
1214 SilcNetListener listener;
1216 SILC_LOG_INFO(("SILC Server shutting down"));
1218 server->server_shutdown = TRUE;
1220 /* Close all connections */
1221 if (server->packet_engine) {
1222 list = silc_packet_engine_get_streams(server->packet_engine);
1224 silc_dlist_start(list);
1225 while ((ps = silc_dlist_get(list))) {
1226 SilcIDListData idata = silc_packet_get_context(ps);
1228 if (!silc_packet_stream_is_valid(ps))
1232 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1234 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1235 "Server is shutting down");
1236 silc_server_free_sock_user_data(server, ps,
1237 "Server is shutting down");
1239 silc_packet_engine_free_streams_list(list);
1242 /* We are not connected to network anymore */
1243 server->standalone = TRUE;
1245 silc_dlist_start(server->listeners);
1246 while ((listener = silc_dlist_get(server->listeners)))
1247 silc_net_close_listener(listener);
1249 silc_server_http_uninit(server);
1251 /* Cancel any possible retry timeouts */
1252 silc_schedule_task_del_by_callback(server->schedule,
1253 silc_server_connect_router);
1254 silc_schedule_task_del_by_callback(server->schedule,
1255 silc_server_connect_to_router_retry);
1256 silc_schedule_task_del_by_callback(server->schedule,
1257 silc_server_connect_to_router);
1259 silc_schedule_stop(server->schedule);
1261 SILC_LOG_DEBUG(("Server stopped"));
1264 /* Purge expired client entries from the server */
1266 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1268 SilcServer server = context;
1269 SilcClientEntry client;
1271 SilcUInt64 curtime = silc_time();
1273 SILC_LOG_DEBUG(("Expire timeout"));
1275 silc_dlist_start(server->expired_clients);
1276 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);
1381 silc_server_disconnect_remote(server, sconn->sock,
1382 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1386 /* XXX For now remote is router always */
1387 entry->data.conn_type = SILC_CONN_ROUTER;
1389 SILC_LOG_INFO(("Connected to %s %s",
1390 SILC_CONNTYPE_STRING(entry->data.conn_type),
1391 sconn->remote_host));
1393 /* Create the actual entry for remote entity */
1394 switch (entry->data.conn_type) {
1395 case SILC_CONN_SERVER:
1396 SILC_LOG_DEBUG(("Remote is SILC server"));
1398 /* Add new server. The server must register itself to us before it
1399 becomes registered to SILC network. */
1400 id_entry = silc_idlist_add_server(server->local_list,
1401 strdup(sconn->remote_host),
1402 SILC_SERVER, NULL, NULL, sconn->sock);
1404 if (sconn->callback)
1405 (*sconn->callback)(server, NULL, sconn->callback_context);
1406 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1407 silc_server_disconnect_remote(server, sconn->sock,
1408 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1413 server->stat.my_servers++;
1414 if (server->server_type == SILC_ROUTER)
1415 server->stat.servers++;
1416 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1418 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1421 case SILC_CONN_ROUTER:
1422 SILC_LOG_DEBUG(("Remote is SILC router"));
1424 /* Register to network */
1425 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1426 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1427 SILC_STR_UI_SHORT(id_len),
1428 SILC_STR_DATA(id, id_len),
1429 SILC_STR_UI_SHORT(strlen(server->server_name)),
1430 SILC_STR_DATA(server->server_name,
1431 strlen(server->server_name)),
1433 if (sconn->callback)
1434 (*sconn->callback)(server, NULL, sconn->callback_context);
1435 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1436 silc_server_disconnect_remote(server, sconn->sock,
1437 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1442 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1444 /* Check that we do not have this ID already */
1445 id_entry = silc_idlist_find_server_by_id(server->local_list,
1446 &remote_id.u.server_id,
1449 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1451 id_entry = silc_idlist_find_server_by_id(server->global_list,
1452 &remote_id.u.server_id,
1455 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1459 SILC_LOG_DEBUG(("New server id(%s)",
1460 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1462 /* Add the connected router to global server list. Router is sent
1463 as NULL since it's local to us. */
1464 id_entry = silc_idlist_add_server(server->global_list,
1465 strdup(sconn->remote_host),
1467 silc_id_dup(&remote_id.u.server_id,
1471 /* Try reconnecting if configuration wants it */
1472 if (!sconn->no_reconnect) {
1473 silc_schedule_task_add_timeout(server->schedule,
1474 silc_server_connect_to_router_retry,
1476 silc_dlist_del(server->conns, sconn);
1480 if (sconn->callback)
1481 (*sconn->callback)(server, NULL, sconn->callback_context);
1482 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1483 silc_server_disconnect_remote(server, sconn->sock,
1484 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1489 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1490 idata = (SilcIDListData)id_entry;
1491 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1492 SILC_IDLIST_STATUS_LOCAL);
1493 idata->sconn = sconn;
1494 idata->sconn->callback = NULL;
1497 server->stat.my_routers++;
1498 if (server->server_type == SILC_ROUTER)
1499 server->stat.routers++;
1500 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1502 if (!sconn->backup) {
1503 /* Mark this router our primary router if we're still standalone */
1504 if (server->standalone) {
1505 SILC_LOG_DEBUG(("This connection is our primary router"));
1506 server->id_entry->router = id_entry;
1507 server->router = id_entry;
1508 server->router->server_type = SILC_ROUTER;
1509 server->standalone = FALSE;
1510 server->backup_primary = FALSE;
1512 /* Announce data if we are not backup router (unless not as primary
1513 currently). Backup router announces later at the end of
1514 resuming protocol. */
1515 if (server->backup_router && server->server_type == SILC_ROUTER) {
1516 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1518 /* If we are router then announce our possible servers. Backup
1519 router announces also global servers. */
1520 if (server->server_type == SILC_ROUTER)
1521 silc_server_announce_servers(server,
1522 server->backup_router ? TRUE : FALSE,
1523 0, SILC_PRIMARY_ROUTE(server));
1525 /* Announce our clients and channels to the router */
1526 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1527 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1530 /* If we are backup router then this primary router is whom we are
1532 if (server->server_type == SILC_BACKUP_ROUTER) {
1533 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1535 NULL, NULL, &ip, NULL);
1536 silc_server_backup_add(server, server->id_entry, ip,
1537 sconn->remote_port, TRUE);
1542 /* We already have primary router. Disconnect this connection */
1543 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1544 silc_idlist_del_server(server->global_list, id_entry);
1545 if (sconn->callback)
1546 (*sconn->callback)(server, NULL, sconn->callback_context);
1547 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1548 silc_server_disconnect_remote(server, sconn->sock,
1549 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1554 /* Add this server to be our backup router */
1555 id_entry->server_type = SILC_BACKUP_ROUTER;
1556 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1557 sconn->backup_replace_port, FALSE);
1563 if (sconn->callback)
1564 (*sconn->callback)(server, NULL, sconn->callback_context);
1565 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1566 silc_server_disconnect_remote(server, sconn->sock,
1567 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1571 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1573 conn = sconn->conn.ref_ptr;
1574 param = &server->config->param;
1575 if (conn && conn->param)
1576 param = conn->param;
1578 /* Register rekey timeout */
1579 sconn->rekey_timeout = param->key_exchange_rekey;
1580 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1581 sconn->sock, sconn->rekey_timeout, 0);
1583 /* Set the entry as packet stream context */
1584 silc_packet_set_context(sconn->sock, id_entry);
1586 /* Call the completion callback to indicate that we've connected to
1588 if (sconn && sconn->callback)
1589 (*sconn->callback)(server, id_entry, sconn->callback_context);
1591 if (sconn == server->router_conn)
1592 server->router_conn = NULL;
1597 /* SKE completion callback */
1599 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1600 SilcSKESecurityProperties prop,
1601 SilcSKEKeyMaterial keymat,
1602 SilcSKERekeyMaterial rekey,
1605 SilcPacketStream sock = context;
1606 SilcUnknownEntry entry = silc_packet_get_context(sock);
1607 SilcServerConnection sconn;
1609 SilcServerConfigRouter *conn;
1610 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1611 void *auth_data = NULL;
1612 SilcUInt32 auth_data_len = 0;
1613 SilcConnAuth connauth;
1614 SilcCipher send_key, receive_key;
1615 SilcHmac hmac_send, hmac_receive;
1617 server = entry->server;
1618 sconn = entry->data.sconn;
1619 conn = sconn->conn.ref_ptr;
1622 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1624 if (status != SILC_SKE_STATUS_OK) {
1626 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1627 silc_ske_map_status(status), entry->hostname, entry->ip));
1630 /* Try reconnecting if configuration wants it */
1631 if (!sconn->no_reconnect) {
1632 silc_schedule_task_add_timeout(server->schedule,
1633 silc_server_connect_to_router_retry,
1635 silc_dlist_del(server->conns, sconn);
1639 if (sconn->callback)
1640 (*sconn->callback)(server, NULL, sconn->callback_context);
1641 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1642 silc_server_disconnect_remote(server, sconn->sock,
1643 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1647 SILC_LOG_DEBUG(("Setting keys into use"));
1649 /* Set the keys into use. The data will be encrypted after this. */
1650 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1651 &hmac_send, &hmac_receive, NULL)) {
1654 /* Try reconnecting if configuration wants it */
1655 if (!sconn->no_reconnect) {
1656 silc_schedule_task_add_timeout(server->schedule,
1657 silc_server_connect_to_router_retry,
1659 silc_dlist_del(server->conns, sconn);
1663 /* Error setting keys */
1664 if (sconn->callback)
1665 (*sconn->callback)(server, NULL, sconn->callback_context);
1666 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1667 silc_server_disconnect_remote(server, sconn->sock,
1668 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1671 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1672 hmac_receive, FALSE);
1674 SILC_LOG_DEBUG(("Starting connection authentication"));
1676 connauth = silc_connauth_alloc(server->schedule, ske,
1677 server->config->conn_auth_timeout);
1681 /* Try reconnecting if configuration wants it */
1682 if (!sconn->no_reconnect) {
1683 silc_schedule_task_add_timeout(server->schedule,
1684 silc_server_connect_to_router_retry,
1686 silc_dlist_del(server->conns, sconn);
1690 /** Error allocating auth protocol */
1691 if (sconn->callback)
1692 (*sconn->callback)(server, NULL, sconn->callback_context);
1693 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1694 silc_server_disconnect_remote(server, sconn->sock,
1695 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1699 /* Get authentication method */
1701 if (conn->passphrase) {
1702 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1703 auth_meth = SILC_AUTH_PUBLIC_KEY;
1704 auth_data = server->private_key;
1706 auth_meth = SILC_AUTH_PASSWORD;
1707 auth_data = conn->passphrase;
1708 auth_data_len = conn->passphrase_len;
1711 auth_meth = SILC_AUTH_PUBLIC_KEY;
1712 auth_data = server->private_key;
1716 entry->data.rekey = rekey;
1718 /* Start connection authentication */
1720 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1721 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1722 auth_data, auth_data_len,
1723 silc_server_ke_auth_compl, sconn);
1726 /* Function that is called when the network connection to a router has
1727 been established. This will continue with the key exchange protocol
1728 with the remote router. */
1730 void silc_server_start_key_exchange(SilcServerConnection sconn)
1732 SilcServer server = sconn->server;
1733 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1734 SilcUnknownEntry entry;
1735 SilcSKEParamsStruct params;
1738 /* Cancel any possible retry timeouts */
1739 silc_schedule_task_del_by_context(server->schedule, sconn);
1741 /* Create packet stream */
1742 sconn->sock = silc_packet_stream_create(server->packet_engine,
1743 server->schedule, sconn->stream);
1745 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1746 silc_stream_destroy(sconn->stream);
1748 /* Try reconnecting if configuration wants it */
1749 if (!sconn->no_reconnect) {
1750 silc_schedule_task_add_timeout(server->schedule,
1751 silc_server_connect_to_router_retry,
1753 silc_dlist_del(server->conns, sconn);
1757 if (sconn->callback)
1758 (*sconn->callback)(server, NULL, sconn->callback_context);
1759 silc_server_connection_free(sconn);
1762 server->stat.conn_num++;
1764 /* Set source ID to packet stream */
1765 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1767 silc_packet_stream_destroy(sconn->sock);
1769 /* Try reconnecting if configuration wants it */
1770 if (!sconn->no_reconnect) {
1771 silc_schedule_task_add_timeout(server->schedule,
1772 silc_server_connect_to_router_retry,
1774 silc_dlist_del(server->conns, sconn);
1778 if (sconn->callback)
1779 (*sconn->callback)(server, NULL, sconn->callback_context);
1780 silc_server_connection_free(sconn);
1784 /* Create entry for remote entity */
1785 entry = silc_calloc(1, sizeof(*entry));
1787 silc_packet_stream_destroy(sconn->sock);
1789 /* Try reconnecting if configuration wants it */
1790 if (!sconn->no_reconnect) {
1791 silc_schedule_task_add_timeout(server->schedule,
1792 silc_server_connect_to_router_retry,
1794 silc_dlist_del(server->conns, sconn);
1798 if (sconn->callback)
1799 (*sconn->callback)(server, NULL, sconn->callback_context);
1800 silc_server_connection_free(sconn);
1803 entry->server = server;
1804 entry->data.sconn = sconn;
1805 silc_packet_set_context(sconn->sock, entry);
1807 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1809 /* Set Key Exchange flags from configuration, but fall back to global
1811 memset(¶ms, 0, sizeof(params));
1812 SILC_GET_SKE_FLAGS(conn, params.flags);
1813 if (server->config->param.key_exchange_pfs)
1814 params.flags |= SILC_SKE_SP_FLAG_PFS;
1816 /* Start SILC Key Exchange protocol */
1817 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1818 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1819 server->public_key, server->private_key, sconn);
1822 silc_packet_stream_destroy(sconn->sock);
1824 /* Try reconnecting if configuration wants it */
1825 if (!sconn->no_reconnect) {
1826 silc_schedule_task_add_timeout(server->schedule,
1827 silc_server_connect_to_router_retry,
1829 silc_dlist_del(server->conns, sconn);
1833 if (sconn->callback)
1834 (*sconn->callback)(server, NULL, sconn->callback_context);
1835 silc_server_connection_free(sconn);
1838 silc_ske_set_callbacks(ske, silc_server_verify_key,
1839 silc_server_ke_completed, sconn->sock);
1841 /* Start key exchange protocol */
1842 params.version = silc_version_string;
1843 params.timeout_secs = server->config->key_exchange_timeout;
1844 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1847 /* Timeout callback that will be called to retry connecting to remote
1848 router. This is used by both normal and router server. This will wait
1849 before retrying the connecting. The timeout is generated by exponential
1850 backoff algorithm. */
1852 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1854 SilcServerConnection sconn = context;
1855 SilcServer server = sconn->server;
1856 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1857 SilcServerConfigConnParams *param =
1858 (conn->param ? conn->param : &server->config->param);
1860 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1861 sconn->remote_port));
1863 /* Calculate next timeout */
1864 if (sconn->retry_count >= 1) {
1865 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1866 if (sconn->retry_timeout > param->reconnect_interval_max)
1867 sconn->retry_timeout = param->reconnect_interval_max;
1869 sconn->retry_timeout = param->reconnect_interval;
1871 sconn->retry_count++;
1872 sconn->retry_timeout = sconn->retry_timeout +
1873 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1875 /* If we've reached max retry count, give up. */
1876 if ((sconn->retry_count > param->reconnect_count) &&
1877 sconn->no_reconnect) {
1878 SILC_LOG_ERROR(("Could not connect, giving up"));
1880 if (sconn->callback)
1881 (*sconn->callback)(server, NULL, sconn->callback_context);
1882 silc_server_connection_free(sconn);
1886 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1888 /* We will lookup a fresh pointer later */
1889 silc_server_config_unref(&sconn->conn);
1891 /* Wait before retrying */
1892 silc_schedule_task_del_by_context(server->schedule, sconn);
1893 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1894 sconn, sconn->retry_timeout, 0);
1897 /* Callback for async connection to remote router */
1899 static void silc_server_connection_established(SilcNetStatus status,
1903 SilcServerConnection sconn = context;
1904 SilcServer server = sconn->server;
1906 silc_schedule_task_del_by_context(server->schedule, sconn);
1911 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1912 sconn->remote_host, sconn->remote_port));
1914 /* Continue with key exchange protocol */
1915 sconn->stream = stream;
1916 silc_server_start_key_exchange(sconn);
1919 case SILC_NET_UNKNOWN_IP:
1920 case SILC_NET_UNKNOWN_HOST:
1921 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1922 sconn->remote_host, sconn->remote_port,
1923 silc_net_get_error_string(status)));
1924 if (!sconn->no_reconnect) {
1925 silc_schedule_task_add_timeout(sconn->server->schedule,
1926 silc_server_connect_to_router_retry,
1928 silc_dlist_del(server->conns, sconn);
1930 if (sconn->callback)
1931 (*sconn->callback)(server, NULL, sconn->callback_context);
1932 silc_server_connection_free(sconn);
1937 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1938 sconn->remote_host, sconn->remote_port,
1939 silc_net_get_error_string(status)));
1940 if (!sconn->no_reconnect) {
1941 silc_schedule_task_add_timeout(sconn->server->schedule,
1942 silc_server_connect_to_router_retry,
1944 silc_dlist_del(server->conns, sconn);
1946 if (sconn->callback)
1947 (*sconn->callback)(server, NULL, sconn->callback_context);
1948 silc_server_connection_free(sconn);
1954 /* Generic routine to use connect to a router. */
1956 SILC_TASK_CALLBACK(silc_server_connect_router)
1958 SilcServerConnection sconn = context;
1959 SilcServer server = sconn->server;
1960 SilcServerConfigRouter *rconn;
1962 silc_schedule_task_del_by_context(server->schedule, sconn);
1964 /* Don't connect if we are shutting down. */
1965 if (server->server_shutdown) {
1966 if (sconn->callback)
1967 (*sconn->callback)(server, NULL, sconn->callback_context);
1968 silc_server_connection_free(sconn);
1972 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1973 (sconn->backup ? "backup router" : "router"),
1974 sconn->remote_host, sconn->remote_port));
1976 if (!sconn->no_conf) {
1977 /* Find connection configuration */
1978 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1979 sconn->remote_port);
1981 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1982 (sconn->backup ? "backup router" : "router"),
1983 sconn->remote_host, sconn->remote_port));
1984 if (sconn->callback)
1985 (*sconn->callback)(server, NULL, sconn->callback_context);
1986 silc_server_connection_free(sconn);
1989 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1992 /* Connect to remote host */
1994 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1995 server->config->server_info->primary->server_ip),
1996 sconn->remote_host, sconn->remote_port,
1997 server->schedule, silc_server_connection_established,
2000 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2001 sconn->remote_host, sconn->remote_port));
2002 if (sconn->callback)
2003 (*sconn->callback)(server, NULL, sconn->callback_context);
2004 silc_server_connection_free(sconn);
2008 /* Add to connection list */
2009 silc_dlist_add(server->conns, sconn);
2012 /* This function connects to our primary router or if we are a router this
2013 establishes all our primary routes. This is called at the start of the
2014 server to do authentication and key exchange with our router - called
2017 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2019 SilcServer server = context;
2020 SilcServerConnection sconn;
2021 SilcServerConfigRouter *ptr;
2022 SilcServerConfigConnParams *param;
2024 /* Don't connect if we are shutting down. */
2025 if (server->server_shutdown)
2028 SILC_LOG_DEBUG(("We are %s",
2029 (server->server_type == SILC_SERVER ?
2030 "normal server" : server->server_type == SILC_ROUTER ?
2031 "router" : "backup router/normal server")));
2033 if (!server->config->routers) {
2034 /* There wasn't a configured router, we will continue but we don't
2035 have a connection to outside world. We will be standalone server. */
2036 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2037 server->standalone = TRUE;
2041 /* Cancel any possible retry timeouts */
2042 silc_schedule_task_del_by_callback(server->schedule,
2043 silc_server_connect_router);
2044 silc_schedule_task_del_by_callback(server->schedule,
2045 silc_server_connect_to_router_retry);
2047 /* Create the connections to all our routes */
2048 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2050 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2051 ptr->backup_router ? "Backup router" : "Router",
2052 ptr->initiator ? "Initiator" : "Responder",
2053 ptr->host, ptr->port));
2055 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2056 ptr->initiator == FALSE && !server->backup_router &&
2057 !silc_server_config_get_backup_router(server))
2058 server->wait_backup = TRUE;
2060 if (!ptr->initiator)
2062 if (ptr->dynamic_connection)
2065 /* Check whether we are connecting or connected to this host already */
2066 if (silc_server_num_sockets_by_remote(server,
2067 silc_net_is_ip(ptr->host) ?
2069 silc_net_is_ip(ptr->host) ?
2070 NULL : ptr->host, ptr->port,
2071 SILC_CONN_ROUTER)) {
2072 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2073 ptr->host, ptr->port));
2075 /* If we don't have primary router and this connection is our
2076 primary router we are in desync. Reconnect to the primary. */
2077 if (server->standalone && !server->router) {
2079 SilcPacketStream sock;
2080 SilcServerConfigRouter *primary =
2081 silc_server_config_get_primary_router(server);
2084 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2085 ptr->host, ptr->port);
2088 server->backup_noswitch = TRUE;
2089 silc_server_free_sock_user_data(server, sock, NULL);
2090 silc_server_disconnect_remote(server, sock, 0, NULL);
2091 server->backup_noswitch = FALSE;
2092 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2098 param = (ptr->param ? ptr->param : &server->config->param);
2100 /* Allocate connection object for hold connection specific stuff. */
2101 sconn = silc_calloc(1, sizeof(*sconn));
2104 sconn->server = server;
2105 sconn->remote_host = strdup(ptr->host);
2106 sconn->remote_port = ptr->port;
2107 sconn->backup = ptr->backup_router;
2108 if (sconn->backup) {
2109 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2110 sconn->backup_replace_port = ptr->backup_replace_port;
2112 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2114 SILC_LOG_DEBUG(("Created connection %p", sconn));
2116 if (!server->router_conn && !sconn->backup)
2117 server->router_conn = sconn;
2120 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2126 /************************ Accepting new connection **************************/
2128 /* After this is called, server don't wait for backup router anymore.
2129 This gets called automatically even after we have backup router
2130 connection established. */
2132 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2134 SilcServer server = context;
2135 server->wait_backup = FALSE;
2138 /* Authentication data callback */
2141 silc_server_accept_get_auth(SilcConnAuth connauth,
2142 SilcConnectionType conn_type,
2143 unsigned char **passphrase,
2144 SilcUInt32 *passphrase_len,
2145 SilcSKR *repository,
2148 SilcPacketStream sock = context;
2149 SilcUnknownEntry entry = silc_packet_get_context(sock);
2150 SilcServer server = entry->server;
2152 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2154 /* Remote end is client */
2155 if (conn_type == SILC_CONN_CLIENT) {
2156 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2160 *passphrase = cconfig->passphrase;
2161 *passphrase_len = cconfig->passphrase_len;
2162 if (cconfig->publickeys)
2163 *repository = server->repository;
2165 if (cconfig->publickeys) {
2166 if (server->config->prefer_passphrase_auth) {
2170 *passphrase_len = 0;
2174 entry->conn_type = conn_type;
2178 /* Remote end is server */
2179 if (conn_type == SILC_CONN_SERVER) {
2180 SilcServerConfigServer *sconfig;
2182 /* If we are normal server, don't accept the connection */
2183 if (server->server_type == SILC_SERVER)
2186 sconfig = entry->sconfig.ref_ptr;
2190 *passphrase = sconfig->passphrase;
2191 *passphrase_len = sconfig->passphrase_len;
2192 if (sconfig->publickeys)
2193 *repository = server->repository;
2195 if (sconfig->publickeys) {
2196 if (server->config->prefer_passphrase_auth) {
2200 *passphrase_len = 0;
2204 entry->conn_type = conn_type;
2208 /* Remote end is router */
2209 if (conn_type == SILC_CONN_ROUTER) {
2210 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2214 *passphrase = rconfig->passphrase;
2215 *passphrase_len = rconfig->passphrase_len;
2216 if (rconfig->publickeys)
2217 *repository = server->repository;
2219 if (rconfig->publickeys) {
2220 if (server->config->prefer_passphrase_auth) {
2224 *passphrase_len = 0;
2228 entry->conn_type = conn_type;
2235 /* Authentication completion callback. */
2238 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2241 SilcPacketStream sock = context;
2242 SilcUnknownEntry entry = silc_packet_get_context(sock);
2243 SilcIDListData idata = (SilcIDListData)entry;
2244 SilcServer server = entry->server;
2245 SilcServerConfigConnParams *param = &server->config->param;
2246 SilcServerConnection sconn;
2248 const char *hostname, *ip;
2252 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2253 NULL, &hostname, &ip, &port);
2255 if (success == FALSE) {
2256 /* Authentication failed */
2257 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2258 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2259 server->stat.auth_failures++;
2260 silc_server_disconnect_remote(server, sock,
2261 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2262 silc_server_config_unref(&entry->cconfig);
2263 silc_server_config_unref(&entry->sconfig);
2264 silc_server_config_unref(&entry->rconfig);
2265 silc_server_free_sock_user_data(server, sock, NULL);
2269 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2271 switch (entry->conn_type) {
2272 case SILC_CONN_CLIENT:
2274 SilcClientEntry client;
2275 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2277 /* Verify whether this connection is after all allowed to connect */
2278 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2279 &server->config->param,
2281 silc_connauth_get_ske(connauth))) {
2282 server->stat.auth_failures++;
2286 /* If we are primary router and we have backup router configured
2287 but it has not connected to use yet, do not accept any other
2289 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2290 !server->backup_router) {
2291 SilcServerConfigRouter *router;
2292 router = silc_server_config_get_backup_router(server);
2293 if (router && strcmp(server->config->server_info->primary->server_ip,
2295 silc_server_find_socket_by_host(server,
2297 router->backup_replace_ip, 0)) {
2298 SILC_LOG_INFO(("Will not accept connections because we do "
2299 "not have backup router connection established"));
2300 silc_server_disconnect_remote(server, sock,
2301 SILC_STATUS_ERR_PERM_DENIED,
2302 "We do not have connection to backup "
2303 "router established, try later");
2304 silc_server_config_unref(&entry->cconfig);
2305 silc_server_config_unref(&entry->sconfig);
2306 silc_server_config_unref(&entry->rconfig);
2307 silc_server_free_sock_user_data(server, sock, NULL);
2308 server->stat.auth_failures++;
2310 /* From here on, wait 20 seconds for the backup router to appear. */
2311 silc_schedule_task_add_timeout(server->schedule,
2312 silc_server_backup_router_wait,
2313 (void *)server, 20, 0);
2318 SILC_LOG_DEBUG(("Remote host is client"));
2319 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2322 /* Add the client to the client ID cache. The nickname and Client ID
2323 and other information is created after we have received NEW_CLIENT
2324 packet from client. */
2325 client = silc_idlist_add_client(server->local_list,
2326 NULL, NULL, NULL, NULL, NULL, sock);
2328 SILC_LOG_ERROR(("Could not add new client to cache"));
2329 server->stat.auth_failures++;
2330 silc_server_disconnect_remote(server, sock,
2331 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2332 silc_server_config_unref(&entry->cconfig);
2333 silc_server_config_unref(&entry->sconfig);
2334 silc_server_config_unref(&entry->rconfig);
2335 silc_server_free_sock_user_data(server, sock, NULL);
2338 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2339 entry->data.conn_type = SILC_CONN_CLIENT;
2342 server->stat.my_clients++;
2343 server->stat.clients++;
2344 server->stat.cell_clients++;
2346 /* Get connection parameters */
2348 param = conn->param;
2350 if (!param->keepalive_secs)
2351 param->keepalive_secs = server->config->param.keepalive_secs;
2353 if (!param->qos && server->config->param.qos) {
2354 param->qos = server->config->param.qos;
2355 param->qos_rate_limit = server->config->param.qos_rate_limit;
2356 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2357 param->qos_limit_sec = server->config->param.qos_limit_sec;
2358 param->qos_limit_usec = server->config->param.qos_limit_usec;
2361 /* Check if to be anonymous connection */
2362 if (param->anonymous)
2363 client->mode |= SILC_UMODE_ANONYMOUS;
2366 /* Add public key to repository */
2367 SILC_LOG_DEBUG(("Add client public key to repository"));
2368 if (!silc_server_get_public_key_by_client(server, client, NULL))
2369 silc_skr_add_public_key_simple(server->repository,
2370 entry->data.public_key,
2371 SILC_SKR_USAGE_IDENTIFICATION, client,
2374 id_entry = (void *)client;
2378 case SILC_CONN_SERVER:
2379 case SILC_CONN_ROUTER:
2381 SilcServerEntry new_server;
2382 SilcBool initiator = FALSE;
2383 SilcBool backup_local = FALSE;
2384 SilcBool backup_router = FALSE;
2385 char *backup_replace_ip = NULL;
2386 SilcUInt16 backup_replace_port = 0;
2387 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2388 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2390 /* If we are backup router and this is incoming server connection
2391 and we do not have connection to primary router, do not allow
2393 if (server->server_type == SILC_BACKUP_ROUTER &&
2394 entry->conn_type == SILC_CONN_SERVER &&
2395 !SILC_PRIMARY_ROUTE(server)) {
2396 SILC_LOG_INFO(("Will not accept server connection because we do "
2397 "not have primary router connection established"));
2398 silc_server_disconnect_remote(server, sock,
2399 SILC_STATUS_ERR_PERM_DENIED,
2400 "We do not have connection to primary "
2401 "router established, try later");
2402 silc_server_config_unref(&entry->cconfig);
2403 silc_server_config_unref(&entry->sconfig);
2404 silc_server_config_unref(&entry->rconfig);
2405 silc_server_free_sock_user_data(server, sock, NULL);
2406 server->stat.auth_failures++;
2410 if (entry->conn_type == SILC_CONN_ROUTER) {
2411 /* Verify whether this connection is after all allowed to connect */
2412 if (!silc_server_connection_allowed(server, sock,
2414 &server->config->param,
2415 rconn ? rconn->param : NULL,
2416 silc_connauth_get_ske(connauth))) {
2417 silc_server_config_unref(&entry->cconfig);
2418 silc_server_config_unref(&entry->sconfig);
2419 silc_server_config_unref(&entry->rconfig);
2420 server->stat.auth_failures++;
2426 param = rconn->param;
2428 if (!param->keepalive_secs)
2429 param->keepalive_secs = server->config->param.keepalive_secs;
2431 if (!param->qos && server->config->param.qos) {
2432 param->qos = server->config->param.qos;
2433 param->qos_rate_limit = server->config->param.qos_rate_limit;
2434 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2435 param->qos_limit_sec = server->config->param.qos_limit_sec;
2436 param->qos_limit_usec = server->config->param.qos_limit_usec;
2440 initiator = rconn->initiator;
2441 backup_local = rconn->backup_local;
2442 backup_router = rconn->backup_router;
2443 backup_replace_ip = rconn->backup_replace_ip;
2444 backup_replace_port = rconn->backup_replace_port;
2448 if (entry->conn_type == SILC_CONN_SERVER) {
2449 /* Verify whether this connection is after all allowed to connect */
2450 if (!silc_server_connection_allowed(server, sock,
2452 &server->config->param,
2453 srvconn ? srvconn->param : NULL,
2454 silc_connauth_get_ske(connauth))) {
2455 server->stat.auth_failures++;
2459 if (srvconn->param) {
2460 param = srvconn->param;
2462 if (!param->keepalive_secs)
2463 param->keepalive_secs = server->config->param.keepalive_secs;
2465 if (!param->qos && server->config->param.qos) {
2466 param->qos = server->config->param.qos;
2467 param->qos_rate_limit = server->config->param.qos_rate_limit;
2468 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2469 param->qos_limit_sec = server->config->param.qos_limit_sec;
2470 param->qos_limit_usec = server->config->param.qos_limit_usec;
2474 backup_router = srvconn->backup_router;
2478 /* If we are primary router and we have backup router configured
2479 but it has not connected to use yet, do not accept any other
2481 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2482 !server->backup_router && !backup_router) {
2483 SilcServerConfigRouter *router;
2484 router = silc_server_config_get_backup_router(server);
2485 if (router && strcmp(server->config->server_info->primary->server_ip,
2487 silc_server_find_socket_by_host(server,
2489 router->backup_replace_ip, 0)) {
2490 SILC_LOG_INFO(("Will not accept connections because we do "
2491 "not have backup router connection established"));
2492 silc_server_disconnect_remote(server, sock,
2493 SILC_STATUS_ERR_PERM_DENIED,
2494 "We do not have connection to backup "
2495 "router established, try later");
2496 silc_server_config_unref(&entry->cconfig);
2497 silc_server_config_unref(&entry->sconfig);
2498 silc_server_config_unref(&entry->rconfig);
2499 silc_server_free_sock_user_data(server, sock, NULL);
2500 server->stat.auth_failures++;
2502 /* From here on, wait 20 seconds for the backup router to appear. */
2503 silc_schedule_task_add_timeout(server->schedule,
2504 silc_server_backup_router_wait,
2505 (void *)server, 20, 0);
2510 SILC_LOG_DEBUG(("Remote host is %s",
2511 entry->conn_type == SILC_CONN_SERVER ?
2512 "server" : (backup_router ?
2513 "backup router" : "router")));
2514 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2515 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2516 "server" : (backup_router ?
2517 "backup router" : "router")));
2519 /* Add the server into server cache. The server name and Server ID
2520 is updated after we have received NEW_SERVER packet from the
2521 server. We mark ourselves as router for this server if we really
2524 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2525 server->local_list : (backup_router ?
2526 server->local_list :
2527 server->global_list)),
2529 (entry->conn_type == SILC_CONN_SERVER ?
2530 SILC_SERVER : SILC_ROUTER),
2532 (entry->conn_type == SILC_CONN_SERVER ?
2533 server->id_entry : (backup_router ?
2534 server->id_entry : NULL)),
2537 SILC_LOG_ERROR(("Could not add new server to cache"));
2538 silc_server_disconnect_remote(server, sock,
2539 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2540 silc_server_config_unref(&entry->cconfig);
2541 silc_server_config_unref(&entry->sconfig);
2542 silc_server_config_unref(&entry->rconfig);
2543 silc_server_free_sock_user_data(server, sock, NULL);
2544 server->stat.auth_failures++;
2547 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2548 entry->data.conn_type = entry->conn_type;
2550 id_entry = (void *)new_server;
2552 /* If the incoming connection is router and marked as backup router
2553 then add it to be one of our backups */
2554 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2555 /* Change it back to SERVER type since that's what it really is. */
2557 entry->data.conn_type = SILC_CONN_SERVER;
2558 new_server->server_type = SILC_BACKUP_ROUTER;
2560 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2561 ("Backup router %s is now online",
2564 /* Remove the backup waiting with timeout */
2565 silc_schedule_task_add_timeout(server->schedule,
2566 silc_server_backup_router_wait,
2567 (void *)server, 10, 0);
2571 if (entry->data.conn_type == SILC_CONN_SERVER) {
2572 server->stat.my_servers++;
2573 server->stat.servers++;
2574 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2576 server->stat.my_routers++;
2577 server->stat.routers++;
2578 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2581 /* Check whether this connection is to be our primary router connection
2582 if we do not already have the primary route. */
2583 if (!backup_router &&
2584 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2585 if (silc_server_config_is_primary_route(server) && !initiator)
2588 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2589 server->standalone = FALSE;
2590 if (!server->id_entry->router) {
2591 server->id_entry->router = id_entry;
2592 server->router = id_entry;
2604 /* Add connection to server->conns so that we know we have connection
2606 sconn = silc_calloc(1, sizeof(*sconn));
2607 sconn->server = server;
2609 sconn->remote_host = strdup(hostname);
2610 sconn->remote_port = port;
2611 silc_dlist_add(server->conns, sconn);
2612 idata->sconn = sconn;
2613 idata->sconn->callback = NULL;
2614 idata->last_receive = time(NULL);
2616 /* Add the common data structure to the ID entry. */
2617 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2618 silc_packet_set_context(sock, id_entry);
2620 /* Connection has been fully established now. Everything is ok. */
2621 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2623 /* Perform Quality of Service */
2625 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2626 param->qos_rate_limit, param->qos_bytes_limit,
2627 param->qos_limit_sec, param->qos_limit_usec);
2629 silc_server_config_unref(&entry->cconfig);
2630 silc_server_config_unref(&entry->sconfig);
2631 silc_server_config_unref(&entry->rconfig);
2635 silc_ske_free(silc_connauth_get_ske(connauth));
2636 silc_connauth_free(connauth);
2639 /* SKE completion callback. We set the new keys into use here. */
2642 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2643 SilcSKESecurityProperties prop,
2644 SilcSKEKeyMaterial keymat,
2645 SilcSKERekeyMaterial rekey,
2648 SilcPacketStream sock = context;
2649 SilcUnknownEntry entry = silc_packet_get_context(sock);
2650 SilcIDListData idata = (SilcIDListData)entry;
2651 SilcServer server = entry->server;
2652 SilcConnAuth connauth;
2653 SilcCipher send_key, receive_key;
2654 SilcHmac hmac_send, hmac_receive;
2661 if (status != SILC_SKE_STATUS_OK) {
2663 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2664 silc_ske_map_status(status), entry->hostname, entry->ip));
2666 silc_server_disconnect_remote(server, sock,
2667 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2668 silc_server_config_unref(&entry->cconfig);
2669 silc_server_config_unref(&entry->sconfig);
2670 silc_server_config_unref(&entry->rconfig);
2671 silc_server_free_sock_user_data(server, sock, NULL);
2675 SILC_LOG_DEBUG(("Setting keys into use"));
2677 /* Set the keys into use. The data will be encrypted after this. */
2678 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2679 &hmac_send, &hmac_receive, &hash)) {
2680 /* Error setting keys */
2682 silc_server_disconnect_remote(server, sock,
2683 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2684 silc_server_free_sock_user_data(server, sock, NULL);
2687 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2688 hmac_receive, FALSE);
2690 idata->rekey = rekey;
2691 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2692 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2694 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2699 SILC_LOG_DEBUG(("Starting connection authentication"));
2700 server->stat.auth_attempts++;
2702 connauth = silc_connauth_alloc(server->schedule, ske,
2703 server->config->conn_auth_timeout);
2705 /** Error allocating auth protocol */
2707 silc_server_disconnect_remote(server, sock,
2708 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2709 silc_server_config_unref(&entry->cconfig);
2710 silc_server_config_unref(&entry->sconfig);
2711 silc_server_config_unref(&entry->rconfig);
2712 silc_server_free_sock_user_data(server, sock, NULL);
2716 /* Start connection authentication */
2718 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2719 silc_server_accept_auth_compl, sock);
2722 /* Accept new TCP connection */
2724 static void silc_server_accept_new_connection(SilcNetStatus status,
2728 SilcServer server = context;
2729 SilcPacketStream packet_stream;
2730 SilcServerConfigClient *cconfig = NULL;
2731 SilcServerConfigServer *sconfig = NULL;
2732 SilcServerConfigRouter *rconfig = NULL;
2733 SilcServerConfigDeny *deny;
2734 SilcUnknownEntry entry;
2736 SilcSKEParamsStruct params;
2737 char *hostname, *ip;
2740 SILC_LOG_DEBUG(("Accepting new connection"));
2742 /* Check for maximum allowed connections */
2743 server->stat.conn_attempts++;
2744 if (silc_dlist_count(server->conns) >
2745 server->config->param.connections_max) {
2746 SILC_LOG_ERROR(("Refusing connection, server is full"));
2747 server->stat.conn_failures++;
2748 silc_stream_destroy(stream);
2752 /* Get hostname, IP and port */
2753 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2754 (const char **)&ip, &port)) {
2755 /* Bad socket stream */
2756 server->stat.conn_failures++;
2757 silc_stream_destroy(stream);
2761 /* Create packet stream */
2762 packet_stream = silc_packet_stream_create(server->packet_engine,
2763 server->schedule, stream);
2764 if (!packet_stream) {
2765 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2766 server->stat.conn_failures++;
2767 silc_stream_destroy(stream);
2770 server->stat.conn_num++;
2772 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2774 /* Set source ID to packet stream */
2775 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2778 server->stat.conn_failures++;
2779 silc_packet_stream_destroy(packet_stream);
2783 /* Check whether this connection is denied to connect to us. */
2784 deny = silc_server_config_find_denied(server, ip);
2786 deny = silc_server_config_find_denied(server, hostname);
2788 /* The connection is denied */
2789 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2790 silc_server_disconnect_remote(server, packet_stream,
2791 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2793 silc_server_free_sock_user_data(server, packet_stream, NULL);
2797 /* Check whether we have configured this sort of connection at all. We
2798 have to check all configurations since we don't know what type of
2799 connection this is. */
2800 if (!(cconfig = silc_server_config_find_client(server, ip)))
2801 cconfig = silc_server_config_find_client(server, hostname);
2802 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2803 sconfig = silc_server_config_find_server_conn(server, hostname);
2804 if (server->server_type == SILC_ROUTER)
2805 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2806 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2807 if (!cconfig && !sconfig && !rconfig) {
2808 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2809 server->stat.conn_failures++;
2810 silc_server_disconnect_remote(server, packet_stream,
2811 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2812 silc_server_free_sock_user_data(server, packet_stream, NULL);
2816 /* The connection is allowed */
2817 entry = silc_calloc(1, sizeof(*entry));
2819 server->stat.conn_failures++;
2820 silc_server_disconnect_remote(server, packet_stream,
2821 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2822 silc_server_free_sock_user_data(server, packet_stream, NULL);
2825 entry->hostname = hostname;
2828 entry->server = server;
2829 entry->data.conn_type = SILC_CONN_UNKNOWN;
2830 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2831 silc_packet_set_context(packet_stream, entry);
2833 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2835 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2836 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2837 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2839 /* Take flags for key exchange. Since we do not know what type of connection
2840 this is, we go through all found configurations and use the global ones
2841 as well. This will result always into strictest key exchange flags. */
2842 memset(¶ms, 0, sizeof(params));
2843 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2844 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2845 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2846 if (server->config->param.key_exchange_pfs)
2847 params.flags |= SILC_SKE_SP_FLAG_PFS;
2849 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2850 server->stat.conn_attempts++;
2852 /* Start SILC Key Exchange protocol */
2853 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2854 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2855 server->public_key, server->private_key,
2858 server->stat.conn_failures++;
2859 silc_server_disconnect_remote(server, packet_stream,
2860 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2861 silc_server_free_sock_user_data(server, packet_stream, NULL);
2864 silc_ske_set_callbacks(ske, silc_server_verify_key,
2865 silc_server_accept_completed, packet_stream);
2867 /* Start key exchange protocol */
2868 params.version = silc_version_string;
2869 params.timeout_secs = server->config->key_exchange_timeout;
2870 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2874 /********************************** Rekey ***********************************/
2876 /* Initiator rekey completion callback */
2878 static void silc_server_rekey_completion(SilcSKE ske,
2879 SilcSKEStatus status,
2880 const SilcSKESecurityProperties prop,
2881 const SilcSKEKeyMaterial keymat,
2882 SilcSKERekeyMaterial rekey,
2885 SilcPacketStream sock = context;
2886 SilcIDListData idata = silc_packet_get_context(sock);
2887 SilcServer server = idata->sconn->server;
2889 idata->sconn->op = NULL;
2890 if (status != SILC_SKE_STATUS_OK) {
2891 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2892 idata->sconn->remote_host));
2896 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2897 idata->sconn->remote_host, idata->sconn->remote_port,
2898 SILC_CONNTYPE_STRING(idata->conn_type)));
2900 /* Save rekey data for next rekey */
2901 idata->rekey = rekey;
2903 /* Register new rekey timeout */
2904 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2905 sock, idata->sconn->rekey_timeout, 0);
2908 /* Rekey callback. Start rekey as initiator */
2910 SILC_TASK_CALLBACK(silc_server_do_rekey)
2912 SilcServer server = app_context;
2913 SilcPacketStream sock = context;
2914 SilcIDListData idata = silc_packet_get_context(sock);
2917 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2919 /* Do not execute rekey with disabled connections */
2920 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2923 /* If another protocol is active do not start rekey */
2924 if (idata->sconn->op) {
2925 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2926 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2931 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2932 idata->sconn->remote_host, idata->sconn->remote_port,
2933 SILC_CONNTYPE_STRING(idata->conn_type)));
2936 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2937 server->public_key, NULL, sock);
2941 /* Set SKE callbacks */
2942 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2945 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2948 /* Responder rekey completion callback */
2951 silc_server_rekey_resp_completion(SilcSKE ske,
2952 SilcSKEStatus status,
2953 const SilcSKESecurityProperties prop,
2954 const SilcSKEKeyMaterial keymat,
2955 SilcSKERekeyMaterial rekey,
2958 SilcPacketStream sock = context;
2959 SilcIDListData idata = silc_packet_get_context(sock);
2961 idata->sconn->op = NULL;
2962 if (status != SILC_SKE_STATUS_OK) {
2963 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2964 idata->sconn->remote_host));
2968 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2969 idata->sconn->remote_host, idata->sconn->remote_port,
2970 SILC_CONNTYPE_STRING(idata->conn_type)));
2972 /* Save rekey data for next rekey */
2973 idata->rekey = rekey;
2976 /* Start rekey as responder */
2978 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2981 SilcIDListData idata = silc_packet_get_context(sock);
2984 if (!idata->rekey) {
2985 silc_packet_free(packet);
2989 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
2990 idata->sconn->remote_host, idata->sconn->remote_port,
2991 SILC_CONNTYPE_STRING(idata->conn_type), sock));
2994 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2995 server->public_key, NULL, sock);
2997 silc_packet_free(packet);
3001 /* Set SKE callbacks */
3002 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3005 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3010 /****************************** Disconnection *******************************/
3012 /* Destroys packet stream. */
3014 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3016 silc_packet_stream_unref(context);
3019 /* Closes connection to socket connection */
3021 void silc_server_close_connection(SilcServer server,
3022 SilcPacketStream sock)
3024 SilcIDListData idata = silc_packet_get_context(sock);
3026 const char *hostname;
3029 if (!silc_packet_stream_is_valid(sock))
3032 memset(tmp, 0, sizeof(tmp));
3033 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3034 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3035 NULL, &hostname, NULL, &port);
3036 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3037 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3038 tmp[0] ? tmp : ""));
3040 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3042 if (idata && idata->sconn) {
3043 silc_server_connection_free(idata->sconn);
3044 idata->sconn = NULL;
3047 /* Take a reference and then destroy the stream. The last reference
3048 is released later in a timeout callback. */
3049 silc_packet_stream_ref(sock);
3050 silc_packet_stream_destroy(sock);
3052 /* Close connection with timeout */
3053 server->stat.conn_num--;
3054 silc_schedule_task_del_by_all(server->schedule, 0,
3055 silc_server_close_connection_final, sock);
3056 silc_schedule_task_add_timeout(server->schedule,
3057 silc_server_close_connection_final,
3061 /* Sends disconnect message to remote connection and disconnects the
3064 void silc_server_disconnect_remote(SilcServer server,
3065 SilcPacketStream sock,
3066 SilcStatus status, ...)
3068 unsigned char buf[512];
3075 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock));
3077 va_start(ap, status);
3078 cp = va_arg(ap, char *);
3080 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3083 /* Send SILC_PACKET_DISCONNECT */
3084 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3085 SILC_STR_UI_CHAR(status),
3086 SILC_STR_UI8_STRING(cp ? buf : NULL),
3089 /* Close connection */
3090 silc_server_close_connection(server, sock);
3093 /* Frees client data and notifies about client's signoff. */
3095 void silc_server_free_client_data(SilcServer server,
3096 SilcPacketStream sock,
3097 SilcClientEntry client,
3099 const char *signoff)
3101 SILC_LOG_DEBUG(("Freeing client %p data", client));
3104 /* Check if anyone is watching this nickname */
3105 if (server->server_type == SILC_ROUTER)
3106 silc_server_check_watcher_list(server, client, NULL,
3107 SILC_NOTIFY_TYPE_SIGNOFF);
3109 /* Send SIGNOFF notify to routers. */
3111 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3112 SILC_BROADCAST(server), client->id,
3116 /* Remove client from all channels */
3118 silc_server_remove_from_channels(server, NULL, client,
3119 TRUE, (char *)signoff, TRUE, FALSE);
3121 silc_server_remove_from_channels(server, NULL, client,
3122 FALSE, NULL, FALSE, FALSE);
3124 /* Remove this client from watcher list if it is */
3125 silc_server_del_from_watcher_list(server, client);
3127 /* Remove client's public key from repository, this will free it too. */
3128 if (client->data.public_key) {
3129 silc_skr_del_public_key(server->repository, client->data.public_key,
3131 client->data.public_key = NULL;
3134 /* Update statistics */
3135 server->stat.my_clients--;
3136 server->stat.clients--;
3137 if (server->stat.cell_clients)
3138 server->stat.cell_clients--;
3139 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3140 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3141 silc_schedule_task_del_by_context(server->schedule, client);
3143 if (client->data.sconn) {
3144 silc_server_connection_free(client->data.sconn);
3145 client->data.sconn = NULL;
3148 /* We will not delete the client entry right away. We will take it
3149 into history (for WHOWAS command) for 5 minutes, unless we're
3150 shutting down server. */
3151 if (!server->server_shutdown) {
3152 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3154 client->router = NULL;
3155 client->connection = NULL;
3156 client->data.created = silc_time();
3157 silc_dlist_del(server->expired_clients, client);
3158 silc_dlist_add(server->expired_clients, client);
3160 /* Delete directly since we're shutting down server */
3161 SILC_LOG_DEBUG(("Delete client directly"));
3162 silc_idlist_del_data(client);
3163 silc_idlist_del_client(server->local_list, client);
3167 /* Frees user_data pointer from socket connection object. This also sends
3168 appropriate notify packets to the network to inform about leaving
3171 void silc_server_free_sock_user_data(SilcServer server,
3172 SilcPacketStream sock,
3173 const char *signoff_message)
3175 SilcIDListData idata;
3182 SILC_LOG_DEBUG(("Start, sock %p", sock));
3184 idata = silc_packet_get_context(sock);
3188 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3191 /* Cancel active protocols */
3193 if (idata->sconn && idata->sconn->op) {
3194 SILC_LOG_DEBUG(("Abort active protocol"));
3195 silc_async_abort(idata->sconn->op, NULL, NULL);
3197 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3198 ((SilcUnknownEntry)idata)->op) {
3199 SILC_LOG_DEBUG(("Abort active protocol"));
3200 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3204 switch (idata->conn_type) {
3205 case SILC_CONN_CLIENT:
3207 SilcClientEntry client_entry = (SilcClientEntry)idata;
3208 silc_server_free_client_data(server, sock, client_entry, TRUE,
3210 silc_packet_set_context(sock, NULL);
3214 case SILC_CONN_SERVER:
3215 case SILC_CONN_ROUTER:
3217 SilcServerEntry user_data = (SilcServerEntry)idata;
3218 SilcServerEntry backup_router = NULL;
3220 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3223 backup_router = silc_server_backup_get(server, user_data->id);
3225 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3226 backup_router == server->id_entry &&
3227 idata->conn_type != SILC_CONN_ROUTER)
3228 backup_router = NULL;
3230 if (server->server_shutdown || server->backup_noswitch)
3231 backup_router = NULL;
3233 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3234 NULL, NULL, &ip, &port);
3236 /* If this was our primary router connection then we're lost to
3237 the outside world. */
3238 if (server->router == user_data) {
3239 /* Check whether we have a backup router connection */
3240 if (!backup_router || backup_router == user_data) {
3241 if (!server->no_reconnect)
3242 silc_server_create_connections(server);
3243 server->id_entry->router = NULL;
3244 server->router = NULL;
3245 server->standalone = TRUE;
3246 server->backup_primary = FALSE;
3247 backup_router = NULL;
3249 if (server->id_entry != backup_router) {
3250 SILC_LOG_INFO(("New primary router is backup router %s",
3251 backup_router->server_name));
3252 server->id_entry->router = backup_router;
3253 server->router = backup_router;
3254 server->router_connect = time(0);
3255 server->backup_primary = TRUE;
3256 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3258 /* Send START_USE to backup router to indicate we have switched */
3259 silc_server_backup_send_start_use(server,
3260 backup_router->connection,
3263 SILC_LOG_INFO(("We are now new primary router in this cell"));
3264 server->id_entry->router = NULL;
3265 server->router = NULL;
3266 server->standalone = TRUE;
3269 /* We stop here to take a breath */
3272 if (server->backup_router) {
3273 server->server_type = SILC_ROUTER;
3275 /* We'll need to constantly try to reconnect to the primary
3276 router so that we'll see when it comes back online. */
3277 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3278 silc_server_backup_connected,
3282 /* Mark this connection as replaced */
3283 silc_server_backup_replaced_add(server, user_data->id,
3286 } else if (backup_router) {
3287 SILC_LOG_INFO(("Enabling the use of backup router %s",
3288 backup_router->server_name));
3290 /* Mark this connection as replaced */
3291 silc_server_backup_replaced_add(server, user_data->id,
3293 } else if (server->server_type == SILC_SERVER &&
3294 idata->conn_type == SILC_CONN_ROUTER) {
3295 /* Reconnect to the router (backup) */
3296 if (!server->no_reconnect)
3297 silc_server_create_connections(server);
3300 if (user_data->server_name)
3301 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3302 ("Server %s signoff", user_data->server_name));
3304 if (!backup_router) {
3305 /* Remove all servers that are originated from this server, and
3306 remove the clients of those servers too. */
3307 silc_server_remove_servers_by_server(server, user_data, TRUE);
3310 /* Remove the clients that this server owns as they will become
3311 invalid now too. For backup router the server is actually
3312 coming from the primary router, so mark that as the owner
3314 if (server->server_type == SILC_BACKUP_ROUTER &&
3315 sock->type == SILC_CONN_SERVER)
3316 silc_server_remove_clients_by_server(server, server->router,
3320 silc_server_remove_clients_by_server(server, user_data,
3323 /* Remove channels owned by this server */
3324 if (server->server_type == SILC_SERVER)
3325 silc_server_remove_channels_by_server(server, user_data);
3327 /* Enable local server connections that may be disabled */
3328 silc_server_local_servers_toggle_enabled(server, TRUE);
3330 /* Update the client entries of this server to the new backup
3331 router. If we are the backup router we also resolve the real
3332 servers for the clients. After updating is over this also
3333 removes the clients that this server explicitly owns. */
3334 silc_server_update_clients_by_server(server, user_data,
3335 backup_router, TRUE);
3337 /* If we are router and just lost our primary router (now standlaone)
3338 we remove everything that was behind it, since we don't know
3340 if (server->server_type == SILC_ROUTER && server->standalone)
3341 /* Remove all servers that are originated from this server, and
3342 remove the clients of those servers too. */
3343 silc_server_remove_servers_by_server(server, user_data, TRUE);
3345 /* Finally remove the clients that are explicitly owned by this
3346 server. They go down with the server. */
3347 silc_server_remove_clients_by_server(server, user_data,
3350 /* Update our server cache to use the new backup router too. */
3351 silc_server_update_servers_by_server(server, user_data, backup_router);
3352 if (server->server_type == SILC_SERVER)
3353 silc_server_update_channels_by_server(server, user_data,
3356 /* Send notify about primary router going down to local operators */
3357 if (server->backup_router)
3358 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3359 SILC_NOTIFY_TYPE_NONE,
3360 ("%s switched to backup router %s "
3361 "(we are primary router now)",
3362 server->server_name, server->server_name));
3363 else if (server->router)
3364 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3365 SILC_NOTIFY_TYPE_NONE,
3366 ("%s switched to backup router %s",
3367 server->server_name,
3368 server->router->server_name));
3370 server->backup_noswitch = FALSE;
3373 silc_server_connection_free(idata->sconn);
3374 idata->sconn = NULL;
3378 if (idata->conn_type == SILC_CONN_SERVER) {
3379 server->stat.my_servers--;
3380 server->stat.servers--;
3381 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3382 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3383 server->stat.my_routers--;
3384 server->stat.routers--;
3385 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3387 if (server->server_type == SILC_ROUTER)
3388 server->stat.cell_servers--;
3390 /* Free the server entry */
3391 silc_server_backup_del(server, user_data);
3392 silc_server_backup_replaced_del(server, user_data);
3393 silc_idlist_del_data(user_data);
3394 if (!silc_idlist_del_server(server->local_list, user_data))
3395 silc_idlist_del_server(server->global_list, user_data);
3397 if (backup_router && backup_router != server->id_entry) {
3398 /* Announce all of our stuff that was created about 5 minutes ago.
3399 The backup router knows all the other stuff already. */
3400 if (server->server_type == SILC_ROUTER)
3401 silc_server_announce_servers(server, FALSE, time(0) - 300,
3402 backup_router->connection);
3404 /* Announce our clients and channels to the router */
3405 silc_server_announce_clients(server, time(0) - 300,
3406 backup_router->connection);
3407 silc_server_announce_channels(server, time(0) - 300,
3408 backup_router->connection);
3411 silc_packet_set_context(sock, NULL);
3417 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3419 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3422 if (server->router_conn == idata->sconn) {
3423 if (!server->no_reconnect)
3424 silc_server_create_connections(server);
3425 server->router_conn = NULL;
3428 silc_server_connection_free(idata->sconn);
3429 idata->sconn = NULL;
3431 silc_idlist_del_data(idata);
3433 silc_packet_set_context(sock, NULL);
3439 /* Removes client from all channels it has joined. This is used when client
3440 connection is disconnected. If the client on a channel is last, the
3441 channel is removed as well. This sends the SIGNOFF notify types. */
3443 void silc_server_remove_from_channels(SilcServer server,
3444 SilcPacketStream sock,
3445 SilcClientEntry client,
3447 const char *signoff_message,
3451 SilcChannelEntry channel;
3452 SilcChannelClientEntry chl;
3453 SilcHashTableList htl;
3454 SilcBuffer clidp = NULL;
3459 if (notify && !client->id)
3462 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3463 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3466 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3471 /* Remove the client from all channels. The client is removed from
3472 the channels' user list. */
3473 silc_hash_table_list(client->channels, &htl);
3474 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3475 channel = chl->channel;
3477 /* Remove channel if this is last client leaving the channel, unless
3478 the channel is permanent. */
3479 if (server->server_type != SILC_SERVER &&
3480 silc_hash_table_count(channel->user_list) < 2) {
3481 silc_server_channel_delete(server, channel);
3485 silc_hash_table_del(client->channels, channel);
3486 silc_hash_table_del(channel->user_list, client);
3487 channel->user_count--;
3489 /* If there is no global users on the channel anymore mark the channel
3490 as local channel. Do not check if the removed client is local client. */
3491 if (server->server_type == SILC_SERVER && channel->global_users &&
3492 chl->client->router && !silc_server_channel_has_global(channel))
3493 channel->global_users = FALSE;
3495 memset(chl, 'A', sizeof(*chl));
3498 /* Update statistics */
3499 if (SILC_IS_LOCAL(client))
3500 server->stat.my_chanclients--;
3501 if (server->server_type == SILC_ROUTER) {
3502 server->stat.cell_chanclients--;
3503 server->stat.chanclients--;
3506 /* If there is not at least one local user on the channel then we don't
3507 need the channel entry anymore, we can remove it safely, unless the
3508 channel is permanent channel */
3509 if (server->server_type == SILC_SERVER &&
3510 !silc_server_channel_has_local(channel)) {
3511 /* Notify about leaving client if this channel has global users. */
3512 if (notify && channel->global_users)
3513 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3514 SILC_NOTIFY_TYPE_SIGNOFF,
3515 signoff_message ? 2 : 1,
3516 clidp->data, silc_buffer_len(clidp),
3517 signoff_message, signoff_message ?
3518 strlen(signoff_message) : 0);
3520 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3521 silc_server_channel_delete(server, channel);
3525 /* Send notify to channel about client leaving SILC and channel too */
3527 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3528 SILC_NOTIFY_TYPE_SIGNOFF,
3529 signoff_message ? 2 : 1,
3530 clidp->data, silc_buffer_len(clidp),
3531 signoff_message, signoff_message ?
3532 strlen(signoff_message) : 0);
3534 if (killed && clidp) {
3535 /* Remove the client from channel's invite list */
3536 if (channel->invite_list &&
3537 silc_hash_table_count(channel->invite_list)) {
3539 SilcArgumentPayload iargs;
3540 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3541 silc_buffer_len(clidp), 3);
3542 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3543 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3544 silc_buffer_free(ab);
3545 silc_argument_payload_free(iargs);
3549 /* Don't create keys if we are shutting down */
3550 if (server->server_shutdown)
3553 /* Re-generate channel key if needed */
3554 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3555 if (!silc_server_create_channel_key(server, channel, 0))
3558 /* Send the channel key to the channel. The key of course is not sent
3559 to the client who was removed from the channel. */
3560 silc_server_send_channel_key(server, client->connection, channel,
3561 server->server_type == SILC_ROUTER ?
3562 FALSE : !server->standalone);
3566 silc_hash_table_list_reset(&htl);
3568 silc_buffer_free(clidp);
3571 /* Removes client from one channel. This is used for example when client
3572 calls LEAVE command to remove itself from the channel. Returns TRUE
3573 if channel still exists and FALSE if the channel is removed when
3574 last client leaves the channel. If `notify' is FALSE notify messages
3577 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3578 SilcPacketStream sock,
3579 SilcChannelEntry channel,
3580 SilcClientEntry client,
3583 SilcChannelClientEntry chl;
3586 SILC_LOG_DEBUG(("Removing %s from channel %s",
3587 silc_id_render(client->id, SILC_ID_CLIENT),
3588 channel->channel_name));
3590 /* Get the entry to the channel, if this client is not on the channel
3592 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3595 /* Remove channel if this is last client leaving the channel, unless
3596 the channel is permanent. */
3597 if (server->server_type != SILC_SERVER &&
3598 silc_hash_table_count(channel->user_list) < 2) {
3599 silc_server_channel_delete(server, channel);
3603 silc_hash_table_del(client->channels, channel);
3604 silc_hash_table_del(channel->user_list, client);
3605 channel->user_count--;
3607 /* If there is no global users on the channel anymore mark the channel
3608 as local channel. Do not check if the client is local client. */
3609 if (server->server_type == SILC_SERVER && channel->global_users &&
3610 chl->client->router && !silc_server_channel_has_global(channel))
3611 channel->global_users = FALSE;
3613 memset(chl, 'O', sizeof(*chl));
3616 /* Update statistics */
3617 if (SILC_IS_LOCAL(client))
3618 server->stat.my_chanclients--;
3619 if (server->server_type == SILC_ROUTER) {
3620 server->stat.cell_chanclients--;
3621 server->stat.chanclients--;
3624 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3628 /* If there is not at least one local user on the channel then we don't
3629 need the channel entry anymore, we can remove it safely, unless the
3630 channel is permanent channel */
3631 if (server->server_type == SILC_SERVER &&
3632 !silc_server_channel_has_local(channel)) {
3633 /* Notify about leaving client if this channel has global users. */
3634 if (notify && channel->global_users)
3635 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3636 SILC_NOTIFY_TYPE_LEAVE, 1,
3637 clidp->data, silc_buffer_len(clidp));
3639 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3640 silc_server_channel_delete(server, channel);
3641 silc_buffer_free(clidp);
3645 /* Send notify to channel about client leaving the channel */
3647 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3648 SILC_NOTIFY_TYPE_LEAVE, 1,
3649 clidp->data, silc_buffer_len(clidp));
3651 silc_buffer_free(clidp);
3655 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3656 function may be used only by router. In real SILC network all channels
3657 are created by routers thus this function is never used by normal
3660 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3661 SilcServerID *router_id,
3667 SilcChannelID *channel_id;
3668 SilcChannelEntry entry;
3669 SilcCipher send_key, receive_key;
3672 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3675 cipher = SILC_DEFAULT_CIPHER;
3677 hmac = SILC_DEFAULT_HMAC;
3679 /* Allocate cipher */
3680 if (!silc_cipher_alloc(cipher, &send_key))
3682 if (!silc_cipher_alloc(cipher, &receive_key)) {
3683 silc_cipher_free(send_key);
3688 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3689 silc_cipher_free(send_key);
3690 silc_cipher_free(receive_key);
3694 channel_name = strdup(channel_name);
3696 /* Create the channel ID */
3697 if (!silc_id_create_channel_id(server, router_id, server->rng,
3699 silc_free(channel_name);
3700 silc_cipher_free(send_key);
3701 silc_cipher_free(receive_key);
3702 silc_hmac_free(newhmac);
3706 /* Create the channel */
3707 entry = silc_idlist_add_channel(server->local_list, channel_name,
3708 SILC_CHANNEL_MODE_NONE, channel_id,
3709 NULL, send_key, receive_key, newhmac);
3711 silc_free(channel_name);
3712 silc_cipher_free(send_key);
3713 silc_cipher_free(receive_key);
3714 silc_hmac_free(newhmac);
3715 silc_free(channel_id);
3719 entry->cipher = strdup(cipher);
3720 entry->hmac_name = strdup(hmac);
3722 /* Now create the actual key material */
3723 if (!silc_server_create_channel_key(server, entry,
3724 silc_cipher_get_key_len(send_key) / 8)) {
3725 silc_idlist_del_channel(server->local_list, entry);
3729 /* Notify other routers about the new channel. We send the packet
3730 to our primary route. */
3732 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3733 channel_name, entry->id,
3734 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3737 /* Distribute to backup routers */
3738 if (broadcast && server->server_type == SILC_ROUTER) {
3740 unsigned char cid[32];
3741 SilcUInt32 name_len = strlen(channel_name);
3744 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3745 packet = silc_channel_payload_encode(channel_name, name_len,
3746 cid, id_len, entry->mode);
3747 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3748 packet->data, silc_buffer_len(packet), FALSE,
3750 silc_buffer_free(packet);
3753 server->stat.my_channels++;
3754 if (server->server_type == SILC_ROUTER) {
3755 server->stat.channels++;
3756 server->stat.cell_channels++;
3757 entry->users_resolved = TRUE;
3763 /* Same as above but creates the channel with Channel ID `channel_id. */
3766 silc_server_create_new_channel_with_id(SilcServer server,
3770 SilcChannelID *channel_id,
3773 SilcChannelEntry entry;
3774 SilcCipher send_key, receive_key;
3777 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3780 cipher = SILC_DEFAULT_CIPHER;
3782 hmac = SILC_DEFAULT_HMAC;
3784 /* Allocate cipher */
3785 if (!silc_cipher_alloc(cipher, &send_key))
3787 if (!silc_cipher_alloc(cipher, &receive_key)) {
3788 silc_cipher_free(send_key);
3793 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3794 silc_cipher_free(send_key);
3795 silc_cipher_free(receive_key);
3799 channel_name = strdup(channel_name);
3801 /* Create the channel */
3802 entry = silc_idlist_add_channel(server->local_list, channel_name,
3803 SILC_CHANNEL_MODE_NONE, channel_id,
3804 NULL, send_key, receive_key, newhmac);
3806 silc_cipher_free(send_key);
3807 silc_cipher_free(receive_key);
3808 silc_hmac_free(newhmac);
3809 silc_free(channel_name);
3813 /* Now create the actual key material */
3814 if (!silc_server_create_channel_key(server, entry,
3815 silc_cipher_get_key_len(send_key) / 8)) {
3816 silc_idlist_del_channel(server->local_list, entry);
3820 /* Notify other routers about the new channel. We send the packet
3821 to our primary route. */
3823 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3824 channel_name, entry->id,
3825 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3828 /* Distribute to backup routers */
3829 if (broadcast && server->server_type == SILC_ROUTER) {
3831 unsigned char cid[32];
3832 SilcUInt32 name_len = strlen(channel_name);
3835 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3836 packet = silc_channel_payload_encode(channel_name, name_len,
3837 cid, id_len, entry->mode);
3838 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3839 packet->data, silc_buffer_len(packet), FALSE,
3841 silc_buffer_free(packet);
3844 server->stat.my_channels++;
3845 if (server->server_type == SILC_ROUTER) {
3846 server->stat.channels++;
3847 server->stat.cell_channels++;
3848 entry->users_resolved = TRUE;
3854 /* Channel's key re-key timeout callback. */
3856 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3858 SilcServer server = app_context;
3859 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3863 /* Return now if we are shutting down */
3864 if (server->server_shutdown)
3867 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3870 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3873 /* Generates new channel key. This is used to create the initial channel key
3874 but also to re-generate new key for channel. If `key_len' is provided
3875 it is the bytes of the key length. */
3877 SilcBool silc_server_create_channel_key(SilcServer server,
3878 SilcChannelEntry channel,
3882 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3885 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3886 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3890 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3892 if (!channel->send_key)
3893 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3894 channel->send_key = NULL;
3897 if (!channel->receive_key)
3898 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3899 silc_cipher_free(channel->send_key);
3900 channel->send_key = channel->receive_key = NULL;
3906 else if (channel->key_len)
3907 len = channel->key_len / 8;
3909 len = silc_cipher_get_key_len(channel->send_key) / 8;
3911 /* Create channel key */
3912 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3915 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3916 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3918 /* Remove old key if exists */
3920 memset(channel->key, 0, channel->key_len / 8);
3921 silc_free(channel->key);
3925 channel->key_len = len * 8;
3926 channel->key = silc_memdup(channel_key, len);
3927 memset(channel_key, 0, sizeof(channel_key));
3929 /* Generate HMAC key from the channel key data and set it */
3931 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3932 memset(channel->key, 0, channel->key_len / 8);
3933 silc_free(channel->key);
3934 silc_cipher_free(channel->send_key);
3935 silc_cipher_free(channel->receive_key);
3936 channel->send_key = channel->receive_key = NULL;
3939 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3940 silc_hmac_set_key(channel->hmac, hash,
3941 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3942 memset(hash, 0, sizeof(hash));
3944 if (server->server_type == SILC_ROUTER) {
3945 if (!channel->rekey)
3946 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3947 channel->rekey->channel = channel;
3948 channel->rekey->key_len = key_len;
3949 if (channel->rekey->task)
3950 silc_schedule_task_del(server->schedule, channel->rekey->task);
3952 channel->rekey->task =
3953 silc_schedule_task_add_timeout(server->schedule,
3954 silc_server_channel_key_rekey,
3955 (void *)channel->rekey,
3956 server->config->channel_rekey_secs, 0);
3962 /* Saves the channel key found in the encoded `key_payload' buffer. This
3963 function is used when we receive Channel Key Payload and also when we're
3964 processing JOIN command reply. Returns entry to the channel. */
3966 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3967 SilcBuffer key_payload,
3968 SilcChannelEntry channel)
3970 SilcChannelKeyPayload payload = NULL;
3972 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3976 /* Decode channel key payload */
3977 payload = silc_channel_key_payload_parse(key_payload->data,
3978 silc_buffer_len(key_payload));
3980 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3985 /* Get the channel entry */
3988 /* Get channel ID */
3989 tmp = silc_channel_key_get_id(payload, &tmp_len);
3990 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3995 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3997 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3999 if (server->server_type == SILC_ROUTER)
4000 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4001 silc_id_render(&id, SILC_ID_CHANNEL)));
4007 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4009 tmp = silc_channel_key_get_key(payload, &tmp_len);
4015 cipher = silc_channel_key_get_cipher(payload, NULL);
4021 /* Remove old key if exists */
4023 memset(channel->key, 0, channel->key_len / 8);
4024 silc_free(channel->key);
4025 silc_cipher_free(channel->send_key);
4026 silc_cipher_free(channel->receive_key);
4029 /* Create new cipher */
4030 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4031 channel->send_key = NULL;
4035 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4036 silc_cipher_free(channel->send_key);
4037 channel->send_key = channel->receive_key = NULL;
4042 if (channel->cipher)
4043 silc_free(channel->cipher);
4044 channel->cipher = strdup(cipher);
4047 channel->key_len = tmp_len * 8;
4048 channel->key = silc_memdup(tmp, tmp_len);
4049 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4050 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4052 /* Generate HMAC key from the channel key data and set it */
4054 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4055 memset(channel->key, 0, channel->key_len / 8);
4056 silc_free(channel->key);
4057 silc_cipher_free(channel->send_key);
4058 silc_cipher_free(channel->receive_key);
4059 channel->send_key = channel->receive_key = NULL;
4062 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4063 silc_hmac_set_key(channel->hmac, hash,
4064 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4066 memset(hash, 0, sizeof(hash));
4067 memset(tmp, 0, tmp_len);
4069 if (server->server_type == SILC_ROUTER) {
4070 if (!channel->rekey)
4071 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4072 channel->rekey->channel = channel;
4073 if (channel->rekey->task)
4074 silc_schedule_task_del(server->schedule, channel->rekey->task);
4076 channel->rekey->task =
4077 silc_schedule_task_add_timeout(server->schedule,
4078 silc_server_channel_key_rekey,
4079 (void *)channel->rekey,
4080 server->config->channel_rekey_secs, 0);
4085 silc_channel_key_payload_free(payload);
4090 /* Returns assembled of all servers in the given ID list. The packet's
4091 form is dictated by the New ID payload. */
4093 static void silc_server_announce_get_servers(SilcServer server,
4094 SilcServerEntry remote,
4096 SilcBuffer *servers,
4097 unsigned long creation_time)
4100 SilcIDCacheEntry id_cache;
4101 SilcServerEntry entry;
4105 /* Go through all clients in the list */
4106 if (silc_idcache_get_all(id_list->servers, &list)) {
4107 silc_list_start(list);
4108 while ((id_cache = silc_list_get(list))) {
4109 entry = (SilcServerEntry)id_cache->context;
4111 /* Do not announce the one we've sending our announcements and
4112 do not announce ourself. Also check the creation time if it's
4114 if ((entry == remote) || (entry == server->id_entry) ||
4115 (creation_time && entry->data.created < creation_time))
4118 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4120 tmp = silc_buffer_realloc(*servers,
4122 silc_buffer_truelen((*servers)) +
4123 silc_buffer_len(idp) :
4124 silc_buffer_len(idp)));
4128 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4129 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4130 silc_buffer_pull(*servers, silc_buffer_len(idp));
4131 silc_buffer_free(idp);
4137 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4143 p = silc_notify_payload_encode(notify, argc, ap);
4149 /* This function is used by router to announce existing servers to our
4150 primary router when we've connected to it. If `creation_time' is non-zero
4151 then only the servers that has been created after the `creation_time'
4152 will be announced. */
4154 void silc_server_announce_servers(SilcServer server, SilcBool global,
4155 unsigned long creation_time,
4156 SilcPacketStream remote)
4158 SilcBuffer servers = NULL;
4160 SILC_LOG_DEBUG(("Announcing servers"));
4162 /* Get servers in local list */
4163 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4164 server->local_list, &servers,
4168 /* Get servers in global list */
4169 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4170 server->global_list, &servers,
4174 silc_buffer_push(servers, servers->data - servers->head);
4175 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4177 /* Send the packet */
4178 silc_server_packet_send(server, remote,
4179 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4180 servers->data, silc_buffer_len(servers));
4182 silc_buffer_free(servers);
4186 /* Returns assembled packet of all clients in the given ID list. The
4187 packet's form is dictated by the New ID Payload. */
4189 static void silc_server_announce_get_clients(SilcServer server,
4191 SilcBuffer *clients,
4193 unsigned long creation_time)
4196 SilcIDCacheEntry id_cache;
4197 SilcClientEntry client;
4200 unsigned char mode[4];
4203 /* Go through all clients in the list */
4204 if (silc_idcache_get_all(id_list->clients, &list)) {
4205 silc_list_start(list);
4206 while ((id_cache = silc_list_get(list))) {
4207 client = (SilcClientEntry)id_cache->context;
4209 if (creation_time && client->data.created < creation_time)
4211 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4213 if (!client->connection && !client->router)
4216 SILC_LOG_DEBUG(("Announce Client ID %s",
4217 silc_id_render(client->id, SILC_ID_CLIENT)));
4219 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4223 tmp2 = silc_buffer_realloc(*clients,
4225 silc_buffer_truelen((*clients)) +
4226 silc_buffer_len(idp) :
4227 silc_buffer_len(idp)));
4231 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4232 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4233 silc_buffer_pull(*clients, silc_buffer_len(idp));
4235 SILC_PUT32_MSB(client->mode, mode);
4237 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4238 2, idp->data, silc_buffer_len(idp),
4240 tmp2 = silc_buffer_realloc(*umodes,
4242 silc_buffer_truelen((*umodes)) +
4243 silc_buffer_len(tmp) :
4244 silc_buffer_len(tmp)));
4248 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4249 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4250 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4251 silc_buffer_free(tmp);
4253 silc_buffer_free(idp);
4258 /* This function is used to announce our existing clients to our router
4259 when we've connected to it. If `creation_time' is non-zero then only
4260 the clients that has been created after the `creation_time' will be
4263 void silc_server_announce_clients(SilcServer server,
4264 unsigned long creation_time,
4265 SilcPacketStream remote)
4267 SilcBuffer clients = NULL;
4268 SilcBuffer umodes = NULL;
4270 SILC_LOG_DEBUG(("Announcing clients"));
4272 /* Get clients in local list */
4273 silc_server_announce_get_clients(server, server->local_list,
4274 &clients, &umodes, creation_time);
4276 /* As router we announce our global list as well */
4277 if (server->server_type == SILC_ROUTER)
4278 silc_server_announce_get_clients(server, server->global_list,
4279 &clients, &umodes, creation_time);
4282 silc_buffer_push(clients, clients->data - clients->head);
4283 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4285 /* Send the packet */
4286 silc_server_packet_send(server, remote,
4287 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4288 clients->data, silc_buffer_len(clients));
4290 silc_buffer_free(clients);
4294 silc_buffer_push(umodes, umodes->data - umodes->head);
4295 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4297 /* Send the packet */
4298 silc_server_packet_send(server, remote,
4299 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4300 umodes->data, silc_buffer_len(umodes));
4302 silc_buffer_free(umodes);
4306 /* Returns channel's topic for announcing it */
4308 void silc_server_announce_get_channel_topic(SilcServer server,
4309 SilcChannelEntry channel,
4314 if (channel->topic) {
4315 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4316 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4318 silc_buffer_len(chidp),
4320 strlen(channel->topic));
4321 silc_buffer_free(chidp);
4325 /* Returns channel's invite and ban lists */
4327 void silc_server_announce_get_inviteban(SilcServer server,
4328 SilcChannelEntry channel,
4332 SilcBuffer list, idp, idp2, tmp2;
4335 SilcHashTableList htl;
4336 const unsigned char a[1] = { 0x03 };
4338 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4340 /* Encode invite list */
4341 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4342 list = silc_buffer_alloc_size(2);
4343 type = silc_hash_table_count(channel->invite_list);
4344 SILC_PUT16_MSB(type, list->data);
4345 silc_hash_table_list(channel->invite_list, &htl);
4346 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4347 list = silc_argument_payload_encode_one(list, tmp2->data,
4348 silc_buffer_len(tmp2),
4349 SILC_PTR_TO_32(ptype));
4350 silc_hash_table_list_reset(&htl);
4352 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4354 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4355 idp->data, silc_buffer_len(idp),
4356 channel->channel_name,
4357 strlen(channel->channel_name),
4358 idp2->data, silc_buffer_len(idp2),
4360 list->data, silc_buffer_len(list));
4361 silc_buffer_free(idp2);
4362 silc_buffer_free(list);
4365 /* Encode ban list */
4366 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4367 list = silc_buffer_alloc_size(2);
4368 type = silc_hash_table_count(channel->ban_list);
4369 SILC_PUT16_MSB(type, list->data);
4370 silc_hash_table_list(channel->ban_list, &htl);
4371 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4372 list = silc_argument_payload_encode_one(list, tmp2->data,
4373 silc_buffer_len(tmp2),
4374 SILC_PTR_TO_32(ptype));
4375 silc_hash_table_list_reset(&htl);
4378 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4379 idp->data, silc_buffer_len(idp),
4381 list->data, silc_buffer_len(list));
4382 silc_buffer_free(list);
4385 silc_buffer_free(idp);
4388 /* Returns assembled packets for channel users of the `channel'. */
4390 void silc_server_announce_get_channel_users(SilcServer server,
4391 SilcChannelEntry channel,
4392 SilcBuffer *channel_modes,
4393 SilcBuffer *channel_users,
4394 SilcBuffer *channel_users_modes)
4396 SilcChannelClientEntry chl;
4397 SilcHashTableList htl;
4398 SilcBuffer chidp, clidp, csidp;
4399 SilcBuffer tmp, fkey = NULL, chpklist;
4401 unsigned char mode[4], ulimit[4];
4405 SILC_LOG_DEBUG(("Start"));
4407 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4408 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4409 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4412 SILC_PUT32_MSB(channel->mode, mode);
4413 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4414 SILC_PUT32_MSB(channel->user_limit, ulimit);
4415 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4416 if (channel->founder_key)
4417 fkey = silc_public_key_payload_encode(channel->founder_key);
4419 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4421 silc_buffer_len(csidp),
4424 hmac, hmac ? strlen(hmac) : 0,
4425 channel->passphrase,
4426 channel->passphrase ?
4427 strlen(channel->passphrase) : 0,
4428 fkey ? fkey->data : NULL,
4429 fkey ? silc_buffer_len(fkey) : 0,
4430 chpklist ? chpklist->data : NULL,
4432 silc_buffer_len(chpklist) : 0,
4434 SILC_CHANNEL_MODE_ULIMIT ?
4437 SILC_CHANNEL_MODE_ULIMIT ?
4438 sizeof(ulimit) : 0));
4439 len = silc_buffer_len(tmp);
4441 silc_buffer_realloc(*channel_modes,
4443 silc_buffer_truelen((*channel_modes)) + len : len));
4446 *channel_modes = tmp2;
4447 silc_buffer_pull_tail(*channel_modes,
4448 ((*channel_modes)->end -
4449 (*channel_modes)->data));
4450 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4451 silc_buffer_pull(*channel_modes, len);
4452 silc_buffer_free(tmp);
4453 silc_buffer_free(fkey);
4456 /* Now find all users on the channel */
4457 silc_hash_table_list(channel->user_list, &htl);
4458 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4459 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4461 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4465 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4467 silc_buffer_len(clidp),
4469 silc_buffer_len(chidp));
4470 len = silc_buffer_len(tmp);
4472 silc_buffer_realloc(*channel_users,
4474 silc_buffer_truelen((*channel_users)) + len : len));
4477 *channel_users = tmp2;
4478 silc_buffer_pull_tail(*channel_users,
4479 ((*channel_users)->end -
4480 (*channel_users)->data));
4482 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4483 silc_buffer_pull(*channel_users, len);
4484 silc_buffer_free(tmp);
4486 /* CUMODE notify for mode change on the channel */
4487 SILC_PUT32_MSB(chl->mode, mode);
4488 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4489 fkey = silc_public_key_payload_encode(channel->founder_key);
4490 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4492 silc_buffer_len(csidp),
4495 silc_buffer_len(clidp),
4496 fkey ? fkey->data : NULL,
4497 fkey ? silc_buffer_len(fkey) : 0);
4498 len = silc_buffer_len(tmp);
4500 silc_buffer_realloc(*channel_users_modes,
4501 (*channel_users_modes ?
4502 silc_buffer_truelen((*channel_users_modes)) +
4506 *channel_users_modes = tmp2;
4507 silc_buffer_pull_tail(*channel_users_modes,
4508 ((*channel_users_modes)->end -
4509 (*channel_users_modes)->data));
4511 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4512 silc_buffer_pull(*channel_users_modes, len);
4513 silc_buffer_free(tmp);
4514 silc_buffer_free(fkey);
4516 silc_buffer_free(clidp);
4518 silc_hash_table_list_reset(&htl);
4519 silc_buffer_free(chidp);
4520 silc_buffer_free(csidp);
4523 /* Returns assembled packets for all channels and users on those channels
4524 from the given ID List. The packets are in the form dictated by the
4525 New Channel and New Channel User payloads. */
4527 void silc_server_announce_get_channels(SilcServer server,
4529 SilcBuffer *channels,
4530 SilcBuffer **channel_modes,
4531 SilcBuffer *channel_users,
4532 SilcBuffer **channel_users_modes,
4533 SilcUInt32 *channel_users_modes_c,
4534 SilcBuffer **channel_topics,
4535 SilcBuffer **channel_invites,
4536 SilcBuffer **channel_bans,
4537 SilcChannelID ***channel_ids,
4538 unsigned long creation_time)
4541 SilcIDCacheEntry id_cache;
4542 SilcChannelEntry channel;
4543 unsigned char cid[32];
4545 SilcUInt16 name_len;
4547 int i = *channel_users_modes_c;
4551 SILC_LOG_DEBUG(("Start"));
4553 /* Go through all channels in the list */
4554 if (silc_idcache_get_all(id_list->channels, &list)) {
4555 silc_list_start(list);
4556 while ((id_cache = silc_list_get(list))) {
4557 channel = (SilcChannelEntry)id_cache->context;
4559 if (creation_time && channel->created < creation_time)
4564 SILC_LOG_DEBUG(("Announce Channel ID %s",
4565 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4567 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4568 name_len = strlen(channel->channel_name);
4571 len = 4 + name_len + id_len + 4;
4573 silc_buffer_realloc(*channels,
4575 silc_buffer_truelen((*channels)) +
4581 silc_buffer_pull_tail(*channels,
4582 ((*channels)->end - (*channels)->data));
4583 silc_buffer_format(*channels,
4584 SILC_STR_UI_SHORT(name_len),
4585 SILC_STR_UI_XNSTRING(channel->channel_name,
4587 SILC_STR_UI_SHORT(id_len),
4588 SILC_STR_UI_XNSTRING(cid, id_len),
4589 SILC_STR_UI_INT(channel->mode),
4591 silc_buffer_pull(*channels, len);
4594 if (creation_time && channel->updated < creation_time)
4600 /* Channel user modes */
4601 tmp = silc_realloc(*channel_users_modes,
4602 sizeof(**channel_users_modes) * (i + 1));
4605 *channel_users_modes = tmp;
4606 (*channel_users_modes)[i] = NULL;
4607 tmp = silc_realloc(*channel_modes,
4608 sizeof(**channel_modes) * (i + 1));
4611 *channel_modes = tmp;
4612 (*channel_modes)[i] = NULL;
4613 tmp = silc_realloc(*channel_ids,
4614 sizeof(**channel_ids) * (i + 1));
4618 (*channel_ids)[i] = NULL;
4619 silc_server_announce_get_channel_users(server, channel,
4620 &(*channel_modes)[i],
4622 &(*channel_users_modes)[i]);
4623 (*channel_ids)[i] = channel->id;
4625 /* Channel's topic */
4626 tmp = silc_realloc(*channel_topics,
4627 sizeof(**channel_topics) * (i + 1));
4630 *channel_topics = tmp;
4631 (*channel_topics)[i] = NULL;
4632 silc_server_announce_get_channel_topic(server, channel,
4633 &(*channel_topics)[i]);
4635 /* Channel's invite and ban list */
4636 tmp = silc_realloc(*channel_invites,
4637 sizeof(**channel_invites) * (i + 1));
4640 *channel_invites = tmp;
4641 (*channel_invites)[i] = NULL;
4642 tmp = silc_realloc(*channel_bans,
4643 sizeof(**channel_bans) * (i + 1));
4646 *channel_bans = tmp;
4647 (*channel_bans)[i] = NULL;
4648 silc_server_announce_get_inviteban(server, channel,
4649 &(*channel_invites)[i],
4650 &(*channel_bans)[i]);
4652 (*channel_users_modes_c)++;
4660 /* This function is used to announce our existing channels to our router
4661 when we've connected to it. This also announces the users on the
4662 channels to the router. If the `creation_time' is non-zero only the
4663 channels that was created after the `creation_time' are announced.
4664 Note that the channel users are still announced even if the `creation_time'
4667 void silc_server_announce_channels(SilcServer server,
4668 unsigned long creation_time,
4669 SilcPacketStream remote)
4671 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4672 SilcBuffer *channel_users_modes = NULL;
4673 SilcBuffer *channel_topics = NULL;
4674 SilcBuffer *channel_invites = NULL;
4675 SilcBuffer *channel_bans = NULL;
4676 SilcUInt32 channel_users_modes_c = 0;
4677 SilcChannelID **channel_ids = NULL;
4679 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4681 /* Get channels and channel users in local list */
4682 silc_server_announce_get_channels(server, server->local_list,
4683 &channels, &channel_modes,
4685 &channel_users_modes,
4686 &channel_users_modes_c,
4690 &channel_ids, creation_time);
4692 /* Get channels and channel users in global list */
4693 if (server->server_type != SILC_SERVER)
4694 silc_server_announce_get_channels(server, server->global_list,
4695 &channels, &channel_modes,
4697 &channel_users_modes,
4698 &channel_users_modes_c,
4702 &channel_ids, creation_time);
4705 silc_buffer_push(channels, channels->data - channels->head);
4706 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4708 /* Send the packet */
4709 silc_server_packet_send(server, remote,
4710 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4711 channels->data, silc_buffer_len(channels));
4713 silc_buffer_free(channels);
4716 if (channel_users) {
4717 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4718 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4719 silc_buffer_len(channel_users));
4721 /* Send the packet */
4722 silc_server_packet_send(server, remote,
4723 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4724 channel_users->data, silc_buffer_len(channel_users));
4726 silc_buffer_free(channel_users);
4729 if (channel_modes) {
4732 for (i = 0; i < channel_users_modes_c; i++) {
4733 if (!channel_modes[i])
4735 silc_buffer_push(channel_modes[i],
4736 channel_modes[i]->data -
4737 channel_modes[i]->head);
4738 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4739 silc_buffer_len(channel_modes[i]));
4740 silc_server_packet_send_dest(server, remote,
4741 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4742 channel_ids[i], SILC_ID_CHANNEL,
4743 channel_modes[i]->data,
4744 silc_buffer_len(channel_modes[i]));
4745 silc_buffer_free(channel_modes[i]);
4747 silc_free(channel_modes);
4750 if (channel_users_modes) {
4753 for (i = 0; i < channel_users_modes_c; i++) {
4754 if (!channel_users_modes[i])
4756 silc_buffer_push(channel_users_modes[i],
4757 channel_users_modes[i]->data -
4758 channel_users_modes[i]->head);
4759 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4760 silc_buffer_len(channel_users_modes[i]));
4761 silc_server_packet_send_dest(server, remote,
4762 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4763 channel_ids[i], SILC_ID_CHANNEL,
4764 channel_users_modes[i]->data,
4765 silc_buffer_len(channel_users_modes[i]));
4766 silc_buffer_free(channel_users_modes[i]);
4768 silc_free(channel_users_modes);
4771 if (channel_topics) {
4774 for (i = 0; i < channel_users_modes_c; i++) {
4775 if (!channel_topics[i])
4778 silc_buffer_push(channel_topics[i],
4779 channel_topics[i]->data -
4780 channel_topics[i]->head);
4781 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4782 silc_buffer_len(channel_topics[i]));
4783 silc_server_packet_send_dest(server, remote,
4784 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4785 channel_ids[i], SILC_ID_CHANNEL,
4786 channel_topics[i]->data,
4787 silc_buffer_len(channel_topics[i]));
4788 silc_buffer_free(channel_topics[i]);
4790 silc_free(channel_topics);
4793 if (channel_invites) {
4796 for (i = 0; i < channel_users_modes_c; i++) {
4797 if (!channel_invites[i])
4800 silc_buffer_push(channel_invites[i],
4801 channel_invites[i]->data -
4802 channel_invites[i]->head);
4803 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4804 silc_buffer_len(channel_invites[i]));
4805 silc_server_packet_send_dest(server, remote,
4806 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4807 channel_ids[i], SILC_ID_CHANNEL,
4808 channel_invites[i]->data,
4809 silc_buffer_len(channel_invites[i]));
4810 silc_buffer_free(channel_invites[i]);
4812 silc_free(channel_invites);
4818 for (i = 0; i < channel_users_modes_c; i++) {
4819 if (!channel_bans[i])
4822 silc_buffer_push(channel_bans[i],
4823 channel_bans[i]->data -
4824 channel_bans[i]->head);
4825 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4826 silc_buffer_len(channel_bans[i]));
4827 silc_server_packet_send_dest(server, remote,
4828 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4829 channel_ids[i], SILC_ID_CHANNEL,
4830 channel_bans[i]->data,
4831 silc_buffer_len(channel_bans[i]));
4832 silc_buffer_free(channel_bans[i]);
4834 silc_free(channel_bans);
4837 silc_free(channel_ids);
4840 /* Announces WATCH list. */
4842 void silc_server_announce_watches(SilcServer server,
4843 SilcPacketStream remote)
4845 SilcHashTableList htl;
4846 SilcBuffer buffer, idp, args, pkp;
4847 SilcClientEntry client;
4850 SILC_LOG_DEBUG(("Announcing watch list"));
4852 /* XXX because way we save the nicks (hash) we cannot announce them. */
4854 /* XXX we should send all public keys in one command if client is
4855 watching more than one key */
4856 silc_hash_table_list(server->watcher_list_pk, &htl);
4857 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4858 if (!client || !client->id)
4861 server->stat.commands_sent++;
4863 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4864 args = silc_buffer_alloc_size(2);
4865 silc_buffer_format(args,
4866 SILC_STR_UI_SHORT(1),
4868 pkp = silc_public_key_payload_encode(key);
4869 args = silc_argument_payload_encode_one(args, pkp->data,
4870 silc_buffer_len(pkp), 0x00);
4871 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4872 ++server->cmd_ident, 2,
4873 1, idp->data, silc_buffer_len(idp),
4875 silc_buffer_len(args));
4878 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4879 buffer->data, silc_buffer_len(buffer));
4881 silc_buffer_free(pkp);
4882 silc_buffer_free(args);
4883 silc_buffer_free(idp);
4884 silc_buffer_free(buffer);
4886 silc_hash_table_list_reset(&htl);
4889 /* Assembles user list and users mode list from the `channel'. */
4891 SilcBool silc_server_get_users_on_channel(SilcServer server,
4892 SilcChannelEntry channel,
4893 SilcBuffer *user_list,
4894 SilcBuffer *mode_list,
4895 SilcUInt32 *user_count)
4897 SilcChannelClientEntry chl;
4898 SilcHashTableList htl;
4899 SilcBuffer client_id_list;
4900 SilcBuffer client_mode_list;
4902 SilcUInt32 list_count = 0, len = 0;
4904 if (!silc_hash_table_count(channel->user_list))
4907 silc_hash_table_list(channel->user_list, &htl);
4908 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4909 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4910 silc_hash_table_list_reset(&htl);
4912 client_id_list = silc_buffer_alloc(len);
4914 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4915 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4916 silc_buffer_pull_tail(client_mode_list,
4917 silc_buffer_truelen(client_mode_list));
4919 silc_hash_table_list(channel->user_list, &htl);
4920 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4922 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4923 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4924 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4925 silc_buffer_free(idp);
4927 /* Client's mode on channel */
4928 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4929 silc_buffer_pull(client_mode_list, 4);
4933 silc_hash_table_list_reset(&htl);
4934 silc_buffer_push(client_id_list,
4935 client_id_list->data - client_id_list->head);
4936 silc_buffer_push(client_mode_list,
4937 client_mode_list->data - client_mode_list->head);
4939 *user_list = client_id_list;
4940 *mode_list = client_mode_list;
4941 *user_count = list_count;
4945 /* Saves users and their modes to the `channel'. */
4947 void silc_server_save_users_on_channel(SilcServer server,
4948 SilcPacketStream sock,
4949 SilcChannelEntry channel,
4950 SilcClientID *noadd,
4951 SilcBuffer user_list,
4952 SilcBuffer mode_list,
4953 SilcUInt32 user_count)
4959 SilcClientEntry client;
4960 SilcIDCacheEntry cache;
4961 SilcChannelClientEntry chl;
4963 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4964 channel->channel_name));
4966 for (i = 0; i < user_count; i++) {
4968 SILC_GET16_MSB(idp_len, user_list->data + 2);
4970 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4972 silc_buffer_pull(user_list, idp_len);
4975 SILC_GET32_MSB(mode, mode_list->data);
4976 silc_buffer_pull(mode_list, 4);
4978 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4983 /* Check if we have this client cached already. */
4984 client = silc_idlist_find_client_by_id(server->local_list,
4986 server->server_type, &cache);
4988 client = silc_idlist_find_client_by_id(server->global_list,
4990 server->server_type, &cache);
4992 /* If router did not find such Client ID in its lists then this must
4993 be bogus client or some router in the net is buggy. */
4994 if (server->server_type != SILC_SERVER)
4997 /* We don't have that client anywhere, add it. The client is added
4998 to global list since server didn't have it in the lists so it must be
5000 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5001 silc_id_dup(&id.u.client_id,
5003 silc_packet_get_context(sock),
5006 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5010 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5013 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5014 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
5015 "%s", channel->channel_name));
5019 if (!silc_server_client_on_channel(client, channel, &chl)) {
5020 /* Client was not on the channel, add it. */
5021 chl = silc_calloc(1, sizeof(*chl));
5022 chl->client = client;
5024 chl->channel = channel;
5025 silc_hash_table_add(channel->user_list, chl->client, chl);
5026 silc_hash_table_add(client->channels, chl->channel, chl);
5027 channel->user_count++;
5035 /* Saves channels and channels user modes to the `client'. Removes
5036 the client from those channels that are not sent in the list but
5039 void silc_server_save_user_channels(SilcServer server,
5040 SilcPacketStream sock,
5041 SilcClientEntry client,
5042 SilcBuffer channels,
5043 SilcBuffer channels_user_modes)
5046 SilcUInt32 *chumodes;
5047 SilcChannelPayload entry;
5048 SilcChannelEntry channel;
5049 SilcChannelID channel_id;
5050 SilcChannelClientEntry chl;
5051 SilcHashTable ht = NULL;
5052 SilcHashTableList htl;
5056 if (!channels || !channels_user_modes ||
5057 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5060 ch = silc_channel_payload_parse_list(channels->data,
5061 silc_buffer_len(channels));
5062 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5064 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5065 NULL, NULL, NULL, TRUE);
5066 silc_dlist_start(ch);
5067 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5068 /* Check if we have this channel, and add it if we don't have it.
5069 Also add the client on the channel unless it is there already. */
5070 if (!silc_channel_get_id_parse(entry, &channel_id))
5072 channel = silc_idlist_find_channel_by_id(server->local_list,
5075 channel = silc_idlist_find_channel_by_id(server->global_list,
5078 if (server->server_type != SILC_SERVER) {
5083 /* We don't have that channel anywhere, add it. */
5084 name = silc_channel_get_name(entry, NULL);
5085 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5086 silc_id_dup(&channel_id,
5088 server->router, NULL, NULL, 0);
5095 channel->mode = silc_channel_get_mode(entry);
5097 /* Add the client on the channel */
5098 if (!silc_server_client_on_channel(client, channel, &chl)) {
5099 chl = silc_calloc(1, sizeof(*chl));
5100 chl->client = client;
5101 chl->mode = chumodes[i++];
5102 chl->channel = channel;
5103 silc_hash_table_add(channel->user_list, chl->client, chl);
5104 silc_hash_table_add(client->channels, chl->channel, chl);
5105 channel->user_count++;
5108 chl->mode = chumodes[i++];
5111 silc_hash_table_add(ht, channel, channel);
5113 silc_channel_payload_list_free(ch);
5114 silc_free(chumodes);
5118 /* Go through the list again and remove client from channels that
5119 are no part of the list. */
5121 silc_hash_table_list(client->channels, &htl);
5122 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5123 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5124 silc_hash_table_del(chl->channel->user_list, chl->client);
5125 silc_hash_table_del(chl->client->channels, chl->channel);
5129 silc_hash_table_list_reset(&htl);
5130 silc_hash_table_free(ht);
5132 silc_hash_table_list(client->channels, &htl);
5133 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5134 silc_hash_table_del(chl->channel->user_list, chl->client);
5135 silc_hash_table_del(chl->client->channels, chl->channel);
5138 silc_hash_table_list_reset(&htl);
5142 /* Lookups route to the client indicated by the `id_data'. The connection
5143 object and internal data object is returned. Returns NULL if route
5144 could not be found to the client. If the `client_id' is specified then
5145 it is used and the `id_data' is ignored. */
5148 silc_server_get_client_route(SilcServer server,
5149 unsigned char *id_data,
5151 SilcClientID *client_id,
5152 SilcIDListData *idata,
5153 SilcClientEntry *client_entry)
5155 SilcClientID *id, clid;
5156 SilcClientEntry client;
5158 SILC_LOG_DEBUG(("Start"));
5161 *client_entry = NULL;
5163 /* Decode destination Client ID */
5165 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5167 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5169 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5172 /* If the destination belongs to our server we don't have to route
5173 the packet anywhere but to send it to the local destination. */
5174 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5178 /* If we are router and the client has router then the client is in
5179 our cell but not directly connected to us. */
5180 if (server->server_type == SILC_ROUTER && client->router) {
5181 /* We are of course in this case the client's router thus the route
5182 to the client is the server who owns the client. So, we will send
5183 the packet to that server. */
5185 *idata = (SilcIDListData)client->router;
5186 return client->router->connection;
5189 /* Seems that client really is directly connected to us */
5191 *idata = (SilcIDListData)client;
5193 *client_entry = client;
5194 return client->connection;
5197 /* Destination belongs to someone not in this server. If we are normal
5198 server our action is to send the packet to our router. */
5199 if (server->server_type != SILC_ROUTER && !server->standalone) {
5202 *idata = (SilcIDListData)server->router;
5203 return SILC_PRIMARY_ROUTE(server);
5206 /* We are router and we will perform route lookup for the destination
5207 and send the packet to fastest route. */
5208 if (server->server_type == SILC_ROUTER && !server->standalone) {
5209 /* Check first that the ID is valid */
5210 client = silc_idlist_find_client_by_id(server->global_list, id,
5213 SilcPacketStream dst_sock;
5215 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5218 if (idata && dst_sock)
5219 *idata = silc_packet_get_context(dst_sock);
5228 /* Encodes and returns channel list of channels the `client' has joined.
5229 Secret channels are not put to the list. */
5231 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5232 SilcClientEntry client,
5233 SilcBool get_private,
5234 SilcBool get_secret,
5235 SilcBuffer *user_mode_list)
5237 SilcBuffer buffer = NULL;
5238 SilcChannelEntry channel;
5239 SilcChannelClientEntry chl;
5240 SilcHashTableList htl;
5241 unsigned char cid[32];
5243 SilcUInt16 name_len;
5247 *user_mode_list = NULL;
5249 silc_hash_table_list(client->channels, &htl);
5250 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5251 channel = chl->channel;
5253 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5255 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5258 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5259 name_len = strlen(channel->channel_name);
5261 len = 4 + name_len + id_len + 4;
5262 buffer = silc_buffer_realloc(buffer,
5264 silc_buffer_truelen(buffer) + len : len));
5265 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5266 silc_buffer_format(buffer,
5267 SILC_STR_UI_SHORT(name_len),
5268 SILC_STR_DATA(channel->channel_name, name_len),
5269 SILC_STR_UI_SHORT(id_len),
5270 SILC_STR_DATA(cid, id_len),
5271 SILC_STR_UI_INT(chl->channel->mode),
5273 silc_buffer_pull(buffer, len);
5275 if (user_mode_list) {
5277 silc_buffer_realloc(*user_mode_list,
5279 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5280 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5281 (*user_mode_list)->data));
5282 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5283 silc_buffer_pull(*user_mode_list, 4);
5286 silc_hash_table_list_reset(&htl);
5289 silc_buffer_push(buffer, buffer->data - buffer->head);
5290 if (user_mode_list && *user_mode_list)
5291 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5292 (*user_mode_list)->head));
5297 /* Task callback used to retrieve network statistical information from
5298 router server once in a while. */
5300 SILC_TASK_CALLBACK(silc_server_get_stats)
5302 SilcServer server = (SilcServer)context;
5303 SilcBuffer idp, packet;
5305 if (!server->standalone) {
5306 SILC_LOG_DEBUG(("Retrieving stats from router"));
5307 server->stat.commands_sent++;
5308 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5310 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5311 ++server->cmd_ident, 1,
5313 silc_buffer_len(idp));
5314 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5315 SILC_PACKET_COMMAND, 0, packet->data,
5316 silc_buffer_len(packet));
5317 silc_buffer_free(packet);
5318 silc_buffer_free(idp);
5322 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,