5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2007 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_do_rekey);
28 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
29 static void silc_server_accept_new_connection(SilcNetStatus status,
32 static void silc_server_packet_parse_type(SilcServer server,
33 SilcPacketStream sock,
35 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
39 /************************ Static utility functions **************************/
41 /* SKE public key verification callback */
44 silc_server_verify_key(SilcSKE ske,
45 SilcPublicKey public_key,
47 SilcSKEVerifyCbCompletion completion,
48 void *completion_context)
50 SilcPacketStream sock = context;
51 SilcUnknownEntry entry = silc_packet_get_context(sock);
53 SILC_LOG_DEBUG(("Verifying public key"));
55 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
56 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
57 entry->hostname, entry->ip, entry->port,
58 silc_pkcs_get_type(public_key)));
59 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
64 /* We accept all keys without explicit verification */
65 completion(ske, SILC_SKE_STATUS_OK, completion_context);
69 /************************ Packet engine callbacks ***************************/
71 /* Packet engine callback to receive a packet */
73 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
74 SilcPacketStream stream,
76 void *callback_context,
79 SilcServer server = callback_context;
80 SilcIDListData idata = stream_context;
85 /* Packets we do not handle */
86 switch (packet->type) {
87 case SILC_PACKET_HEARTBEAT:
88 case SILC_PACKET_SUCCESS:
89 case SILC_PACKET_FAILURE:
90 case SILC_PACKET_REJECT:
91 case SILC_PACKET_KEY_EXCHANGE:
92 case SILC_PACKET_KEY_EXCHANGE_1:
93 case SILC_PACKET_KEY_EXCHANGE_2:
94 case SILC_PACKET_REKEY_DONE:
95 case SILC_PACKET_CONNECTION_AUTH:
100 /* Only specific packets can come without source ID present. */
101 if ((!packet->src_id ||
102 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
103 packet->type != SILC_PACKET_NEW_CLIENT &&
104 packet->type != SILC_PACKET_NEW_SERVER &&
105 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
106 packet->type != SILC_PACKET_DISCONNECT)
109 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID
110 and for unregistered connection. */
111 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
112 packet->type == SILC_PACKET_NEW_SERVER) &&
113 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
116 /* Ignore packets from disabled connection */
117 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
118 packet->type != SILC_PACKET_HEARTBEAT &&
119 packet->type != SILC_PACKET_RESUME_ROUTER &&
120 packet->type != SILC_PACKET_REKEY)
123 /* Check that the the current client ID is same as in the client's packet. */
124 if (idata->conn_type == SILC_CONN_CLIENT) {
125 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
126 SilcClientID client_id;
128 if (client->id && packet->src_id &&
129 silc_id_str2id(packet->src_id, packet->src_id_len,
130 packet->src_id_type, &client_id, sizeof(client_id))) {
131 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
132 SILC_LOG_DEBUG(("Packet source is not same as sender"));
138 if (server->server_type == SILC_ROUTER) {
139 /* Route the packet if it is not destined to us. Other ID types but
140 server are handled separately after processing them. */
141 if (packet->dst_id &&
142 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
143 packet->dst_id_type == SILC_ID_SERVER &&
144 idata->conn_type != SILC_CONN_CLIENT &&
145 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
146 SilcPacketStream conn;
147 SilcServerID server_id;
149 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
150 &server_id, sizeof(server_id));
152 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
154 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
155 silc_id_render(&server_id, SILC_ID_SERVER)));
159 silc_server_packet_route(server, conn, packet);
160 silc_packet_free(packet);
165 /* Broadcast packet if it is marked as broadcast packet and it is
166 originated from router and we are router. */
167 if (server->server_type == SILC_ROUTER &&
168 idata->conn_type == SILC_CONN_ROUTER &&
169 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
170 /* Broadcast to our primary route */
171 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
173 /* If we have backup routers then we need to feed all broadcast
174 data to those servers. */
175 silc_server_backup_broadcast(server, stream, packet);
179 silc_server_packet_parse_type(server, stream, packet);
184 /* Packet engine callback to indicate end of stream */
186 static void silc_server_packet_eos(SilcPacketEngine engine,
187 SilcPacketStream stream,
188 void *callback_context,
189 void *stream_context)
191 SilcServer server = callback_context;
192 SilcIDListData idata = silc_packet_get_context(stream);
194 SILC_LOG_DEBUG(("End of stream received"));
199 if (server->router_conn && server->router_conn->sock == stream &&
200 !server->router && server->standalone) {
201 silc_server_create_connections(server);
203 /* If backup disconnected then mark that resuming will not be allowed */
204 if (server->server_type == SILC_ROUTER && !server->backup_router &&
205 idata->conn_type == SILC_CONN_SERVER) {
206 SilcServerEntry server_entry = (SilcServerEntry)idata;
207 if (server_entry->server_type == SILC_BACKUP_ROUTER)
208 server->backup_closed = TRUE;
211 silc_server_free_sock_user_data(server, stream, NULL);
214 silc_server_close_connection(server, stream);
217 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
219 SilcServer server = app_context;
220 SilcPacketStream stream = context;
221 SilcIDListData idata = silc_packet_get_context(stream);
226 if (server->router_conn && server->router_conn->sock == stream &&
227 !server->router && server->standalone) {
228 silc_server_create_connections(server);
230 /* If backup disconnected then mark that resuming will not be allowed */
231 if (server->server_type == SILC_ROUTER && !server->backup_router &&
232 idata->conn_type == SILC_CONN_SERVER) {
233 SilcServerEntry server_entry = (SilcServerEntry)idata;
234 if (server_entry->server_type == SILC_BACKUP_ROUTER)
235 server->backup_closed = TRUE;
238 silc_server_free_sock_user_data(server, stream, NULL);
241 silc_server_close_connection(server, stream);
244 /* Packet engine callback to indicate error */
246 static void silc_server_packet_error(SilcPacketEngine engine,
247 SilcPacketStream stream,
248 SilcPacketError error,
249 void *callback_context,
250 void *stream_context)
252 SilcServer server = callback_context;
253 SilcIDListData idata = silc_packet_get_context(stream);
254 SilcStream sock = silc_packet_stream_get_stream(stream);
261 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
264 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
265 SILC_CONNTYPE_STRING(idata->conn_type),
266 silc_packet_error_string(error)));
268 silc_schedule_task_add_timeout(server->schedule,
269 silc_server_packet_error_timeout,
273 /* Packet stream callbacks */
274 static SilcPacketCallbacks silc_server_stream_cbs =
276 silc_server_packet_receive,
277 silc_server_packet_eos,
278 silc_server_packet_error
281 /* Parses the packet type and calls what ever routines the packet type
282 requires. This is done for all incoming packets. */
284 static void silc_server_packet_parse_type(SilcServer server,
285 SilcPacketStream sock,
288 SilcPacketType type = packet->type;
289 SilcIDListData idata = silc_packet_get_context(sock);
291 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
292 silc_get_packet_name(type), packet->flags));
294 /* Parse the packet type */
296 case SILC_PACKET_NOTIFY:
298 * Received notify packet. Server can receive notify packets from
299 * router. Server then relays the notify messages to clients if needed.
301 if (packet->flags & SILC_PACKET_FLAG_LIST)
302 silc_server_notify_list(server, sock, packet);
304 silc_server_notify(server, sock, packet);
308 * Private Message packets
310 case SILC_PACKET_PRIVATE_MESSAGE:
312 * Received private message packet. The packet is coming from either
315 if (packet->flags & SILC_PACKET_FLAG_LIST)
317 idata->last_receive = time(NULL);
318 silc_server_private_message(server, sock, packet);
324 case SILC_PACKET_CHANNEL_MESSAGE:
326 * Received channel message. Channel messages are special packets
327 * (although probably most common ones) thus they are handled
330 if (packet->flags & SILC_PACKET_FLAG_LIST)
332 idata->last_receive = time(NULL);
333 silc_server_channel_message(server, sock, packet);
339 case SILC_PACKET_COMMAND:
341 * Recived command. Processes the command request and allocates the
342 * command context and calls the command.
344 if (packet->flags & SILC_PACKET_FLAG_LIST)
346 server->stat.commands_received++;
347 silc_server_command_process(server, sock, packet);
350 case SILC_PACKET_COMMAND_REPLY:
352 * Received command reply packet. Received command reply to command. It
353 * may be reply to command sent by us or reply to command sent by client
354 * that we've routed further.
356 if (packet->flags & SILC_PACKET_FLAG_LIST)
358 server->stat.commands_received++;
359 silc_server_command_reply(server, sock, packet);
362 case SILC_PACKET_DISCONNECT:
365 char *message = NULL;
366 const char *hostname, *ip;
368 if (packet->flags & SILC_PACKET_FLAG_LIST)
370 if (silc_buffer_len(&packet->buffer) < 1)
373 status = (SilcStatus)packet->buffer.data[0];
374 if (silc_buffer_len(&packet->buffer) > 1 &&
375 silc_utf8_valid(packet->buffer.data + 1,
376 silc_buffer_len(&packet->buffer) - 1))
377 message = silc_memdup(packet->buffer.data + 1,
378 silc_buffer_len(&packet->buffer) - 1);
380 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
381 NULL, &hostname, &ip, NULL))
384 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
385 silc_get_status_message(status), status,
386 message ? message : ""));
390 /* Do not switch to backup in case of error */
391 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
393 /* If backup disconnected then mark that resuming will not be allowed */
395 if (server->server_type == SILC_ROUTER && !server->backup_router &&
396 sock->type == SILC_CONN_SERVER && sock->user_data) {
397 SilcServerEntry server_entry = sock->user_data;
398 if (server_entry->server_type == SILC_BACKUP_ROUTER)
399 server->backup_closed = TRUE;
402 /* Handle the disconnection from our end too */
403 if (sock->user_data && SILC_IS_LOCAL(sock->user_data))
404 silc_server_free_sock_user_data(server, sock, NULL);
405 SILC_SET_DISCONNECTING(sock);
406 silc_server_close_connection(server, sock);
407 server->backup_noswitch = FALSE;
412 case SILC_PACKET_CHANNEL_KEY:
414 * Received key for channel. As channels are created by the router
415 * the keys are as well. We will distribute the key to all of our
416 * locally connected clients on the particular channel. Router
417 * never receives this channel and thus is ignored.
419 if (packet->flags & SILC_PACKET_FLAG_LIST)
421 silc_server_channel_key(server, sock, packet);
424 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
426 * Private message key packet.
428 if (packet->flags & SILC_PACKET_FLAG_LIST)
430 silc_server_private_message_key(server, sock, packet);
433 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
435 * Connection authentication request packet. When we receive this packet
436 * we will send to the other end information about our mandatory
437 * authentication method for the connection. This packet maybe received
440 if (packet->flags & SILC_PACKET_FLAG_LIST)
442 silc_server_connection_auth_request(server, sock, packet);
445 case SILC_PACKET_NEW_ID:
447 * Received New ID packet. This includes some new ID that has been
448 * created. It may be for client, server or channel. This is the way
449 * to distribute information about new registered entities in the
452 if (packet->flags & SILC_PACKET_FLAG_LIST)
453 silc_server_new_id_list(server, sock, packet);
455 silc_server_new_id(server, sock, packet);
458 case SILC_PACKET_NEW_CLIENT:
460 * Received new client packet. This includes client information that
461 * we will use to create initial client ID. After creating new
462 * ID we will send it to the client.
464 if (packet->flags & SILC_PACKET_FLAG_LIST)
466 silc_server_new_client(server, sock, packet);
469 case SILC_PACKET_NEW_SERVER:
471 * Received new server packet. This includes Server ID and some other
472 * information that we may save. This is received after server has
475 if (packet->flags & SILC_PACKET_FLAG_LIST)
477 silc_server_new_server(server, sock, packet);
480 case SILC_PACKET_NEW_CHANNEL:
482 * Received new channel packet. Information about new channel in the
483 * network are distributed using this packet.
485 if (packet->flags & SILC_PACKET_FLAG_LIST)
486 silc_server_new_channel_list(server, sock, packet);
488 silc_server_new_channel(server, sock, packet);
491 case SILC_PACKET_HEARTBEAT:
493 * Received heartbeat.
495 if (packet->flags & SILC_PACKET_FLAG_LIST)
499 case SILC_PACKET_KEY_AGREEMENT:
501 * Received heartbeat.
503 if (packet->flags & SILC_PACKET_FLAG_LIST)
505 silc_server_key_agreement(server, sock, packet);
508 case SILC_PACKET_REKEY:
510 * Received re-key packet. The sender wants to regenerate the session
513 if (packet->flags & SILC_PACKET_FLAG_LIST)
515 silc_server_rekey(server, sock, packet);
518 case SILC_PACKET_FTP:
520 if (packet->flags & SILC_PACKET_FLAG_LIST)
522 silc_server_ftp(server, sock, packet);
525 case SILC_PACKET_RESUME_CLIENT:
527 if (packet->flags & SILC_PACKET_FLAG_LIST)
529 silc_server_resume_client(server, sock, packet);
532 case SILC_PACKET_RESUME_ROUTER:
533 /* Resume router packet received. This packet is received for backup
534 router resuming protocol. */
535 if (packet->flags & SILC_PACKET_FLAG_LIST)
538 silc_server_backup_resume_router(server, sock, packet);
543 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
548 /****************************** Server API **********************************/
550 /* Allocates a new SILC server object. This has to be done before the server
551 can be used. After allocation one must call silc_server_init to initialize
552 the server. The new allocated server object is returned to the new_server
555 SilcBool silc_server_alloc(SilcServer *new_server)
559 SILC_LOG_DEBUG(("Allocating new server object"));
561 server = silc_calloc(1, sizeof(*server));
564 server->server_type = SILC_SERVER;
565 server->standalone = TRUE;
566 server->local_list = silc_calloc(1, sizeof(*server->local_list));
567 if (!server->local_list)
569 server->global_list = silc_calloc(1, sizeof(*server->global_list));
570 if (!server->global_list)
572 server->pending_commands = silc_dlist_init();
573 if (!server->pending_commands)
575 server->listeners = silc_dlist_init();
576 if (!server->listeners)
578 server->repository = silc_skr_alloc();
579 if (!server->repository)
581 server->conns = silc_dlist_init();
584 server->expired_clients = silc_dlist_init();
585 if (!server->expired_clients)
588 *new_server = server;
593 /* Free's the SILC server object. This is called at the very end before
596 void silc_server_free(SilcServer server)
599 SilcIDCacheEntry cache;
600 SilcIDListData idata;
602 SILC_LOG_DEBUG(("Free server %p", server));
607 silc_server_backup_free(server);
608 silc_server_config_unref(&server->config_ref);
610 silc_rng_free(server->rng);
611 if (server->public_key)
612 silc_pkcs_public_key_free(server->public_key);
613 if (server->private_key)
614 silc_pkcs_private_key_free(server->private_key);
615 if (server->pending_commands)
616 silc_dlist_uninit(server->pending_commands);
617 if (server->id_entry) {
618 if (server->id_entry->data.sconn)
619 silc_schedule_task_del_by_context(server->schedule,
620 server->id_entry->data.sconn->sock);
621 silc_idlist_del_server(server->local_list, server->id_entry);
624 /* Delete all channels */
625 if (silc_idcache_get_all(server->local_list->channels, &list)) {
626 silc_list_start(list);
627 while ((cache = silc_list_get(list)))
628 silc_idlist_del_channel(server->local_list, cache->context);
630 if (silc_idcache_get_all(server->global_list->channels, &list)) {
631 silc_list_start(list);
632 while ((cache = silc_list_get(list)))
633 silc_idlist_del_channel(server->global_list, cache->context);
636 /* Delete all clients */
637 if (silc_idcache_get_all(server->local_list->clients, &list)) {
638 silc_list_start(list);
639 while ((cache = silc_list_get(list))) {
640 silc_schedule_task_del_by_context(server->schedule, cache->context);
641 silc_idlist_del_client(server->local_list, cache->context);
644 if (silc_idcache_get_all(server->global_list->clients, &list)) {
645 silc_list_start(list);
646 while ((cache = silc_list_get(list))) {
647 silc_schedule_task_del_by_context(server->schedule, cache->context);
648 silc_idlist_del_client(server->global_list, cache->context);
652 /* Delete all servers */
653 if (silc_idcache_get_all(server->local_list->servers, &list)) {
654 silc_list_start(list);
655 while ((cache = silc_list_get(list))) {
656 idata = (SilcIDListData)cache->context;
658 silc_schedule_task_del_by_context(server->schedule,
660 silc_idlist_del_server(server->local_list, cache->context);
663 if (silc_idcache_get_all(server->global_list->servers, &list)) {
664 while ((cache = silc_list_get(list))) {
665 idata = (SilcIDListData)cache->context;
667 silc_schedule_task_del_by_context(server->schedule,
669 silc_idlist_del_server(server->global_list, cache->context);
673 silc_idcache_free(server->local_list->clients);
674 silc_idcache_free(server->local_list->servers);
675 silc_idcache_free(server->local_list->channels);
676 silc_idcache_free(server->global_list->clients);
677 silc_idcache_free(server->global_list->servers);
678 silc_idcache_free(server->global_list->channels);
679 silc_hash_table_free(server->watcher_list);
680 silc_hash_table_free(server->watcher_list_pk);
681 silc_hash_free(server->md5hash);
682 silc_hash_free(server->sha1hash);
684 silc_dlist_uninit(server->listeners);
685 silc_dlist_uninit(server->conns);
686 silc_dlist_uninit(server->expired_clients);
687 silc_skr_free(server->repository);
688 silc_packet_engine_stop(server->packet_engine);
690 silc_schedule_task_del_by_context(server->schedule, server);
691 silc_schedule_uninit(server->schedule);
692 server->schedule = NULL;
694 silc_free(server->local_list);
695 silc_free(server->global_list);
696 silc_free(server->server_name);
699 silc_hmac_unregister_all();
700 silc_hash_unregister_all();
701 silc_cipher_unregister_all();
702 silc_pkcs_unregister_all();
705 /* Creates a new server listener. */
707 static SilcNetListener
708 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
710 SilcNetListener listener;
713 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
714 server->config->require_reverse_lookup,
716 silc_server_accept_new_connection, server);
718 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
726 /* Adds a secondary listener. */
728 SilcBool silc_server_init_secondary(SilcServer server)
733 SilcPacketStream newsocket = NULL;
734 SilcServerConfigServerInfoInterface *interface;
736 for (interface = server->config->server_info->secondary; interface;
737 interface = interface->next, sock++) {
739 if (!silc_server_listen(server,
740 interface->server_ip, interface->port, &sock_list[sock]))
743 /* Set socket to non-blocking mode */
744 silc_net_set_socket_nonblock(sock_list[sock]);
746 /* Add ourselves also to the socket table. The entry allocated above
747 is sent as argument for fast referencing in the future. */
748 silc_socket_alloc(sock_list[sock],
749 SILC_CONN_SERVER, NULL, &newsocket);
750 server->sockets[sock_list[sock]] = newsocket;
751 SILC_SET_LISTENER(newsocket);
753 /* Perform name and address lookups to resolve the listenning address
755 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
757 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
759 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
760 newsocket->hostname ? newsocket->hostname :
761 newsocket->ip ? newsocket->ip : ""));
762 server->stat.conn_failures++;
765 if (!newsocket->hostname)
766 newsocket->hostname = strdup(newsocket->ip);
768 newsocket->port = silc_net_get_local_port(sock);
770 newsocket->user_data = (void *)server->id_entry;
771 silc_schedule_task_add(server->schedule, sock_list[sock],
772 silc_server_accept_new_connection,
773 (void *)server, 0, 0,
775 SILC_TASK_PRI_NORMAL);
781 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
786 /* Initializes the entire SILC server. This is called always before running
787 the server. This is called only once at the initialization of the program.
788 This binds the server to its listenning port. After this function returns
789 one should call silc_server_run to start the server. This returns TRUE
790 when everything is ok to run the server. Configuration file must be
791 read and parsed before calling this. */
793 SilcBool silc_server_init(SilcServer server)
796 SilcServerEntry id_entry;
797 SilcNetListener listener;
801 SILC_LOG_DEBUG(("Initializing server"));
803 server->starttime = time(NULL);
805 /* Take config object for us */
806 silc_server_config_ref(&server->config_ref, server->config,
810 /* Set debugging on if configured */
811 if (server->config->debug_string) {
812 silc_log_debug(TRUE);
813 silc_log_set_debug_string(server->config->debug_string);
815 #endif /* SILC_DEBUG */
817 /* Steal public and private key from the config object */
818 server->public_key = server->config->server_info->public_key;
819 server->private_key = server->config->server_info->private_key;
820 server->config->server_info->public_key = NULL;
821 server->config->server_info->private_key = NULL;
823 /* Register all configured ciphers, PKCS and hash functions. */
824 if (!silc_server_config_register_ciphers(server))
825 silc_cipher_register_default();
826 if (!silc_server_config_register_pkcs(server))
827 silc_pkcs_register_default();
828 if (!silc_server_config_register_hashfuncs(server))
829 silc_hash_register_default();
830 if (!silc_server_config_register_hmacs(server))
831 silc_hmac_register_default();
833 /* Initialize random number generator for the server. */
834 server->rng = silc_rng_alloc();
835 silc_rng_init(server->rng);
836 silc_rng_global_init(server->rng);
838 /* Initialize hash functions for server to use */
839 silc_hash_alloc("md5", &server->md5hash);
840 silc_hash_alloc("sha1", &server->sha1hash);
842 /* Initialize the scheduler */
843 server->schedule = silc_schedule_init(server->config->param.connections_max,
845 if (!server->schedule)
848 /* First, register log files configuration for error output */
849 silc_server_config_setlogfiles(server);
851 /* Initialize ID caches */
852 server->local_list->clients =
853 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
855 server->local_list->servers =
856 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
858 server->local_list->channels =
859 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
862 /* These are allocated for normal server as well as these hold some
863 global information that the server has fetched from its router. For
864 router these are used as they are supposed to be used on router. */
865 server->global_list->clients =
866 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
868 server->global_list->servers =
869 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
871 server->global_list->channels =
872 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
875 /* Init watcher lists */
876 server->watcher_list =
877 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
878 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
880 if (!server->watcher_list)
882 server->watcher_list_pk =
883 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
884 silc_hash_public_key_compare, NULL,
886 if (!server->watcher_list_pk)
889 /* Create TCP listener */
890 listener = silc_server_listen(
892 server->config->server_info->primary == NULL ? NULL :
893 server->config->server_info->primary->server_ip,
894 server->config->server_info->primary == NULL ? 0 :
895 server->config->server_info->primary->port);
899 silc_dlist_add(server->listeners, listener);
901 /* Create a Server ID for the server. */
902 port = silc_net_listener_get_port(listener, NULL);
903 ip = silc_net_listener_get_ip(listener, NULL);
904 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
905 server->config->server_info->primary->public_ip :
906 ip[0], port[0], server->rng, &id);
915 server->server_name = server->config->server_info->server_name;
916 server->config->server_info->server_name = NULL;
917 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
918 sizeof(server->id_string), &server->id_string_len);
920 /* Add ourselves to the server list. We don't have a router yet
921 beacuse we haven't established a route yet. It will be done later.
922 For now, NULL is sent as router. This allocates new entry to
925 silc_idlist_add_server(server->local_list, strdup(server->server_name),
926 server->server_type, server->id, NULL, NULL);
928 SILC_LOG_ERROR(("Could not add local server to cache"));
931 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
932 server->id_entry = id_entry;
934 /* Create secondary TCP listeners */
935 if (silc_server_init_secondary(server) == FALSE)
938 server->listenning = TRUE;
940 /* Create connections to configured routers. */
941 silc_server_create_connections(server);
943 /* If server connections has been configured then we must be router as
944 normal server cannot have server connections, only router connections. */
945 if (server->config->servers) {
946 SilcServerConfigServer *ptr = server->config->servers;
948 server->server_type = SILC_ROUTER;
950 if (ptr->backup_router) {
951 server->server_type = SILC_BACKUP_ROUTER;
952 server->backup_router = TRUE;
953 server->id_entry->server_type = SILC_BACKUP_ROUTER;
961 /* Register the ID Cache purge task. This periodically purges the ID cache
962 and removes the expired cache entries. */
964 /* Clients local list */
965 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
966 purge->cache = server->local_list->clients;
967 purge->timeout = 600;
968 silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
969 (void *)purge, purge->timeout, 0);
971 /* Clients global list */
972 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
973 purge->cache = server->global_list->clients;
974 purge->timeout = 300;
975 silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
976 (void *)purge, purge->timeout, 0);
979 /* If we are normal server we'll retrieve network statisticial information
980 once in a while from the router. */
981 if (server->server_type != SILC_ROUTER)
982 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
985 if (server->server_type == SILC_ROUTER)
986 server->stat.routers++;
988 /* Start packet engine */
989 server->packet_engine =
990 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
991 &silc_server_stream_cbs, server);
992 if (!server->packet_engine)
995 /* Register client entry expiration timeout */
996 silc_schedule_task_add_timeout(server->schedule,
997 silc_server_purge_expired_clients, server,
1000 /* Initialize HTTP server */
1001 silc_server_http_init(server);
1003 SILC_LOG_DEBUG(("Server initialized"));
1005 /* We are done here, return succesfully */
1009 silc_server_config_unref(&server->config_ref);
1014 /* Task callback to close a socket connection after rehash */
1016 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
1018 SilcServer server = context;
1019 SilcPacketStream sock = server->sockets[fd];
1024 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
1025 sock->hostname, sock->port,
1026 (sock->type == SILC_CONN_UNKNOWN ? "Unknown" :
1027 sock->type == SILC_CONN_CLIENT ? "Client" :
1028 sock->type == SILC_CONN_SERVER ? "Server" :
1030 silc_schedule_task_del_by_context(server->schedule, sock);
1031 silc_server_disconnect_remote(server, sock,
1032 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1033 "This connection is removed from "
1035 if (sock->user_data)
1036 silc_server_free_sock_user_data(server, sock, NULL);
1040 /* This function basically reads the config file again and switches the config
1041 object pointed by the server object. After that, we have to fix various
1042 things such as the server_name and the listening ports.
1043 Keep in mind that we no longer have the root privileges at this point. */
1045 SilcBool silc_server_rehash(SilcServer server)
1048 SilcServerConfig newconfig;
1050 SILC_LOG_INFO(("Rehashing server"));
1052 /* Reset the logging system */
1053 silc_log_quick(TRUE);
1054 silc_log_flush_all();
1056 /* Start the main rehash phase (read again the config file) */
1057 newconfig = silc_server_config_alloc(server->config_file, server);
1059 SILC_LOG_ERROR(("Rehash FAILED."));
1063 /* Reinit scheduler if necessary */
1064 if (newconfig->param.connections_max > server->config->param.connections_max)
1065 if (!silc_schedule_reinit(server->schedule,
1066 newconfig->param.connections_max))
1069 /* Fix the server_name field */
1070 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1071 silc_free(server->server_name);
1073 /* Check server name */
1074 server->server_name =
1075 silc_identifier_check(newconfig->server_info->server_name,
1076 strlen(newconfig->server_info->server_name),
1077 SILC_STRING_LOCALE, 256, NULL);
1078 if (!server->server_name) {
1079 SILC_LOG_ERROR(("Malformed server name string '%s'",
1080 server->config->server_info->server_name));
1084 /* Update the idcache list with a fresh pointer */
1085 silc_free(server->id_entry->server_name);
1086 server->id_entry->server_name = strdup(server->server_name);
1087 if (!silc_idcache_del_by_context(server->local_list->servers,
1090 if (!silc_idcache_add(server->local_list->servers,
1091 strdup(server->id_entry->server_name),
1092 server->id_entry->id, server->id_entry, 0, NULL))
1097 silc_server_config_setlogfiles(server);
1099 /* Change new key pair if necessary */
1100 if (newconfig->server_info->public_key &&
1101 !silc_pkcs_public_key_compare(server->public_key,
1102 newconfig->server_info->public_key)) {
1103 silc_pkcs_public_key_free(server->public_key);
1104 silc_pkcs_private_key_free(server->private_key);
1105 server->public_key = newconfig->server_info->public_key;
1106 server->private_key = newconfig->server_info->private_key;
1107 newconfig->server_info->public_key = NULL;
1108 newconfig->server_info->private_key = NULL;
1110 /* Allocate PKCS context for local public and private keys */
1111 silc_pkcs_free(server->pkcs);
1112 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
1114 silc_pkcs_public_key_set(server->pkcs, server->public_key);
1115 silc_pkcs_private_key_set(server->pkcs, server->private_key);
1118 /* Check for unconfigured server and router connections and close
1119 connections that were unconfigured. */
1121 if (server->config->routers) {
1122 SilcServerConfigRouter *ptr;
1123 SilcServerConfigRouter *newptr;
1126 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1129 /* Check whether new config has this one too */
1130 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1131 if (silc_string_compare(newptr->host, ptr->host) &&
1132 newptr->port == ptr->port &&
1133 newptr->initiator == ptr->initiator) {
1139 if (!found && ptr->host) {
1140 /* Remove this connection */
1141 SilcPacketStream sock;
1142 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1143 ptr->host, ptr->port);
1144 if (sock && !SILC_IS_LISTENER(sock))
1145 silc_schedule_task_add(server->schedule, sock->sock,
1146 silc_server_rehash_close_connection,
1147 server, 0, 1, SILC_TASK_TIMEOUT,
1148 SILC_TASK_PRI_NORMAL);
1153 if (server->config->servers) {
1154 SilcServerConfigServer *ptr;
1155 SilcServerConfigServer *newptr;
1158 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1161 /* Check whether new config has this one too */
1162 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1163 if (silc_string_compare(newptr->host, ptr->host)) {
1169 if (!found && ptr->host) {
1170 /* Remove this connection */
1171 SilcPacketStream sock;
1172 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1174 if (sock && !SILC_IS_LISTENER(sock))
1175 silc_schedule_task_add(server->schedule, sock->sock,
1176 silc_server_rehash_close_connection,
1177 server, 0, 1, SILC_TASK_TIMEOUT,
1178 SILC_TASK_PRI_NORMAL);
1183 if (server->config->clients) {
1184 SilcServerConfigClient *ptr;
1185 SilcServerConfigClient *newptr;
1188 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1191 /* Check whether new config has this one too */
1192 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1193 if (silc_string_compare(newptr->host, ptr->host)) {
1199 if (!found && ptr->host) {
1200 /* Remove this connection */
1201 SilcPacketStream sock;
1202 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1205 silc_schedule_task_add(server->schedule, sock->sock,
1206 silc_server_rehash_close_connection,
1207 server, 0, 1, SILC_TASK_TIMEOUT,
1208 SILC_TASK_PRI_NORMAL);
1213 /* Create connections after rehash */
1214 silc_server_create_connections(server);
1216 /* Check whether our router status has changed */
1217 if (newconfig->servers) {
1218 SilcServerConfigServer *ptr = newconfig->servers;
1220 server->server_type = SILC_ROUTER;
1222 if (ptr->backup_router) {
1223 server->server_type = SILC_BACKUP_ROUTER;
1224 server->backup_router = TRUE;
1225 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1232 /* Our old config is gone now. We'll unreference our reference made in
1233 silc_server_init and then destroy it since we are destroying it
1234 underneath the application (layer which called silc_server_init). */
1235 silc_server_config_unref(&server->config_ref);
1236 silc_server_config_destroy(server->config);
1238 /* Take new config context */
1239 server->config = newconfig;
1240 silc_server_config_ref(&server->config_ref, server->config, server->config);
1243 /* Set debugging on if configured */
1244 if (server->config->debug_string) {
1245 silc_log_debug(TRUE);
1246 silc_log_set_debug_string(server->config->debug_string);
1248 #endif /* SILC_DEBUG */
1250 SILC_LOG_DEBUG(("Server rehashed"));
1256 /* The heart of the server. This runs the scheduler thus runs the server.
1257 When this returns the server has been stopped and the program will
1260 void silc_server_run(SilcServer server)
1262 SILC_LOG_INFO(("SILC Server started"));
1264 /* Start the scheduler, the heart of the SILC server. When this returns
1265 the program will be terminated. */
1266 silc_schedule(server->schedule);
1269 /* Stops the SILC server. This function is used to shutdown the server.
1270 This is usually called after the scheduler has returned. After stopping
1271 the server one should call silc_server_free. */
1273 void silc_server_stop(SilcServer server)
1276 SilcPacketStream ps;
1277 SilcNetListener listener;
1279 SILC_LOG_INFO(("SILC Server shutting down"));
1281 server->server_shutdown = TRUE;
1283 /* Close all connections */
1284 if (server->packet_engine) {
1285 list = silc_packet_engine_get_streams(server->packet_engine);
1287 silc_dlist_start(list);
1288 while ((ps = silc_dlist_get(list))) {
1289 SilcIDListData idata = silc_packet_get_context(ps);
1292 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1294 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1295 "Server is shutting down");
1296 silc_server_free_sock_user_data(server, ps,
1297 "Server is shutting down");
1299 silc_dlist_uninit(list);
1302 /* We are not connected to network anymore */
1303 server->standalone = TRUE;
1305 silc_dlist_start(server->listeners);
1306 while ((listener = silc_dlist_get(server->listeners)))
1307 silc_net_close_listener(listener);
1309 silc_server_http_uninit(server);
1311 silc_schedule_stop(server->schedule);
1313 SILC_LOG_DEBUG(("Server stopped"));
1316 /* Purge expired client entries from the server */
1318 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1320 SilcServer server = context;
1321 SilcClientEntry client;
1323 SilcUInt64 curtime = silc_time();
1325 SILC_LOG_DEBUG(("Expire timeout"));
1327 silc_dlist_start(server->expired_clients);
1328 while ((client = silc_dlist_get(server->expired_clients))) {
1329 if (client->data.status & SILC_IDLIST_STATUS_REGISTERED)
1332 /* For unregistered clients the created timestamp is actually
1333 unregistered timestamp. Make sure client remains in history
1334 at least 500 seconds. */
1335 if (curtime - client->data.created < 500)
1338 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1339 server->local_list : server->global_list);
1341 silc_idlist_del_data(client);
1342 silc_idlist_del_client(id_list, client);
1343 silc_dlist_del(server->expired_clients, client);
1346 silc_schedule_task_add_timeout(server->schedule,
1347 silc_server_purge_expired_clients, server,
1352 /******************************* Connecting *********************************/
1354 /* Free connection context */
1356 void silc_server_connection_free(SilcServerConnection sconn)
1358 SILC_LOG_DEBUG(("Free connection %p", sconn));
1359 silc_dlist_del(sconn->server->conns, sconn);
1360 silc_server_config_unref(&sconn->conn);
1361 silc_free(sconn->remote_host);
1362 silc_free(sconn->backup_replace_ip);
1366 /* Creates connection to a remote router. */
1368 void silc_server_create_connection(SilcServer server,
1371 const char *remote_host, SilcUInt32 port,
1372 SilcServerConnectCallback callback,
1375 SilcServerConnection sconn;
1377 /* Allocate connection object for hold connection specific stuff. */
1378 sconn = silc_calloc(1, sizeof(*sconn));
1381 sconn->remote_host = strdup(remote_host);
1382 sconn->remote_port = port;
1383 sconn->no_reconnect = reconnect == FALSE;
1384 sconn->callback = callback;
1385 sconn->callback_context = context;
1386 sconn->no_conf = dynamic;
1387 sconn->server = server;
1389 SILC_LOG_DEBUG(("Created connection %p", sconn));
1391 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1395 /* Connection authentication completion callback */
1398 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1401 SilcServerConnection sconn = context;
1402 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1403 SilcServer server = entry->server;
1404 SilcServerConfigServer *conn;
1405 SilcServerConfigConnParams *param;
1406 SilcIDListData idata;
1407 SilcServerEntry id_entry = NULL;
1408 unsigned char id[32];
1412 SILC_LOG_DEBUG(("Connection authentication completed"));
1416 if (success == FALSE) {
1417 /* Authentication failed */
1418 /* XXX retry connecting */
1420 silc_server_disconnect_remote(server, sconn->sock,
1421 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1422 if (sconn->callback)
1423 (*sconn->callback)(server, NULL, sconn->callback_context);
1427 /* XXX For now remote is router always */
1428 entry->data.conn_type = SILC_CONN_ROUTER;
1430 SILC_LOG_INFO(("Connected to %s %s",
1431 SILC_CONNTYPE_STRING(entry->data.conn_type),
1432 sconn->remote_host));
1434 /* Create the actual entry for remote entity */
1435 switch (entry->data.conn_type) {
1436 case SILC_CONN_SERVER:
1437 SILC_LOG_DEBUG(("Remote is SILC server"));
1439 /* Add new server. The server must register itself to us before it
1440 becomes registered to SILC network. */
1441 id_entry = silc_idlist_add_server(server->local_list,
1442 strdup(sconn->remote_host),
1443 SILC_SERVER, NULL, NULL, sconn->sock);
1445 silc_server_disconnect_remote(server, sconn->sock,
1446 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1447 if (sconn->callback)
1448 (*sconn->callback)(server, NULL, sconn->callback_context);
1449 silc_server_connection_free(sconn);
1454 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1457 case SILC_CONN_ROUTER:
1458 SILC_LOG_DEBUG(("Remote is SILC router"));
1460 /* Register to network */
1461 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1462 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1463 SILC_STR_UI_SHORT(id_len),
1464 SILC_STR_DATA(id, id_len),
1465 SILC_STR_UI_SHORT(strlen(server->server_name)),
1466 SILC_STR_DATA(server->server_name,
1467 strlen(server->server_name)),
1469 silc_server_disconnect_remote(server, sconn->sock,
1470 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1471 if (sconn->callback)
1472 (*sconn->callback)(server, NULL, sconn->callback_context);
1473 silc_server_connection_free(sconn);
1479 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1481 /* Check that we do not have this ID already */
1482 id_entry = silc_idlist_find_server_by_id(server->local_list,
1483 &remote_id.u.server_id,
1486 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1488 id_entry = silc_idlist_find_server_by_id(server->global_list,
1489 &remote_id.u.server_id,
1492 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1496 SILC_LOG_DEBUG(("New server id(%s)",
1497 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1499 /* Add the connected router to global server list. Router is sent
1500 as NULL since it's local to us. */
1501 id_entry = silc_idlist_add_server(server->global_list,
1502 strdup(sconn->remote_host),
1504 silc_id_dup(&remote_id.u.server_id,
1508 silc_server_disconnect_remote(server, sconn->sock,
1509 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1510 if (sconn->callback)
1511 (*sconn->callback)(server, NULL, sconn->callback_context);
1512 silc_server_connection_free(sconn);
1518 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1519 idata = (SilcIDListData)id_entry;
1520 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1521 SILC_IDLIST_STATUS_LOCAL);
1522 idata->sconn = sconn;
1524 if (!sconn->backup) {
1525 /* Mark this router our primary router if we're still standalone */
1526 if (server->standalone) {
1527 SILC_LOG_DEBUG(("This connection is our primary router"));
1528 server->id_entry->router = id_entry;
1529 server->router = id_entry;
1530 server->router->server_type = SILC_ROUTER;
1531 server->standalone = FALSE;
1532 server->backup_primary = FALSE;
1534 /* Announce data if we are not backup router (unless not as primary
1535 currently). Backup router announces later at the end of
1536 resuming protocol. */
1537 if (server->backup_router && server->server_type == SILC_ROUTER) {
1538 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1540 /* If we are router then announce our possible servers. Backup
1541 router announces also global servers. */
1542 if (server->server_type == SILC_ROUTER)
1543 silc_server_announce_servers(server,
1544 server->backup_router ? TRUE : FALSE,
1545 0, SILC_PRIMARY_ROUTE(server));
1547 /* Announce our clients and channels to the router */
1548 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1549 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1553 /* If we are backup router then this primary router is whom we are
1555 if (server->server_type == SILC_BACKUP_ROUTER)
1556 silc_server_backup_add(server, server->id_entry, sock->ip,
1557 sconn->remote_port, TRUE);
1560 /* We already have primary router. Disconnect this connection */
1561 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1562 silc_idlist_del_server(server->global_list, id_entry);
1563 silc_server_disconnect_remote(server, sconn->sock,
1564 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1565 if (sconn->callback)
1566 (*sconn->callback)(server, NULL, sconn->callback_context);
1567 silc_server_connection_free(sconn);
1572 /* Add this server to be our backup router */
1573 id_entry->server_type = SILC_BACKUP_ROUTER;
1574 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1575 sconn->backup_replace_port, FALSE);
1581 silc_server_disconnect_remote(server, sconn->sock,
1582 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1583 if (sconn->callback)
1584 (*sconn->callback)(server, NULL, sconn->callback_context);
1585 silc_server_connection_free(sconn);
1590 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1592 conn = sconn->conn.ref_ptr;
1593 param = &server->config->param;
1594 if (conn && conn->param)
1595 param = conn->param;
1597 /* Register rekey timeout */
1598 sconn->rekey_timeout = param->key_exchange_rekey;
1599 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1600 sconn->sock, sconn->rekey_timeout, 0);
1603 /* Perform keepalive. */
1604 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
1605 silc_server_perform_heartbeat,
1609 /* Set the entry as packet stream context */
1610 silc_packet_set_context(sconn->sock, id_entry);
1613 /* Call the completion callback to indicate that we've connected to
1615 if (sconn && sconn->callback)
1616 (*sconn->callback)(server, id_entry, sconn->callback_context);
1619 /* Free the temporary connection data context */
1621 silc_server_config_unref(&sconn->conn);
1622 silc_free(sconn->remote_host);
1623 silc_free(sconn->backup_replace_ip);
1626 if (sconn == server->router_conn)
1627 server->router_conn = NULL;
1633 /* SKE completion callback */
1635 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1636 SilcSKESecurityProperties prop,
1637 SilcSKEKeyMaterial keymat,
1638 SilcSKERekeyMaterial rekey,
1641 SilcPacketStream sock = context;
1642 SilcUnknownEntry entry = silc_packet_get_context(sock);
1643 SilcServerConnection sconn = silc_ske_get_context(ske);
1644 SilcServer server = entry->server;
1645 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1646 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1647 void *auth_data = NULL;
1648 SilcUInt32 auth_data_len = 0;
1649 SilcConnAuth connauth;
1650 SilcCipher send_key, receive_key;
1651 SilcHmac hmac_send, hmac_receive;
1656 if (status != SILC_SKE_STATUS_OK) {
1658 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1659 silc_ske_map_status(status), entry->hostname, entry->ip));
1661 /* XXX retry connecting */
1663 silc_server_disconnect_remote(server, sconn->sock,
1664 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1665 if (sconn->callback)
1666 (*sconn->callback)(server, NULL, sconn->callback_context);
1667 silc_server_connection_free(sconn);
1671 SILC_LOG_DEBUG(("Setting keys into use"));
1673 /* Set the keys into use. The data will be encrypted after this. */
1674 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1675 &hmac_send, &hmac_receive, &hash)) {
1677 /* XXX retry connecting */
1679 /* Error setting keys */
1681 silc_server_disconnect_remote(server, sconn->sock,
1682 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1683 if (sconn->callback)
1684 (*sconn->callback)(server, NULL, sconn->callback_context);
1685 silc_server_connection_free(sconn);
1688 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1689 hmac_receive, FALSE);
1691 SILC_LOG_DEBUG(("Starting connection authentication"));
1693 connauth = silc_connauth_alloc(server->schedule, ske,
1694 server->config->conn_auth_timeout);
1696 /* XXX retry connecting */
1698 /** Error allocating auth protocol */
1700 silc_server_disconnect_remote(server, sconn->sock,
1701 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1702 if (sconn->callback)
1703 (*sconn->callback)(server, NULL, sconn->callback_context);
1704 silc_server_connection_free(sconn);
1708 /* Get authentication method */
1710 if (conn->passphrase) {
1711 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1712 auth_meth = SILC_AUTH_PUBLIC_KEY;
1713 auth_data = server->private_key;
1715 auth_meth = SILC_AUTH_PASSWORD;
1716 auth_data = conn->passphrase;
1717 auth_data_len = conn->passphrase_len;
1720 auth_meth = SILC_AUTH_PUBLIC_KEY;
1721 auth_data = server->private_key;
1725 /* Start connection authentication */
1727 silc_connauth_initiator(connauth, server->server_type == SILC_ROUTER ?
1728 SILC_CONN_ROUTER : SILC_CONN_SERVER, auth_meth,
1729 auth_data, auth_data_len,
1730 silc_server_ke_auth_compl, sconn);
1733 /* Function that is called when the network connection to a router has
1734 been established. This will continue with the key exchange protocol
1735 with the remote router. */
1737 void silc_server_start_key_exchange(SilcServerConnection sconn)
1739 SilcServer server = sconn->server;
1740 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1741 SilcUnknownEntry entry;
1742 SilcSKEParamsStruct params;
1745 /* Cancel any possible retry timeouts */
1746 silc_schedule_task_del_by_context(server->schedule, sconn);
1748 /* Create packet stream */
1749 sconn->sock = silc_packet_stream_create(server->packet_engine,
1750 server->schedule, sconn->stream);
1752 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1753 silc_stream_destroy(sconn->stream);
1754 if (sconn->callback)
1755 (*sconn->callback)(server, NULL, sconn->callback_context);
1756 silc_server_connection_free(sconn);
1759 server->stat.conn_num++;
1761 /* Set source ID to packet stream */
1762 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1764 silc_packet_stream_destroy(sconn->sock);
1765 if (sconn->callback)
1766 (*sconn->callback)(server, NULL, sconn->callback_context);
1767 silc_server_connection_free(sconn);
1771 /* Create entry for remote entity */
1772 entry = silc_calloc(1, sizeof(*entry));
1774 silc_packet_stream_destroy(sconn->sock);
1775 silc_server_connection_free(sconn);
1778 entry->server = server;
1779 silc_packet_set_context(sconn->sock, entry);
1781 /* Set Key Exchange flags from configuration, but fall back to global
1783 memset(¶ms, 0, sizeof(params));
1784 SILC_GET_SKE_FLAGS(conn, params.flags);
1785 if (server->config->param.key_exchange_pfs)
1786 params.flags |= SILC_SKE_SP_FLAG_PFS;
1788 /* Start SILC Key Exchange protocol */
1789 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1790 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1791 server->public_key, server->private_key, sconn);
1794 silc_packet_stream_destroy(sconn->sock);
1795 if (sconn->callback)
1796 (*sconn->callback)(server, NULL, sconn->callback_context);
1797 silc_server_connection_free(sconn);
1800 silc_ske_set_callbacks(ske, silc_server_verify_key,
1801 silc_server_ke_completed, sconn->sock);
1803 /* Start key exchange protocol */
1804 params.version = silc_version_string;
1805 params.timeout_secs = server->config->key_exchange_timeout;
1806 sconn->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1809 /* Timeout callback that will be called to retry connecting to remote
1810 router. This is used by both normal and router server. This will wait
1811 before retrying the connecting. The timeout is generated by exponential
1812 backoff algorithm. */
1814 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1816 SilcServerConnection sconn = context;
1817 SilcServer server = sconn->server;
1818 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1819 SilcServerConfigConnParams *param =
1820 (conn->param ? conn->param : &server->config->param);
1822 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1823 sconn->remote_port));
1825 /* Calculate next timeout */
1826 if (sconn->retry_count >= 1) {
1827 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1828 if (sconn->retry_timeout > param->reconnect_interval_max)
1829 sconn->retry_timeout = param->reconnect_interval_max;
1831 sconn->retry_timeout = param->reconnect_interval;
1833 sconn->retry_count++;
1834 sconn->retry_timeout = sconn->retry_timeout +
1835 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1837 /* If we've reached max retry count, give up. */
1838 if ((sconn->retry_count > param->reconnect_count) &&
1839 !param->reconnect_keep_trying) {
1840 SILC_LOG_ERROR(("Could not connect, giving up"));
1842 if (sconn->callback)
1843 (*sconn->callback)(server, NULL, sconn->callback_context);
1844 silc_server_connection_free(sconn);
1848 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1850 /* We will lookup a fresh pointer later */
1851 silc_server_config_unref(&sconn->conn);
1853 /* Wait before retrying */
1854 silc_schedule_task_del_by_context(server->schedule, sconn);
1855 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1856 sconn, sconn->retry_timeout, 0);
1859 /* Callback for async connection to remote router */
1861 static void silc_server_connection_established(SilcNetStatus status,
1865 SilcServerConnection sconn = context;
1866 SilcServer server = sconn->server;
1868 silc_schedule_task_del_by_context(server->schedule, sconn);
1873 SILC_LOG_DEBUG(("Connection to %s:%d established",
1874 sconn->remote_host, sconn->remote_port));
1876 /* Continue with key exchange protocol */
1877 sconn->stream = stream;
1878 silc_server_start_key_exchange(sconn);
1881 case SILC_NET_UNKNOWN_IP:
1882 case SILC_NET_UNKNOWN_HOST:
1883 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1884 sconn->remote_host, sconn->remote_port,
1885 silc_net_get_error_string(status)));
1887 if (sconn->callback)
1888 (*sconn->callback)(server, NULL, sconn->callback_context);
1889 silc_server_connection_free(sconn);
1893 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1894 sconn->remote_host, sconn->remote_port,
1895 silc_net_get_error_string(status)));
1896 if (!sconn->no_reconnect) {
1897 silc_schedule_task_add_timeout(sconn->server->schedule,
1898 silc_server_connect_to_router_retry,
1901 if (sconn->callback)
1902 (*sconn->callback)(server, NULL, sconn->callback_context);
1903 silc_server_connection_free(sconn);
1909 /* Generic routine to use connect to a router. */
1911 SILC_TASK_CALLBACK(silc_server_connect_router)
1913 SilcServerConnection sconn = context;
1914 SilcServer server = sconn->server;
1915 SilcServerConfigRouter *rconn;
1917 silc_schedule_task_del_by_context(server->schedule, sconn);
1919 /* Don't connect if we are shutting down. */
1920 if (server->server_shutdown) {
1921 if (sconn->callback)
1922 (*sconn->callback)(server, NULL, sconn->callback_context);
1923 silc_server_connection_free(sconn);
1927 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1928 (sconn->backup ? "backup router" : "router"),
1929 sconn->remote_host, sconn->remote_port));
1931 if (!sconn->no_conf) {
1932 /* Find connection configuration */
1933 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1934 sconn->remote_port);
1936 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1937 (sconn->backup ? "backup router" : "router"),
1938 sconn->remote_host, sconn->remote_port));
1939 silc_server_connection_free(sconn);
1942 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1945 /* Connect to remote host */
1947 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1948 server->config->server_info->primary->server_ip),
1949 sconn->remote_host, sconn->remote_port,
1950 server->schedule, silc_server_connection_established,
1953 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1954 sconn->remote_host, sconn->remote_port));
1955 silc_server_connection_free(sconn);
1959 /* Add to connection list */
1960 silc_dlist_add(server->conns, sconn);
1963 /* This function connects to our primary router or if we are a router this
1964 establishes all our primary routes. This is called at the start of the
1965 server to do authentication and key exchange with our router - called
1968 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1970 SilcServer server = context;
1971 SilcServerConnection sconn;
1972 SilcServerConfigRouter *ptr;
1974 /* Don't connect if we are shutting down. */
1975 if (server->server_shutdown)
1978 SILC_LOG_DEBUG(("We are %s",
1979 (server->server_type == SILC_SERVER ?
1980 "normal server" : server->server_type == SILC_ROUTER ?
1981 "router" : "backup router/normal server")));
1984 if (!server->config->routers) {
1985 /* There wasn't a configured router, we will continue but we don't
1986 have a connection to outside world. We will be standalone server. */
1987 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1988 server->standalone = TRUE;
1992 /* Create the connections to all our routes */
1993 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1995 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1996 ptr->backup_router ? "Backup router" : "Router",
1997 ptr->initiator ? "Initiator" : "Responder",
1998 ptr->host, ptr->port));
2000 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2001 ptr->initiator == FALSE && !server->backup_router &&
2002 !silc_server_config_get_backup_router(server))
2003 server->wait_backup = TRUE;
2005 if (!ptr->initiator)
2007 if (ptr->dynamic_connection)
2010 /* Check whether we are connecting or connected to this host already */
2011 if (silc_server_num_sockets_by_remote(server,
2012 silc_net_is_ip(ptr->host) ?
2014 silc_net_is_ip(ptr->host) ?
2015 NULL : ptr->host, ptr->port)) {
2016 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2017 ptr->host, ptr->port));
2019 /* If we don't have primary router and this connection is our
2020 primary router we are in desync. Reconnect to the primary. */
2021 if (server->standalone && !server->router) {
2023 SilcPacketStream sock;
2024 SilcServerConfigRouter *primary =
2025 silc_server_config_get_primary_router(server);
2028 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2029 ptr->host, ptr->port);
2032 server->backup_noswitch = TRUE;
2034 if (sock->user_data)
2035 silc_server_free_sock_user_data(server, sock, NULL);
2036 silc_server_disconnect_remote(server, sock, 0, NULL);
2038 server->backup_noswitch = FALSE;
2039 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2045 /* Allocate connection object for hold connection specific stuff. */
2046 sconn = silc_calloc(1, sizeof(*sconn));
2049 sconn->remote_host = strdup(ptr->host);
2050 sconn->remote_port = ptr->port;
2051 sconn->backup = ptr->backup_router;
2052 if (sconn->backup) {
2053 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2054 sconn->backup_replace_port = ptr->backup_replace_port;
2057 SILC_LOG_DEBUG(("Created connection %p", sconn));
2060 if (!server->router_conn && !sconn->backup)
2061 server->router_conn = sconn;
2064 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2070 /************************ Accepting new connection **************************/
2072 /* After this is called, server don't wait for backup router anymore.
2073 This gets called automatically even after we have backup router
2074 connection established. */
2076 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2078 SilcServer server = context;
2079 server->wait_backup = FALSE;
2082 /* Authentication data callback */
2085 silc_server_accept_get_auth(SilcConnAuth connauth,
2086 SilcConnectionType conn_type,
2087 unsigned char **passphrase,
2088 SilcUInt32 *passphrase_len,
2089 SilcSKR *repository,
2092 SilcPacketStream sock = context;
2093 SilcUnknownEntry entry = silc_packet_get_context(sock);
2094 SilcServer server = entry->server;
2096 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2098 /* Remote end is client */
2099 if (conn_type == SILC_CONN_CLIENT) {
2100 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2104 *passphrase = cconfig->passphrase;
2105 *passphrase_len = cconfig->passphrase_len;
2106 if (cconfig->publickeys)
2107 *repository = server->repository;
2109 entry->data.conn_type = conn_type;
2113 /* Remote end is server */
2114 if (conn_type == SILC_CONN_SERVER) {
2115 SilcServerConfigServer *sconfig;
2117 /* If we are normal server, don't accept the connection */
2118 if (server->server_type == SILC_SERVER)
2121 sconfig = entry->sconfig.ref_ptr;
2125 *passphrase = sconfig->passphrase;
2126 *passphrase_len = sconfig->passphrase_len;
2127 if (sconfig->publickeys)
2128 *repository = server->repository;
2130 entry->data.conn_type = conn_type;
2134 /* Remote end is router */
2135 if (conn_type == SILC_CONN_ROUTER) {
2136 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2140 *passphrase = rconfig->passphrase;
2141 *passphrase_len = rconfig->passphrase_len;
2142 if (rconfig->publickeys)
2143 *repository = server->repository;
2145 entry->data.conn_type = conn_type;
2152 /* Authentication completion callback. */
2155 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2158 SilcPacketStream sock = context;
2159 SilcUnknownEntry entry = silc_packet_get_context(sock);
2160 SilcIDListData idata = (SilcIDListData)entry;
2161 SilcServer server = entry->server;
2162 SilcServerConfigConnParams *param = &server->config->param;
2163 SilcServerConnection sconn;
2165 const char *hostname;
2169 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2170 NULL, &hostname, NULL, &port);
2172 if (success == FALSE) {
2173 /* Authentication failed */
2174 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2175 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2176 server->stat.auth_failures++;
2177 silc_server_disconnect_remote(server, sock,
2178 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2182 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2184 switch (entry->data.conn_type) {
2185 case SILC_CONN_CLIENT:
2187 SilcClientEntry client;
2188 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2190 /* Verify whether this connection is after all allowed to connect */
2191 if (!silc_server_connection_allowed(server, sock, entry->data.conn_type,
2192 &server->config->param,
2194 silc_connauth_get_ske(connauth))) {
2195 server->stat.auth_failures++;
2199 /* If we are primary router and we have backup router configured
2200 but it has not connected to use yet, do not accept any other
2202 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2203 !server->backup_router) {
2204 SilcServerConfigRouter *router;
2205 router = silc_server_config_get_backup_router(server);
2206 if (router && strcmp(server->config->server_info->primary->server_ip,
2208 silc_server_find_socket_by_host(server,
2210 router->backup_replace_ip, 0)) {
2211 SILC_LOG_INFO(("Will not accept connections because we do "
2212 "not have backup router connection established"));
2213 silc_server_disconnect_remote(server, sock,
2214 SILC_STATUS_ERR_PERM_DENIED,
2215 "We do not have connection to backup "
2216 "router established, try later");
2217 server->stat.auth_failures++;
2219 /* From here on, wait 20 seconds for the backup router to appear. */
2220 silc_schedule_task_add_timeout(server->schedule,
2221 silc_server_backup_router_wait,
2222 (void *)server, 20, 0);
2227 SILC_LOG_DEBUG(("Remote host is client"));
2228 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2231 /* Add the client to the client ID cache. The nickname and Client ID
2232 and other information is created after we have received NEW_CLIENT
2233 packet from client. */
2234 client = silc_idlist_add_client(server->local_list,
2235 NULL, NULL, NULL, NULL, NULL, sock);
2237 SILC_LOG_ERROR(("Could not add new client to cache"));
2238 server->stat.auth_failures++;
2239 silc_server_disconnect_remote(server, sock,
2240 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2243 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2246 server->stat.my_clients++;
2247 server->stat.clients++;
2248 server->stat.cell_clients++;
2250 /* Get connection parameters */
2252 param = conn->param;
2254 if (!param->keepalive_secs)
2255 param->keepalive_secs = server->config->param.keepalive_secs;
2257 if (!param->qos && server->config->param.qos) {
2258 param->qos = server->config->param.qos;
2259 param->qos_rate_limit = server->config->param.qos_rate_limit;
2260 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2261 param->qos_limit_sec = server->config->param.qos_limit_sec;
2262 param->qos_limit_usec = server->config->param.qos_limit_usec;
2265 /* Check if to be anonymous connection */
2266 if (param->anonymous)
2267 client->mode |= SILC_UMODE_ANONYMOUS;
2270 /* Add public key to repository */
2271 if (!silc_server_get_public_key_by_client(server, client, NULL))
2272 silc_skr_add_public_key_simple(server->repository,
2273 entry->data.public_key,
2274 SILC_SKR_USAGE_IDENTIFICATION, client,
2277 id_entry = (void *)client;
2281 case SILC_CONN_SERVER:
2282 case SILC_CONN_ROUTER:
2284 SilcServerEntry new_server;
2285 SilcBool initiator = FALSE;
2286 SilcBool backup_local = FALSE;
2287 SilcBool backup_router = FALSE;
2288 char *backup_replace_ip = NULL;
2289 SilcUInt16 backup_replace_port = 0;
2290 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2291 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2293 /* If we are backup router and this is incoming server connection
2294 and we do not have connection to primary router, do not allow
2296 if (server->server_type == SILC_BACKUP_ROUTER &&
2297 entry->data.conn_type == SILC_CONN_SERVER &&
2298 !SILC_PRIMARY_ROUTE(server)) {
2299 SILC_LOG_INFO(("Will not accept server connection because we do "
2300 "not have primary router connection established"));
2301 silc_server_disconnect_remote(server, sock,
2302 SILC_STATUS_ERR_PERM_DENIED,
2303 "We do not have connection to primary "
2304 "router established, try later");
2305 server->stat.auth_failures++;
2309 if (entry->data.conn_type == SILC_CONN_ROUTER) {
2310 /* Verify whether this connection is after all allowed to connect */
2311 if (!silc_server_connection_allowed(server, sock,
2312 entry->data.conn_type,
2313 &server->config->param,
2314 rconn ? rconn->param : NULL,
2315 silc_connauth_get_ske(connauth))) {
2316 server->stat.auth_failures++;
2322 param = rconn->param;
2324 if (!param->keepalive_secs)
2325 param->keepalive_secs = server->config->param.keepalive_secs;
2327 if (!param->qos && server->config->param.qos) {
2328 param->qos = server->config->param.qos;
2329 param->qos_rate_limit = server->config->param.qos_rate_limit;
2330 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2331 param->qos_limit_sec = server->config->param.qos_limit_sec;
2332 param->qos_limit_usec = server->config->param.qos_limit_usec;
2336 initiator = rconn->initiator;
2337 backup_local = rconn->backup_local;
2338 backup_router = rconn->backup_router;
2339 backup_replace_ip = rconn->backup_replace_ip;
2340 backup_replace_port = rconn->backup_replace_port;
2344 if (entry->data.conn_type == SILC_CONN_SERVER) {
2345 /* Verify whether this connection is after all allowed to connect */
2346 if (!silc_server_connection_allowed(server, sock,
2347 entry->data.conn_type,
2348 &server->config->param,
2349 srvconn ? srvconn->param : NULL,
2350 silc_connauth_get_ske(connauth))) {
2351 server->stat.auth_failures++;
2355 if (srvconn->param) {
2356 param = srvconn->param;
2358 if (!param->keepalive_secs)
2359 param->keepalive_secs = server->config->param.keepalive_secs;
2361 if (!param->qos && server->config->param.qos) {
2362 param->qos = server->config->param.qos;
2363 param->qos_rate_limit = server->config->param.qos_rate_limit;
2364 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2365 param->qos_limit_sec = server->config->param.qos_limit_sec;
2366 param->qos_limit_usec = server->config->param.qos_limit_usec;
2370 backup_router = srvconn->backup_router;
2374 /* If we are primary router and we have backup router configured
2375 but it has not connected to use yet, do not accept any other
2378 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2379 !server->backup_router && !backup_router) {
2380 SilcServerConfigRouter *router;
2381 router = silc_server_config_get_backup_router(server);
2382 if (router && strcmp(server->config->server_info->primary->server_ip,
2384 silc_server_find_socket_by_host(server,
2386 router->backup_replace_ip, 0)) {
2387 SILC_LOG_INFO(("Will not accept connections because we do "
2388 "not have backup router connection established"));
2389 silc_server_disconnect_remote(server, sock,
2390 SILC_STATUS_ERR_PERM_DENIED,
2391 "We do not have connection to backup "
2392 "router established, try later");
2393 server->stat.auth_failures++;
2395 /* From here on, wait 20 seconds for the backup router to appear. */
2396 silc_schedule_task_add_timeout(server->schedule,
2397 silc_server_backup_router_wait,
2398 (void *)server, 20, 0);
2404 SILC_LOG_DEBUG(("Remote host is %s",
2405 entry->data.conn_type == SILC_CONN_SERVER ?
2406 "server" : (backup_router ?
2407 "backup router" : "router")));
2408 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2409 entry->ip, entry->data.conn_type == SILC_CONN_SERVER ?
2410 "server" : (backup_router ?
2411 "backup router" : "router")));
2413 /* Add the server into server cache. The server name and Server ID
2414 is updated after we have received NEW_SERVER packet from the
2415 server. We mark ourselves as router for this server if we really
2418 silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ?
2419 server->local_list : (backup_router ?
2420 server->local_list :
2421 server->global_list)),
2423 (entry->data.conn_type == SILC_CONN_SERVER ?
2424 SILC_SERVER : SILC_ROUTER),
2426 (entry->data.conn_type == SILC_CONN_SERVER ?
2427 server->id_entry : (backup_router ?
2428 server->id_entry : NULL)),
2431 SILC_LOG_ERROR(("Could not add new server to cache"));
2432 silc_server_disconnect_remote(server, sock,
2433 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2434 server->stat.auth_failures++;
2437 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2439 id_entry = (void *)new_server;
2441 /* If the incoming connection is router and marked as backup router
2442 then add it to be one of our backups */
2443 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2444 /* Change it back to SERVER type since that's what it really is. */
2446 entry->data.conn_type = SILC_CONN_SERVER;
2447 new_server->server_type = SILC_BACKUP_ROUTER;
2449 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2450 ("Backup router %s is now online",
2453 /* Remove the backup waiting with timeout */
2454 silc_schedule_task_add_timeout(server->schedule,
2455 silc_server_backup_router_wait,
2456 (void *)server, 10, 0);
2460 if (entry->data.conn_type == SILC_CONN_SERVER) {
2461 server->stat.my_servers++;
2462 server->stat.servers++;
2464 server->stat.my_routers++;
2465 server->stat.routers++;
2468 /* Check whether this connection is to be our primary router connection
2469 if we do not already have the primary route. */
2470 if (!backup_router &&
2471 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2472 if (silc_server_config_is_primary_route(server) && !initiator)
2475 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2476 server->standalone = FALSE;
2477 if (!server->id_entry->router) {
2478 server->id_entry->router = id_entry;
2479 server->router = id_entry;
2491 /* Add connection to server->conns so that we know we have connection
2493 sconn = silc_calloc(1, sizeof(*sconn));
2494 sconn->server = server;
2496 sconn->remote_host = strdup(hostname);
2497 sconn->remote_port = port;
2498 silc_dlist_add(server->conns, sconn);
2499 idata->sconn = sconn;
2500 idata->last_receive = time(NULL);
2502 /* Add the common data structure to the ID entry. */
2503 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2504 silc_packet_set_context(sock, id_entry);
2506 /* Connection has been fully established now. Everything is ok. */
2507 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2510 /* Perform keepalive. */
2511 if (param->keepalive_secs)
2512 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
2513 silc_server_perform_heartbeat,
2517 /* Perform Quality of Service */
2519 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2520 param->qos_rate_limit, param->qos_bytes_limit,
2521 param->qos_limit_sec, param->qos_limit_usec);
2523 silc_server_config_unref(&entry->cconfig);
2524 silc_server_config_unref(&entry->sconfig);
2525 silc_server_config_unref(&entry->rconfig);
2529 silc_ske_free(silc_connauth_get_ske(connauth));
2530 silc_connauth_free(connauth);
2533 /* SKE completion callback. We set the new keys into use here. */
2536 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2537 SilcSKESecurityProperties prop,
2538 SilcSKEKeyMaterial keymat,
2539 SilcSKERekeyMaterial rekey,
2542 SilcPacketStream sock = context;
2543 SilcUnknownEntry entry = silc_packet_get_context(sock);
2544 SilcIDListData idata = (SilcIDListData)entry;
2545 SilcServer server = entry->server;
2546 SilcConnAuth connauth;
2547 SilcCipher send_key, receive_key;
2548 SilcHmac hmac_send, hmac_receive;
2555 if (status != SILC_SKE_STATUS_OK) {
2557 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2558 silc_ske_map_status(status), entry->hostname, entry->ip));
2560 silc_server_disconnect_remote(server, sock,
2561 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2565 SILC_LOG_DEBUG(("Setting keys into use"));
2567 /* Set the keys into use. The data will be encrypted after this. */
2568 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2569 &hmac_send, &hmac_receive, &hash)) {
2570 /* Error setting keys */
2572 silc_server_disconnect_remote(server, sock,
2573 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2576 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2577 hmac_receive, FALSE);
2579 idata->rekey = rekey;
2580 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2581 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2582 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2584 SILC_LOG_DEBUG(("Starting connection authentication"));
2585 server->stat.auth_attempts++;
2587 connauth = silc_connauth_alloc(server->schedule, ske,
2588 server->config->conn_auth_timeout);
2590 /** Error allocating auth protocol */
2592 silc_server_disconnect_remote(server, sock,
2593 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2597 /* Start connection authentication */
2599 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2600 silc_server_accept_auth_compl, sock);
2603 /* Accept new TCP connection */
2605 static void silc_server_accept_new_connection(SilcNetStatus status,
2609 SilcServer server = context;
2610 SilcPacketStream packet_stream;
2611 SilcServerConfigClient *cconfig = NULL;
2612 SilcServerConfigServer *sconfig = NULL;
2613 SilcServerConfigRouter *rconfig = NULL;
2614 SilcServerConfigDeny *deny;
2615 SilcUnknownEntry entry;
2617 SilcSKEParamsStruct params;
2618 char *hostname, *ip;
2621 SILC_LOG_DEBUG(("Accepting new connection"));
2623 /* Check for maximum allowed connections */
2624 server->stat.conn_attempts++;
2625 if (silc_dlist_count(server->conns) >
2626 server->config->param.connections_max) {
2627 SILC_LOG_ERROR(("Refusing connection, server is full"));
2628 server->stat.conn_failures++;
2629 silc_stream_destroy(stream);
2633 /* Get hostname, IP and port */
2634 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2635 (const char **)&ip, &port)) {
2636 /* Bad socket stream */
2637 server->stat.conn_failures++;
2638 silc_stream_destroy(stream);
2642 /* Create packet stream */
2643 packet_stream = silc_packet_stream_create(server->packet_engine,
2644 server->schedule, stream);
2645 if (!packet_stream) {
2646 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2647 server->stat.conn_failures++;
2648 silc_stream_destroy(stream);
2651 server->stat.conn_num++;
2653 /* Set source ID to packet stream */
2654 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2657 server->stat.conn_failures++;
2658 silc_packet_stream_destroy(packet_stream);
2662 /* Check whether this connection is denied to connect to us. */
2663 deny = silc_server_config_find_denied(server, ip);
2665 deny = silc_server_config_find_denied(server, hostname);
2667 /* The connection is denied */
2668 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2669 silc_server_disconnect_remote(server, packet_stream,
2670 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2675 /* Check whether we have configured this sort of connection at all. We
2676 have to check all configurations since we don't know what type of
2677 connection this is. */
2678 if (!(cconfig = silc_server_config_find_client(server, ip)))
2679 cconfig = silc_server_config_find_client(server, hostname);
2680 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2681 sconfig = silc_server_config_find_server_conn(server, hostname);
2682 if (server->server_type == SILC_ROUTER)
2683 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2684 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2685 if (!cconfig && !sconfig && !rconfig) {
2686 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2687 server->stat.conn_failures++;
2688 silc_server_disconnect_remote(server, packet_stream,
2689 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2693 /* The connection is allowed */
2694 entry = silc_calloc(1, sizeof(*entry));
2696 server->stat.conn_failures++;
2697 silc_server_disconnect_remote(server, packet_stream,
2698 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2701 entry->hostname = hostname;
2704 entry->server = server;
2705 entry->data.conn_type = SILC_CONN_UNKNOWN;
2706 silc_packet_set_context(packet_stream, entry);
2708 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2709 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2710 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2712 /* Take flags for key exchange. Since we do not know what type of connection
2713 this is, we go through all found configurations and use the global ones
2714 as well. This will result always into strictest key exchange flags. */
2715 memset(¶ms, 0, sizeof(params));
2716 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2717 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2718 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2719 if (server->config->param.key_exchange_pfs)
2720 params.flags |= SILC_SKE_SP_FLAG_PFS;
2722 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2723 server->stat.conn_attempts++;
2725 /* Start SILC Key Exchange protocol */
2726 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2727 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2728 server->public_key, server->private_key,
2731 server->stat.conn_failures++;
2732 silc_server_disconnect_remote(server, packet_stream,
2733 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2736 silc_ske_set_callbacks(ske, silc_server_verify_key,
2737 silc_server_accept_completed, packet_stream);
2739 /* Start key exchange protocol */
2740 params.version = silc_version_string;
2741 params.timeout_secs = server->config->key_exchange_timeout;
2742 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2746 /********************************** Rekey ***********************************/
2748 /* Initiator rekey completion callback */
2750 static void silc_server_rekey_completion(SilcSKE ske,
2751 SilcSKEStatus status,
2752 const SilcSKESecurityProperties prop,
2753 const SilcSKEKeyMaterial keymat,
2754 SilcSKERekeyMaterial rekey,
2757 SilcPacketStream sock = context;
2758 SilcIDListData idata = silc_packet_get_context(sock);
2759 SilcServer server = idata->sconn->server;
2761 idata->sconn->op = NULL;
2762 if (status != SILC_SKE_STATUS_OK) {
2763 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2764 idata->sconn->remote_host));
2768 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2769 idata->sconn->remote_host, idata->sconn->remote_port,
2770 SILC_CONNTYPE_STRING(idata->conn_type)));
2772 /* Save rekey data for next rekey */
2773 idata->rekey = rekey;
2775 /* Register new rekey timeout */
2776 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2777 sock, idata->sconn->rekey_timeout, 0);
2780 /* Rekey callback. Start rekey as initiator */
2782 SILC_TASK_CALLBACK(silc_server_do_rekey)
2784 SilcServer server = app_context;
2785 SilcPacketStream sock = context;
2786 SilcIDListData idata = silc_packet_get_context(sock);
2789 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2791 /* Do not execute rekey with disabled connections */
2792 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2795 /* If another protocol is active do not start rekey */
2796 if (idata->sconn->op) {
2797 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2798 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2803 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2804 idata->sconn->remote_host, idata->sconn->remote_port,
2805 SILC_CONNTYPE_STRING(idata->conn_type)));
2808 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2809 server->public_key, server->private_key, sock);
2813 /* Set SKE callbacks */
2814 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2817 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2820 /* Responder rekey completion callback */
2823 silc_server_rekey_resp_completion(SilcSKE ske,
2824 SilcSKEStatus status,
2825 const SilcSKESecurityProperties prop,
2826 const SilcSKEKeyMaterial keymat,
2827 SilcSKERekeyMaterial rekey,
2830 SilcPacketStream sock = context;
2831 SilcIDListData idata = silc_packet_get_context(sock);
2833 idata->sconn->op = NULL;
2834 if (status != SILC_SKE_STATUS_OK) {
2835 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2836 idata->sconn->remote_host));
2840 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2841 idata->sconn->remote_host, idata->sconn->remote_port,
2842 SILC_CONNTYPE_STRING(idata->conn_type)));
2844 /* Save rekey data for next rekey */
2845 idata->rekey = rekey;
2848 /* Start rekey as responder */
2850 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2853 SilcIDListData idata = silc_packet_get_context(sock);
2856 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2857 idata->sconn->remote_host, idata->sconn->remote_port,
2858 SILC_CONNTYPE_STRING(idata->conn_type)));
2861 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2862 server->public_key, server->private_key, sock);
2864 silc_packet_free(packet);
2868 /* Set SKE callbacks */
2869 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2872 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2877 /****************************** Disconnection *******************************/
2879 /* Destroys packet stream. */
2881 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2883 silc_packet_stream_destroy(context);
2886 /* Closes connection to socket connection */
2888 void silc_server_close_connection(SilcServer server,
2889 SilcPacketStream sock)
2891 SilcIDListData idata = silc_packet_get_context(sock);
2893 const char *hostname;
2896 memset(tmp, 0, sizeof(tmp));
2897 // silc_socket_get_error(sock, tmp, sizeof(tmp));
2898 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2899 NULL, &hostname, NULL, &port);
2900 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2901 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
2902 tmp[0] ? tmp : ""));
2904 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2906 if (idata && idata->sconn) {
2907 silc_server_connection_free(idata->sconn);
2908 idata->sconn = NULL;
2911 /* Close connection with timeout */
2912 server->stat.conn_num--;
2913 silc_schedule_task_del_by_all(server->schedule, 0,
2914 silc_server_close_connection_final, sock);
2915 silc_schedule_task_add_timeout(server->schedule,
2916 silc_server_close_connection_final,
2920 /* Sends disconnect message to remote connection and disconnects the
2923 void silc_server_disconnect_remote(SilcServer server,
2924 SilcPacketStream sock,
2925 SilcStatus status, ...)
2927 unsigned char buf[512];
2934 SILC_LOG_DEBUG(("Disconnecting remote host"));
2936 va_start(ap, status);
2937 cp = va_arg(ap, char *);
2939 silc_vsnprintf(buf, sizeof(buf), cp, ap);
2942 /* Send SILC_PACKET_DISCONNECT */
2943 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2944 SILC_STR_UI_CHAR(status),
2945 SILC_STR_UI8_STRING(cp ? buf : NULL),
2948 /* Close connection */
2949 silc_server_close_connection(server, sock);
2952 /* Frees client data and notifies about client's signoff. */
2954 void silc_server_free_client_data(SilcServer server,
2955 SilcPacketStream sock,
2956 SilcClientEntry client,
2958 const char *signoff)
2960 SILC_LOG_DEBUG(("Freeing client %p data", client));
2963 /* Check if anyone is watching this nickname */
2964 if (server->server_type == SILC_ROUTER)
2965 silc_server_check_watcher_list(server, client, NULL,
2966 SILC_NOTIFY_TYPE_SIGNOFF);
2968 /* Send SIGNOFF notify to routers. */
2970 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2971 SILC_BROADCAST(server), client->id,
2975 /* Remove client from all channels */
2977 silc_server_remove_from_channels(server, NULL, client,
2978 TRUE, (char *)signoff, TRUE, FALSE);
2980 silc_server_remove_from_channels(server, NULL, client,
2981 FALSE, NULL, FALSE, FALSE);
2983 /* Remove this client from watcher list if it is */
2984 silc_server_del_from_watcher_list(server, client);
2986 /* Remove client's public key from repository, this will free it too. */
2987 if (client->data.public_key) {
2988 silc_skr_del_public_key(server->repository, client->data.public_key,
2990 client->data.public_key = NULL;
2993 /* Update statistics */
2994 server->stat.my_clients--;
2995 server->stat.clients--;
2996 if (server->stat.cell_clients)
2997 server->stat.cell_clients--;
2998 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2999 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3000 silc_schedule_task_del_by_context(server->schedule, client);
3002 if (client->data.sconn)
3003 silc_server_connection_free(client->data.sconn);
3005 /* We will not delete the client entry right away. We will take it
3006 into history (for WHOWAS command) for 5 minutes, unless we're
3007 shutting down server. */
3008 if (!server->server_shutdown) {
3009 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3011 client->router = NULL;
3012 client->connection = NULL;
3013 client->data.created = silc_time();
3014 silc_dlist_add(server->expired_clients, client);
3016 /* Delete directly since we're shutting down server */
3017 SILC_LOG_DEBUG(("Delete client directly"));
3018 silc_idlist_del_data(client);
3019 silc_idlist_del_client(server->local_list, client);
3023 /* Frees user_data pointer from socket connection object. This also sends
3024 appropriate notify packets to the network to inform about leaving
3027 void silc_server_free_sock_user_data(SilcServer server,
3028 SilcPacketStream sock,
3029 const char *signoff_message)
3031 SilcIDListData idata = silc_packet_get_context(sock);
3033 SILC_LOG_DEBUG(("Start"));
3038 silc_schedule_task_del_by_context(server->schedule, sock);
3040 /* Cancel active protocols */
3042 if (idata->sconn && idata->sconn->op) {
3043 SILC_LOG_DEBUG(("Abort active protocol"));
3044 silc_async_abort(idata->sconn->op, NULL, NULL);
3046 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3047 ((SilcUnknownEntry)idata)->op) {
3048 SILC_LOG_DEBUG(("Abort active protocol"));
3049 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3053 switch (idata->conn_type) {
3054 case SILC_CONN_CLIENT:
3056 SilcClientEntry client_entry = (SilcClientEntry)idata;
3057 silc_server_free_client_data(server, sock, client_entry, TRUE,
3059 silc_packet_set_context(sock, NULL);
3063 case SILC_CONN_SERVER:
3064 case SILC_CONN_ROUTER:
3066 SilcServerEntry user_data = (SilcServerEntry)idata;
3067 SilcServerEntry backup_router = NULL;
3069 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3072 backup_router = silc_server_backup_get(server, user_data->id);
3074 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3075 backup_router == server->id_entry &&
3076 idata->conn_type != SILC_CONN_ROUTER)
3077 backup_router = NULL;
3079 if (server->server_shutdown || server->backup_noswitch)
3080 backup_router = NULL;
3082 /* If this was our primary router connection then we're lost to
3083 the outside world. */
3084 if (server->router == user_data) {
3085 /* Check whether we have a backup router connection */
3086 if (!backup_router || backup_router == user_data) {
3087 if (!server->no_reconnect)
3088 silc_server_create_connections(server);
3089 server->id_entry->router = NULL;
3090 server->router = NULL;
3091 server->standalone = TRUE;
3092 server->backup_primary = FALSE;
3093 backup_router = NULL;
3095 if (server->id_entry != backup_router) {
3096 SILC_LOG_INFO(("New primary router is backup router %s",
3097 backup_router->server_name));
3098 server->id_entry->router = backup_router;
3099 server->router = backup_router;
3100 server->router_connect = time(0);
3101 server->backup_primary = TRUE;
3102 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3104 /* Send START_USE to backup router to indicate we have switched */
3105 silc_server_backup_send_start_use(server,
3106 backup_router->connection,
3109 SILC_LOG_INFO(("We are now new primary router in this cell"));
3110 server->id_entry->router = NULL;
3111 server->router = NULL;
3112 server->standalone = TRUE;
3115 /* We stop here to take a breath */
3119 if (server->backup_router) {
3120 server->server_type = SILC_ROUTER;
3122 /* We'll need to constantly try to reconnect to the primary
3123 router so that we'll see when it comes back online. */
3124 silc_server_backup_reconnect(server, sock->ip, sock->port,
3125 silc_server_backup_connected,
3130 /* Mark this connection as replaced */
3131 silc_server_backup_replaced_add(server, user_data->id,
3134 } else if (backup_router) {
3135 SILC_LOG_INFO(("Enabling the use of backup router %s",
3136 backup_router->server_name));
3138 /* Mark this connection as replaced */
3139 silc_server_backup_replaced_add(server, user_data->id,
3141 } else if (server->server_type == SILC_SERVER &&
3142 idata->conn_type == SILC_CONN_ROUTER) {
3143 /* Reconnect to the router (backup) */
3144 if (!server->no_reconnect)
3145 silc_server_create_connections(server);
3148 if (user_data->server_name)
3149 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3150 ("Server %s signoff", user_data->server_name));
3152 if (!backup_router) {
3153 /* Remove all servers that are originated from this server, and
3154 remove the clients of those servers too. */
3155 silc_server_remove_servers_by_server(server, user_data, TRUE);
3158 /* Remove the clients that this server owns as they will become
3159 invalid now too. For backup router the server is actually
3160 coming from the primary router, so mark that as the owner
3162 if (server->server_type == SILC_BACKUP_ROUTER &&
3163 sock->type == SILC_CONN_SERVER)
3164 silc_server_remove_clients_by_server(server, server->router,
3168 silc_server_remove_clients_by_server(server, user_data,
3171 /* Remove channels owned by this server */
3172 if (server->server_type == SILC_SERVER)
3173 silc_server_remove_channels_by_server(server, user_data);
3175 /* Enable local server connections that may be disabled */
3176 silc_server_local_servers_toggle_enabled(server, TRUE);
3178 /* Update the client entries of this server to the new backup
3179 router. If we are the backup router we also resolve the real
3180 servers for the clients. After updating is over this also
3181 removes the clients that this server explicitly owns. */
3182 silc_server_update_clients_by_server(server, user_data,
3183 backup_router, TRUE);
3185 /* If we are router and just lost our primary router (now standlaone)
3186 we remove everything that was behind it, since we don't know
3188 if (server->server_type == SILC_ROUTER && server->standalone)
3189 /* Remove all servers that are originated from this server, and
3190 remove the clients of those servers too. */
3191 silc_server_remove_servers_by_server(server, user_data, TRUE);
3193 /* Finally remove the clients that are explicitly owned by this
3194 server. They go down with the server. */
3195 silc_server_remove_clients_by_server(server, user_data,
3198 /* Update our server cache to use the new backup router too. */
3199 silc_server_update_servers_by_server(server, user_data, backup_router);
3200 if (server->server_type == SILC_SERVER)
3201 silc_server_update_channels_by_server(server, user_data,
3204 /* Send notify about primary router going down to local operators */
3205 if (server->backup_router)
3206 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3207 SILC_NOTIFY_TYPE_NONE,
3208 ("%s switched to backup router %s "
3209 "(we are primary router now)",
3210 server->server_name, server->server_name));
3211 else if (server->router)
3212 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3213 SILC_NOTIFY_TYPE_NONE,
3214 ("%s switched to backup router %s",
3215 server->server_name,
3216 server->router->server_name));
3218 server->backup_noswitch = FALSE;
3221 silc_server_connection_free(idata->sconn);
3223 /* Free the server entry */
3224 silc_server_backup_del(server, user_data);
3225 silc_server_backup_replaced_del(server, user_data);
3226 silc_idlist_del_data(user_data);
3227 if (!silc_idlist_del_server(server->local_list, user_data))
3228 silc_idlist_del_server(server->global_list, user_data);
3229 if (idata->conn_type == SILC_CONN_SERVER) {
3230 server->stat.my_servers--;
3231 server->stat.servers--;
3233 server->stat.my_routers--;
3234 server->stat.routers--;
3236 if (server->server_type == SILC_ROUTER)
3237 server->stat.cell_servers--;
3239 if (backup_router && backup_router != server->id_entry) {
3240 /* Announce all of our stuff that was created about 5 minutes ago.
3241 The backup router knows all the other stuff already. */
3242 if (server->server_type == SILC_ROUTER)
3243 silc_server_announce_servers(server, FALSE, time(0) - 300,
3244 backup_router->connection);
3246 /* Announce our clients and channels to the router */
3247 silc_server_announce_clients(server, time(0) - 300,
3248 backup_router->connection);
3249 silc_server_announce_channels(server, time(0) - 300,
3250 backup_router->connection);
3253 silc_packet_set_context(sock, NULL);
3259 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3261 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3264 silc_server_connection_free(idata->sconn);
3265 silc_idlist_del_data(idata);
3267 silc_packet_set_context(sock, NULL);
3273 /* Removes client from all channels it has joined. This is used when client
3274 connection is disconnected. If the client on a channel is last, the
3275 channel is removed as well. This sends the SIGNOFF notify types. */
3277 void silc_server_remove_from_channels(SilcServer server,
3278 SilcPacketStream sock,
3279 SilcClientEntry client,
3281 const char *signoff_message,
3285 SilcChannelEntry channel;
3286 SilcChannelClientEntry chl;
3287 SilcHashTableList htl;
3288 SilcBuffer clidp = NULL;
3293 if (notify && !client->id)
3296 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3297 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3300 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3305 /* Remove the client from all channels. The client is removed from
3306 the channels' user list. */
3307 silc_hash_table_list(client->channels, &htl);
3308 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3309 channel = chl->channel;
3311 /* Remove channel if this is last client leaving the channel, unless
3312 the channel is permanent. */
3313 if (server->server_type != SILC_SERVER &&
3314 silc_hash_table_count(channel->user_list) < 2) {
3315 silc_server_channel_delete(server, channel);
3319 silc_hash_table_del(client->channels, channel);
3320 silc_hash_table_del(channel->user_list, client);
3321 channel->user_count--;
3323 /* If there is no global users on the channel anymore mark the channel
3324 as local channel. Do not check if the removed client is local client. */
3325 if (server->server_type == SILC_SERVER && channel->global_users &&
3326 chl->client->router && !silc_server_channel_has_global(channel))
3327 channel->global_users = FALSE;
3329 memset(chl, 'A', sizeof(*chl));
3332 /* Update statistics */
3333 if (SILC_IS_LOCAL(client))
3334 server->stat.my_chanclients--;
3335 if (server->server_type == SILC_ROUTER) {
3336 server->stat.cell_chanclients--;
3337 server->stat.chanclients--;
3340 /* If there is not at least one local user on the channel then we don't
3341 need the channel entry anymore, we can remove it safely, unless the
3342 channel is permanent channel */
3343 if (server->server_type == SILC_SERVER &&
3344 !silc_server_channel_has_local(channel)) {
3345 /* Notify about leaving client if this channel has global users. */
3346 if (notify && channel->global_users)
3347 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3348 SILC_NOTIFY_TYPE_SIGNOFF,
3349 signoff_message ? 2 : 1,
3350 clidp->data, silc_buffer_len(clidp),
3351 signoff_message, signoff_message ?
3352 strlen(signoff_message) : 0);
3354 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3355 silc_server_channel_delete(server, channel);
3359 /* Send notify to channel about client leaving SILC and channel too */
3361 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3362 SILC_NOTIFY_TYPE_SIGNOFF,
3363 signoff_message ? 2 : 1,
3364 clidp->data, silc_buffer_len(clidp),
3365 signoff_message, signoff_message ?
3366 strlen(signoff_message) : 0);
3368 if (killed && clidp) {
3369 /* Remove the client from channel's invite list */
3370 if (channel->invite_list &&
3371 silc_hash_table_count(channel->invite_list)) {
3373 SilcArgumentPayload iargs;
3374 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3375 silc_buffer_len(clidp), 3);
3376 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3377 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3378 silc_buffer_free(ab);
3379 silc_argument_payload_free(iargs);
3383 /* Don't create keys if we are shutting down */
3384 if (server->server_shutdown)
3387 /* Re-generate channel key if needed */
3388 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3389 if (!silc_server_create_channel_key(server, channel, 0))
3392 /* Send the channel key to the channel. The key of course is not sent
3393 to the client who was removed from the channel. */
3394 silc_server_send_channel_key(server, client->connection, channel,
3395 server->server_type == SILC_ROUTER ?
3396 FALSE : !server->standalone);
3400 silc_hash_table_list_reset(&htl);
3402 silc_buffer_free(clidp);
3405 /* Removes client from one channel. This is used for example when client
3406 calls LEAVE command to remove itself from the channel. Returns TRUE
3407 if channel still exists and FALSE if the channel is removed when
3408 last client leaves the channel. If `notify' is FALSE notify messages
3411 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3412 SilcPacketStream sock,
3413 SilcChannelEntry channel,
3414 SilcClientEntry client,
3417 SilcChannelClientEntry chl;
3420 SILC_LOG_DEBUG(("Removing %s from channel %s",
3421 silc_id_render(client->id, SILC_ID_CLIENT),
3422 channel->channel_name));
3424 /* Get the entry to the channel, if this client is not on the channel
3426 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3429 /* Remove channel if this is last client leaving the channel, unless
3430 the channel is permanent. */
3431 if (server->server_type != SILC_SERVER &&
3432 silc_hash_table_count(channel->user_list) < 2) {
3433 silc_server_channel_delete(server, channel);
3437 silc_hash_table_del(client->channels, channel);
3438 silc_hash_table_del(channel->user_list, client);
3439 channel->user_count--;
3441 /* If there is no global users on the channel anymore mark the channel
3442 as local channel. Do not check if the client is local client. */
3443 if (server->server_type == SILC_SERVER && channel->global_users &&
3444 chl->client->router && !silc_server_channel_has_global(channel))
3445 channel->global_users = FALSE;
3447 memset(chl, 'O', sizeof(*chl));
3450 /* Update statistics */
3451 if (SILC_IS_LOCAL(client))
3452 server->stat.my_chanclients--;
3453 if (server->server_type == SILC_ROUTER) {
3454 server->stat.cell_chanclients--;
3455 server->stat.chanclients--;
3458 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3462 /* If there is not at least one local user on the channel then we don't
3463 need the channel entry anymore, we can remove it safely, unless the
3464 channel is permanent channel */
3465 if (server->server_type == SILC_SERVER &&
3466 !silc_server_channel_has_local(channel)) {
3467 /* Notify about leaving client if this channel has global users. */
3468 if (notify && channel->global_users)
3469 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3470 SILC_NOTIFY_TYPE_LEAVE, 1,
3471 clidp->data, silc_buffer_len(clidp));
3473 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3474 silc_server_channel_delete(server, channel);
3475 silc_buffer_free(clidp);
3479 /* Send notify to channel about client leaving the channel */
3481 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3482 SILC_NOTIFY_TYPE_LEAVE, 1,
3483 clidp->data, silc_buffer_len(clidp));
3485 silc_buffer_free(clidp);
3489 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3490 function may be used only by router. In real SILC network all channels
3491 are created by routers thus this function is never used by normal
3494 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3495 SilcServerID *router_id,
3501 SilcChannelID *channel_id;
3502 SilcChannelEntry entry;
3503 SilcCipher send_key, receive_key;
3506 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3509 cipher = SILC_DEFAULT_CIPHER;
3511 hmac = SILC_DEFAULT_HMAC;
3513 /* Allocate cipher */
3514 if (!silc_cipher_alloc(cipher, &send_key))
3516 if (!silc_cipher_alloc(cipher, &receive_key)) {
3517 silc_cipher_free(send_key);
3522 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3523 silc_cipher_free(send_key);
3524 silc_cipher_free(receive_key);
3528 channel_name = strdup(channel_name);
3530 /* Create the channel ID */
3531 if (!silc_id_create_channel_id(server, router_id, server->rng,
3533 silc_free(channel_name);
3534 silc_cipher_free(send_key);
3535 silc_cipher_free(receive_key);
3536 silc_hmac_free(newhmac);
3540 /* Create the channel */
3541 entry = silc_idlist_add_channel(server->local_list, channel_name,
3542 SILC_CHANNEL_MODE_NONE, channel_id,
3543 NULL, send_key, receive_key, newhmac);
3545 silc_free(channel_name);
3546 silc_cipher_free(send_key);
3547 silc_cipher_free(receive_key);
3548 silc_hmac_free(newhmac);
3549 silc_free(channel_id);
3553 entry->cipher = strdup(cipher);
3554 entry->hmac_name = strdup(hmac);
3556 /* Now create the actual key material */
3557 if (!silc_server_create_channel_key(server, entry,
3558 silc_cipher_get_key_len(send_key) / 8)) {
3559 silc_idlist_del_channel(server->local_list, entry);
3563 /* Notify other routers about the new channel. We send the packet
3564 to our primary route. */
3566 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3567 channel_name, entry->id,
3568 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3571 /* Distribute to backup routers */
3572 if (broadcast && server->server_type == SILC_ROUTER) {
3574 unsigned char cid[32];
3575 SilcUInt32 name_len = strlen(channel_name);
3578 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3579 packet = silc_channel_payload_encode(channel_name, name_len,
3580 cid, id_len, entry->mode);
3581 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3582 packet->data, silc_buffer_len(packet), FALSE,
3584 silc_buffer_free(packet);
3587 server->stat.my_channels++;
3588 if (server->server_type == SILC_ROUTER) {
3589 server->stat.channels++;
3590 server->stat.cell_channels++;
3591 entry->users_resolved = TRUE;
3597 /* Same as above but creates the channel with Channel ID `channel_id. */
3600 silc_server_create_new_channel_with_id(SilcServer server,
3604 SilcChannelID *channel_id,
3607 SilcChannelEntry entry;
3608 SilcCipher send_key, receive_key;
3611 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3614 cipher = SILC_DEFAULT_CIPHER;
3616 hmac = SILC_DEFAULT_HMAC;
3618 /* Allocate cipher */
3619 if (!silc_cipher_alloc(cipher, &send_key))
3621 if (!silc_cipher_alloc(cipher, &receive_key)) {
3622 silc_cipher_free(send_key);
3627 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3628 silc_cipher_free(send_key);
3629 silc_cipher_free(receive_key);
3633 channel_name = strdup(channel_name);
3635 /* Create the channel */
3636 entry = silc_idlist_add_channel(server->local_list, channel_name,
3637 SILC_CHANNEL_MODE_NONE, channel_id,
3638 NULL, send_key, receive_key, newhmac);
3640 silc_cipher_free(send_key);
3641 silc_cipher_free(receive_key);
3642 silc_hmac_free(newhmac);
3643 silc_free(channel_name);
3647 /* Now create the actual key material */
3648 if (!silc_server_create_channel_key(server, entry,
3649 silc_cipher_get_key_len(send_key) / 8)) {
3650 silc_idlist_del_channel(server->local_list, entry);
3654 /* Notify other routers about the new channel. We send the packet
3655 to our primary route. */
3657 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3658 channel_name, entry->id,
3659 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3662 /* Distribute to backup routers */
3663 if (broadcast && server->server_type == SILC_ROUTER) {
3665 unsigned char cid[32];
3666 SilcUInt32 name_len = strlen(channel_name);
3669 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3670 packet = silc_channel_payload_encode(channel_name, name_len,
3671 cid, id_len, entry->mode);
3672 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3673 packet->data, silc_buffer_len(packet), FALSE,
3675 silc_buffer_free(packet);
3678 server->stat.my_channels++;
3679 if (server->server_type == SILC_ROUTER) {
3680 server->stat.channels++;
3681 server->stat.cell_channels++;
3682 entry->users_resolved = TRUE;
3688 /* Channel's key re-key timeout callback. */
3690 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3692 SilcServer server = app_context;
3693 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3697 /* Return now if we are shutting down */
3698 if (server->server_shutdown)
3701 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3704 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3707 /* Generates new channel key. This is used to create the initial channel key
3708 but also to re-generate new key for channel. If `key_len' is provided
3709 it is the bytes of the key length. */
3711 SilcBool silc_server_create_channel_key(SilcServer server,
3712 SilcChannelEntry channel,
3716 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3719 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3720 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3724 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3726 if (!channel->send_key)
3727 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3728 channel->send_key = NULL;
3731 if (!channel->receive_key)
3732 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3733 silc_cipher_free(channel->send_key);
3734 channel->send_key = channel->receive_key = NULL;
3740 else if (channel->key_len)
3741 len = channel->key_len / 8;
3743 len = silc_cipher_get_key_len(channel->send_key) / 8;
3745 /* Create channel key */
3746 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3749 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3750 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3752 /* Remove old key if exists */
3754 memset(channel->key, 0, channel->key_len / 8);
3755 silc_free(channel->key);
3759 channel->key_len = len * 8;
3760 channel->key = silc_memdup(channel_key, len);
3761 memset(channel_key, 0, sizeof(channel_key));
3763 /* Generate HMAC key from the channel key data and set it */
3765 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3766 memset(channel->key, 0, channel->key_len / 8);
3767 silc_free(channel->key);
3768 silc_cipher_free(channel->send_key);
3769 silc_cipher_free(channel->receive_key);
3770 channel->send_key = channel->receive_key = NULL;
3773 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3774 silc_hmac_set_key(channel->hmac, hash,
3775 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3776 memset(hash, 0, sizeof(hash));
3778 if (server->server_type == SILC_ROUTER) {
3779 if (!channel->rekey)
3780 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3781 channel->rekey->channel = channel;
3782 channel->rekey->key_len = key_len;
3783 if (channel->rekey->task)
3784 silc_schedule_task_del(server->schedule, channel->rekey->task);
3786 channel->rekey->task =
3787 silc_schedule_task_add_timeout(server->schedule,
3788 silc_server_channel_key_rekey,
3789 (void *)channel->rekey,
3790 server->config->channel_rekey_secs, 0);
3796 /* Saves the channel key found in the encoded `key_payload' buffer. This
3797 function is used when we receive Channel Key Payload and also when we're
3798 processing JOIN command reply. Returns entry to the channel. */
3800 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3801 SilcBuffer key_payload,
3802 SilcChannelEntry channel)
3804 SilcChannelKeyPayload payload = NULL;
3806 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3810 /* Decode channel key payload */
3811 payload = silc_channel_key_payload_parse(key_payload->data,
3812 silc_buffer_len(key_payload));
3814 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3819 /* Get the channel entry */
3822 /* Get channel ID */
3823 tmp = silc_channel_key_get_id(payload, &tmp_len);
3824 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3829 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3831 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3833 if (server->server_type == SILC_ROUTER)
3834 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3835 silc_id_render(&id, SILC_ID_CHANNEL)));
3841 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3843 tmp = silc_channel_key_get_key(payload, &tmp_len);
3849 cipher = silc_channel_key_get_cipher(payload, NULL);
3855 /* Remove old key if exists */
3857 memset(channel->key, 0, channel->key_len / 8);
3858 silc_free(channel->key);
3859 silc_cipher_free(channel->send_key);
3860 silc_cipher_free(channel->receive_key);
3863 /* Create new cipher */
3864 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3865 channel->send_key = NULL;
3869 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3870 silc_cipher_free(channel->send_key);
3871 channel->send_key = channel->receive_key = NULL;
3876 if (channel->cipher)
3877 silc_free(channel->cipher);
3878 channel->cipher = strdup(cipher);
3881 channel->key_len = tmp_len * 8;
3882 channel->key = silc_memdup(tmp, tmp_len);
3883 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3884 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3886 /* Generate HMAC key from the channel key data and set it */
3888 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3889 memset(channel->key, 0, channel->key_len / 8);
3890 silc_free(channel->key);
3891 silc_cipher_free(channel->send_key);
3892 silc_cipher_free(channel->receive_key);
3893 channel->send_key = channel->receive_key = NULL;
3896 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3897 silc_hmac_set_key(channel->hmac, hash,
3898 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3900 memset(hash, 0, sizeof(hash));
3901 memset(tmp, 0, tmp_len);
3903 if (server->server_type == SILC_ROUTER) {
3904 if (!channel->rekey)
3905 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3906 channel->rekey->channel = channel;
3907 if (channel->rekey->task)
3908 silc_schedule_task_del(server->schedule, channel->rekey->task);
3910 channel->rekey->task =
3911 silc_schedule_task_add_timeout(server->schedule,
3912 silc_server_channel_key_rekey,
3913 (void *)channel->rekey,
3914 server->config->channel_rekey_secs, 0);
3919 silc_channel_key_payload_free(payload);
3924 /* Returns assembled of all servers in the given ID list. The packet's
3925 form is dictated by the New ID payload. */
3927 static void silc_server_announce_get_servers(SilcServer server,
3928 SilcServerEntry remote,
3930 SilcBuffer *servers,
3931 unsigned long creation_time)
3934 SilcIDCacheEntry id_cache;
3935 SilcServerEntry entry;
3938 /* Go through all clients in the list */
3939 if (silc_idcache_get_all(id_list->servers, &list)) {
3940 silc_list_start(list);
3941 while ((id_cache = silc_list_get(list))) {
3942 entry = (SilcServerEntry)id_cache->context;
3944 /* Do not announce the one we've sending our announcements and
3945 do not announce ourself. Also check the creation time if it's
3947 if ((entry == remote) || (entry == server->id_entry) ||
3948 (creation_time && entry->data.created < creation_time))
3951 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3953 *servers = silc_buffer_realloc(*servers,
3955 silc_buffer_truelen((*servers)) +
3956 silc_buffer_len(idp) :
3957 silc_buffer_len(idp)));
3958 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3959 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3960 silc_buffer_pull(*servers, silc_buffer_len(idp));
3961 silc_buffer_free(idp);
3967 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3973 p = silc_notify_payload_encode(notify, argc, ap);
3979 /* This function is used by router to announce existing servers to our
3980 primary router when we've connected to it. If `creation_time' is non-zero
3981 then only the servers that has been created after the `creation_time'
3982 will be announced. */
3984 void silc_server_announce_servers(SilcServer server, SilcBool global,
3985 unsigned long creation_time,
3986 SilcPacketStream remote)
3988 SilcBuffer servers = NULL;
3990 SILC_LOG_DEBUG(("Announcing servers"));
3992 /* Get servers in local list */
3993 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3994 server->local_list, &servers,
3998 /* Get servers in global list */
3999 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4000 server->global_list, &servers,
4004 silc_buffer_push(servers, servers->data - servers->head);
4005 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4007 /* Send the packet */
4008 silc_server_packet_send(server, remote,
4009 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4010 servers->data, silc_buffer_len(servers));
4012 silc_buffer_free(servers);
4016 /* Returns assembled packet of all clients in the given ID list. The
4017 packet's form is dictated by the New ID Payload. */
4019 static void silc_server_announce_get_clients(SilcServer server,
4021 SilcBuffer *clients,
4023 unsigned long creation_time)
4026 SilcIDCacheEntry id_cache;
4027 SilcClientEntry client;
4030 unsigned char mode[4];
4032 /* Go through all clients in the list */
4033 if (silc_idcache_get_all(id_list->clients, &list)) {
4034 silc_list_start(list);
4035 while ((id_cache = silc_list_get(list))) {
4036 client = (SilcClientEntry)id_cache->context;
4038 if (creation_time && client->data.created < creation_time)
4040 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4042 if (!client->connection && !client->router)
4045 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4047 *clients = silc_buffer_realloc(*clients,
4049 silc_buffer_truelen((*clients)) +
4050 silc_buffer_len(idp) :
4051 silc_buffer_len(idp)));
4052 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4053 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4054 silc_buffer_pull(*clients, silc_buffer_len(idp));
4056 SILC_PUT32_MSB(client->mode, mode);
4058 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4059 2, idp->data, silc_buffer_len(idp),
4061 *umodes = silc_buffer_realloc(*umodes,
4063 silc_buffer_truelen((*umodes)) +
4064 silc_buffer_len(tmp) :
4065 silc_buffer_len(tmp)));
4066 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4067 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4068 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4069 silc_buffer_free(tmp);
4071 silc_buffer_free(idp);
4076 /* This function is used to announce our existing clients to our router
4077 when we've connected to it. If `creation_time' is non-zero then only
4078 the clients that has been created after the `creation_time' will be
4081 void silc_server_announce_clients(SilcServer server,
4082 unsigned long creation_time,
4083 SilcPacketStream remote)
4085 SilcBuffer clients = NULL;
4086 SilcBuffer umodes = NULL;
4088 SILC_LOG_DEBUG(("Announcing clients"));
4090 /* Get clients in local list */
4091 silc_server_announce_get_clients(server, server->local_list,
4092 &clients, &umodes, creation_time);
4094 /* As router we announce our global list as well */
4095 if (server->server_type == SILC_ROUTER)
4096 silc_server_announce_get_clients(server, server->global_list,
4097 &clients, &umodes, creation_time);
4100 silc_buffer_push(clients, clients->data - clients->head);
4101 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4103 /* Send the packet */
4104 silc_server_packet_send(server, remote,
4105 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4106 clients->data, silc_buffer_len(clients));
4108 silc_buffer_free(clients);
4112 silc_buffer_push(umodes, umodes->data - umodes->head);
4113 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4115 /* Send the packet */
4116 silc_server_packet_send(server, remote,
4117 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4118 umodes->data, silc_buffer_len(umodes));
4120 silc_buffer_free(umodes);
4124 /* Returns channel's topic for announcing it */
4126 void silc_server_announce_get_channel_topic(SilcServer server,
4127 SilcChannelEntry channel,
4132 if (channel->topic) {
4133 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4134 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4136 silc_buffer_len(chidp),
4138 strlen(channel->topic));
4139 silc_buffer_free(chidp);
4143 /* Returns channel's invite and ban lists */
4145 void silc_server_announce_get_inviteban(SilcServer server,
4146 SilcChannelEntry channel,
4150 SilcBuffer list, idp, idp2, tmp2;
4152 SilcHashTableList htl;
4153 const unsigned char a[1] = { 0x03 };
4155 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4157 /* Encode invite list */
4158 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4159 list = silc_buffer_alloc_size(2);
4160 type = silc_hash_table_count(channel->invite_list);
4161 SILC_PUT16_MSB(type, list->data);
4162 silc_hash_table_list(channel->invite_list, &htl);
4163 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4164 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4166 silc_hash_table_list_reset(&htl);
4168 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4170 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4171 idp->data, silc_buffer_len(idp),
4172 channel->channel_name,
4173 strlen(channel->channel_name),
4174 idp2->data, silc_buffer_len(idp2),
4176 list->data, silc_buffer_len(list));
4177 silc_buffer_free(idp2);
4178 silc_buffer_free(list);
4181 /* Encode ban list */
4182 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4183 list = silc_buffer_alloc_size(2);
4184 type = silc_hash_table_count(channel->ban_list);
4185 SILC_PUT16_MSB(type, list->data);
4186 silc_hash_table_list(channel->ban_list, &htl);
4187 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4188 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4190 silc_hash_table_list_reset(&htl);
4193 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4194 idp->data, silc_buffer_len(idp),
4196 list->data, silc_buffer_len(list));
4197 silc_buffer_free(list);
4200 silc_buffer_free(idp);
4203 /* Returns assembled packets for channel users of the `channel'. */
4205 void silc_server_announce_get_channel_users(SilcServer server,
4206 SilcChannelEntry channel,
4207 SilcBuffer *channel_modes,
4208 SilcBuffer *channel_users,
4209 SilcBuffer *channel_users_modes)
4211 SilcChannelClientEntry chl;
4212 SilcHashTableList htl;
4213 SilcBuffer chidp, clidp, csidp;
4214 SilcBuffer tmp, fkey = NULL, chpklist;
4216 unsigned char mode[4], ulimit[4];
4219 SILC_LOG_DEBUG(("Start"));
4221 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4222 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4223 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4226 SILC_PUT32_MSB(channel->mode, mode);
4227 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4228 SILC_PUT32_MSB(channel->user_limit, ulimit);
4229 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4230 if (channel->founder_key)
4231 fkey = silc_public_key_payload_encode(channel->founder_key);
4233 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4235 silc_buffer_len(csidp),
4238 hmac, hmac ? strlen(hmac) : 0,
4239 channel->passphrase,
4240 channel->passphrase ?
4241 strlen(channel->passphrase) : 0,
4242 fkey ? fkey->data : NULL,
4243 fkey ? silc_buffer_len(fkey) : 0,
4244 chpklist ? chpklist->data : NULL,
4246 silc_buffer_len(chpklist) : 0,
4248 SILC_CHANNEL_MODE_ULIMIT ?
4251 SILC_CHANNEL_MODE_ULIMIT ?
4252 sizeof(ulimit) : 0));
4253 len = silc_buffer_len(tmp);
4255 silc_buffer_realloc(*channel_modes,
4257 silc_buffer_truelen((*channel_modes)) + len : len));
4258 silc_buffer_pull_tail(*channel_modes,
4259 ((*channel_modes)->end -
4260 (*channel_modes)->data));
4261 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4262 silc_buffer_pull(*channel_modes, len);
4263 silc_buffer_free(tmp);
4264 silc_buffer_free(fkey);
4267 /* Now find all users on the channel */
4268 silc_hash_table_list(channel->user_list, &htl);
4269 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4270 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4273 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4275 silc_buffer_len(clidp),
4277 silc_buffer_len(chidp));
4278 len = silc_buffer_len(tmp);
4280 silc_buffer_realloc(*channel_users,
4282 silc_buffer_truelen((*channel_users)) + len : len));
4283 silc_buffer_pull_tail(*channel_users,
4284 ((*channel_users)->end -
4285 (*channel_users)->data));
4287 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4288 silc_buffer_pull(*channel_users, len);
4289 silc_buffer_free(tmp);
4291 /* CUMODE notify for mode change on the channel */
4292 SILC_PUT32_MSB(chl->mode, mode);
4293 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4294 fkey = silc_public_key_payload_encode(channel->founder_key);
4295 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4297 silc_buffer_len(csidp),
4300 silc_buffer_len(clidp),
4301 fkey ? fkey->data : NULL,
4302 fkey ? silc_buffer_len(fkey) : 0);
4303 len = silc_buffer_len(tmp);
4304 *channel_users_modes =
4305 silc_buffer_realloc(*channel_users_modes,
4306 (*channel_users_modes ?
4307 silc_buffer_truelen((*channel_users_modes)) +
4309 silc_buffer_pull_tail(*channel_users_modes,
4310 ((*channel_users_modes)->end -
4311 (*channel_users_modes)->data));
4313 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4314 silc_buffer_pull(*channel_users_modes, len);
4315 silc_buffer_free(tmp);
4316 silc_buffer_free(fkey);
4318 silc_buffer_free(clidp);
4320 silc_hash_table_list_reset(&htl);
4321 silc_buffer_free(chidp);
4322 silc_buffer_free(csidp);
4325 /* Returns assembled packets for all channels and users on those channels
4326 from the given ID List. The packets are in the form dictated by the
4327 New Channel and New Channel User payloads. */
4329 void silc_server_announce_get_channels(SilcServer server,
4331 SilcBuffer *channels,
4332 SilcBuffer **channel_modes,
4333 SilcBuffer *channel_users,
4334 SilcBuffer **channel_users_modes,
4335 SilcUInt32 *channel_users_modes_c,
4336 SilcBuffer **channel_topics,
4337 SilcBuffer **channel_invites,
4338 SilcBuffer **channel_bans,
4339 SilcChannelID ***channel_ids,
4340 unsigned long creation_time)
4343 SilcIDCacheEntry id_cache;
4344 SilcChannelEntry channel;
4345 unsigned char cid[32];
4347 SilcUInt16 name_len;
4349 int i = *channel_users_modes_c;
4352 SILC_LOG_DEBUG(("Start"));
4354 /* Go through all channels in the list */
4355 if (silc_idcache_get_all(id_list->channels, &list)) {
4356 silc_list_start(list);
4357 while ((id_cache = silc_list_get(list))) {
4358 channel = (SilcChannelEntry)id_cache->context;
4360 if (creation_time && channel->created < creation_time)
4365 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4366 name_len = strlen(channel->channel_name);
4369 len = 4 + name_len + id_len + 4;
4371 silc_buffer_realloc(*channels,
4373 silc_buffer_truelen((*channels)) +
4375 silc_buffer_pull_tail(*channels,
4376 ((*channels)->end - (*channels)->data));
4377 silc_buffer_format(*channels,
4378 SILC_STR_UI_SHORT(name_len),
4379 SILC_STR_UI_XNSTRING(channel->channel_name,
4381 SILC_STR_UI_SHORT(id_len),
4382 SILC_STR_UI_XNSTRING(cid, id_len),
4383 SILC_STR_UI_INT(channel->mode),
4385 silc_buffer_pull(*channels, len);
4388 if (creation_time && channel->updated < creation_time)
4394 /* Channel user modes */
4395 *channel_users_modes = silc_realloc(*channel_users_modes,
4396 sizeof(**channel_users_modes) *
4398 (*channel_users_modes)[i] = NULL;
4399 *channel_modes = silc_realloc(*channel_modes,
4400 sizeof(**channel_modes) * (i + 1));
4401 (*channel_modes)[i] = NULL;
4402 *channel_ids = silc_realloc(*channel_ids,
4403 sizeof(**channel_ids) * (i + 1));
4404 (*channel_ids)[i] = NULL;
4405 silc_server_announce_get_channel_users(server, channel,
4406 &(*channel_modes)[i],
4408 &(*channel_users_modes)[i]);
4409 (*channel_ids)[i] = channel->id;
4411 /* Channel's topic */
4412 *channel_topics = silc_realloc(*channel_topics,
4413 sizeof(**channel_topics) * (i + 1));
4414 (*channel_topics)[i] = NULL;
4415 silc_server_announce_get_channel_topic(server, channel,
4416 &(*channel_topics)[i]);
4418 /* Channel's invite and ban list */
4419 *channel_invites = silc_realloc(*channel_invites,
4420 sizeof(**channel_invites) * (i + 1));
4421 (*channel_invites)[i] = NULL;
4422 *channel_bans = silc_realloc(*channel_bans,
4423 sizeof(**channel_bans) * (i + 1));
4424 (*channel_bans)[i] = NULL;
4425 silc_server_announce_get_inviteban(server, channel,
4426 &(*channel_invites)[i],
4427 &(*channel_bans)[i]);
4429 (*channel_users_modes_c)++;
4437 /* This function is used to announce our existing channels to our router
4438 when we've connected to it. This also announces the users on the
4439 channels to the router. If the `creation_time' is non-zero only the
4440 channels that was created after the `creation_time' are announced.
4441 Note that the channel users are still announced even if the `creation_time'
4444 void silc_server_announce_channels(SilcServer server,
4445 unsigned long creation_time,
4446 SilcPacketStream remote)
4448 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4449 SilcBuffer *channel_users_modes = NULL;
4450 SilcBuffer *channel_topics = NULL;
4451 SilcBuffer *channel_invites = NULL;
4452 SilcBuffer *channel_bans = NULL;
4453 SilcUInt32 channel_users_modes_c = 0;
4454 SilcChannelID **channel_ids = NULL;
4456 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4458 /* Get channels and channel users in local list */
4459 silc_server_announce_get_channels(server, server->local_list,
4460 &channels, &channel_modes,
4462 &channel_users_modes,
4463 &channel_users_modes_c,
4467 &channel_ids, creation_time);
4469 /* Get channels and channel users in global list */
4470 if (server->server_type != SILC_SERVER)
4471 silc_server_announce_get_channels(server, server->global_list,
4472 &channels, &channel_modes,
4474 &channel_users_modes,
4475 &channel_users_modes_c,
4479 &channel_ids, creation_time);
4482 silc_buffer_push(channels, channels->data - channels->head);
4483 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4485 /* Send the packet */
4486 silc_server_packet_send(server, remote,
4487 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4488 channels->data, silc_buffer_len(channels));
4490 silc_buffer_free(channels);
4493 if (channel_users) {
4494 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4495 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4496 silc_buffer_len(channel_users));
4498 /* Send the packet */
4499 silc_server_packet_send(server, remote,
4500 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4501 channel_users->data, silc_buffer_len(channel_users));
4503 silc_buffer_free(channel_users);
4506 if (channel_modes) {
4509 for (i = 0; i < channel_users_modes_c; i++) {
4510 if (!channel_modes[i])
4512 silc_buffer_push(channel_modes[i],
4513 channel_modes[i]->data -
4514 channel_modes[i]->head);
4515 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4516 silc_buffer_len(channel_modes[i]));
4517 silc_server_packet_send_dest(server, remote,
4518 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4519 channel_ids[i], SILC_ID_CHANNEL,
4520 channel_modes[i]->data,
4521 silc_buffer_len(channel_modes[i]));
4522 silc_buffer_free(channel_modes[i]);
4524 silc_free(channel_modes);
4527 if (channel_users_modes) {
4530 for (i = 0; i < channel_users_modes_c; i++) {
4531 if (!channel_users_modes[i])
4533 silc_buffer_push(channel_users_modes[i],
4534 channel_users_modes[i]->data -
4535 channel_users_modes[i]->head);
4536 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4537 silc_buffer_len(channel_users_modes[i]));
4538 silc_server_packet_send_dest(server, remote,
4539 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4540 channel_ids[i], SILC_ID_CHANNEL,
4541 channel_users_modes[i]->data,
4542 silc_buffer_len(channel_users_modes[i]));
4543 silc_buffer_free(channel_users_modes[i]);
4545 silc_free(channel_users_modes);
4548 if (channel_topics) {
4551 for (i = 0; i < channel_users_modes_c; i++) {
4552 if (!channel_topics[i])
4555 silc_buffer_push(channel_topics[i],
4556 channel_topics[i]->data -
4557 channel_topics[i]->head);
4558 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4559 silc_buffer_len(channel_topics[i]));
4560 silc_server_packet_send_dest(server, remote,
4561 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4562 channel_ids[i], SILC_ID_CHANNEL,
4563 channel_topics[i]->data,
4564 silc_buffer_len(channel_topics[i]));
4565 silc_buffer_free(channel_topics[i]);
4567 silc_free(channel_topics);
4570 if (channel_invites) {
4573 for (i = 0; i < channel_users_modes_c; i++) {
4574 if (!channel_invites[i])
4577 silc_buffer_push(channel_invites[i],
4578 channel_invites[i]->data -
4579 channel_invites[i]->head);
4580 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4581 silc_buffer_len(channel_invites[i]));
4582 silc_server_packet_send_dest(server, remote,
4583 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4584 channel_ids[i], SILC_ID_CHANNEL,
4585 channel_invites[i]->data,
4586 silc_buffer_len(channel_invites[i]));
4587 silc_buffer_free(channel_invites[i]);
4589 silc_free(channel_invites);
4595 for (i = 0; i < channel_users_modes_c; i++) {
4596 if (!channel_bans[i])
4599 silc_buffer_push(channel_bans[i],
4600 channel_bans[i]->data -
4601 channel_bans[i]->head);
4602 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4603 silc_buffer_len(channel_bans[i]));
4604 silc_server_packet_send_dest(server, remote,
4605 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4606 channel_ids[i], SILC_ID_CHANNEL,
4607 channel_bans[i]->data,
4608 silc_buffer_len(channel_bans[i]));
4609 silc_buffer_free(channel_bans[i]);
4611 silc_free(channel_bans);
4614 silc_free(channel_ids);
4617 /* Announces WATCH list. */
4619 void silc_server_announce_watches(SilcServer server,
4620 SilcPacketStream remote)
4622 SilcHashTableList htl;
4623 SilcBuffer buffer, idp, args, pkp;
4624 SilcClientEntry client;
4627 SILC_LOG_DEBUG(("Announcing watch list"));
4629 /* XXX because way we save the nicks (hash) we cannot announce them. */
4631 /* XXX we should send all public keys in one command if client is
4632 watching more than one key */
4633 silc_hash_table_list(server->watcher_list_pk, &htl);
4634 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4635 if (!client || !client->id)
4638 server->stat.commands_sent++;
4640 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4641 args = silc_buffer_alloc_size(2);
4642 silc_buffer_format(args,
4643 SILC_STR_UI_SHORT(1),
4645 pkp = silc_public_key_payload_encode(key);
4646 args = silc_argument_payload_encode_one(args, pkp->data,
4647 silc_buffer_len(pkp), 0x00);
4648 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4649 ++server->cmd_ident, 2,
4650 1, idp->data, silc_buffer_len(idp),
4652 silc_buffer_len(args));
4655 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4656 buffer->data, silc_buffer_len(buffer));
4658 silc_buffer_free(pkp);
4659 silc_buffer_free(args);
4660 silc_buffer_free(idp);
4661 silc_buffer_free(buffer);
4663 silc_hash_table_list_reset(&htl);
4666 /* Assembles user list and users mode list from the `channel'. */
4668 SilcBool silc_server_get_users_on_channel(SilcServer server,
4669 SilcChannelEntry channel,
4670 SilcBuffer *user_list,
4671 SilcBuffer *mode_list,
4672 SilcUInt32 *user_count)
4674 SilcChannelClientEntry chl;
4675 SilcHashTableList htl;
4676 SilcBuffer client_id_list;
4677 SilcBuffer client_mode_list;
4679 SilcUInt32 list_count = 0, len = 0;
4681 if (!silc_hash_table_count(channel->user_list))
4684 silc_hash_table_list(channel->user_list, &htl);
4685 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4686 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4687 silc_hash_table_list_reset(&htl);
4689 client_id_list = silc_buffer_alloc(len);
4691 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4692 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4693 silc_buffer_pull_tail(client_mode_list,
4694 silc_buffer_truelen(client_mode_list));
4696 silc_hash_table_list(channel->user_list, &htl);
4697 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4699 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4700 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4701 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4702 silc_buffer_free(idp);
4704 /* Client's mode on channel */
4705 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4706 silc_buffer_pull(client_mode_list, 4);
4710 silc_hash_table_list_reset(&htl);
4711 silc_buffer_push(client_id_list,
4712 client_id_list->data - client_id_list->head);
4713 silc_buffer_push(client_mode_list,
4714 client_mode_list->data - client_mode_list->head);
4716 *user_list = client_id_list;
4717 *mode_list = client_mode_list;
4718 *user_count = list_count;
4722 /* Saves users and their modes to the `channel'. */
4724 void silc_server_save_users_on_channel(SilcServer server,
4725 SilcPacketStream sock,
4726 SilcChannelEntry channel,
4727 SilcClientID *noadd,
4728 SilcBuffer user_list,
4729 SilcBuffer mode_list,
4730 SilcUInt32 user_count)
4736 SilcClientEntry client;
4737 SilcIDCacheEntry cache;
4738 SilcChannelClientEntry chl;
4740 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4741 channel->channel_name));
4743 for (i = 0; i < user_count; i++) {
4745 SILC_GET16_MSB(idp_len, user_list->data + 2);
4747 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4749 silc_buffer_pull(user_list, idp_len);
4752 SILC_GET32_MSB(mode, mode_list->data);
4753 silc_buffer_pull(mode_list, 4);
4755 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4760 /* Check if we have this client cached already. */
4761 client = silc_idlist_find_client_by_id(server->local_list,
4763 server->server_type, &cache);
4765 client = silc_idlist_find_client_by_id(server->global_list,
4767 server->server_type, &cache);
4769 /* If router did not find such Client ID in its lists then this must
4770 be bogus client or some router in the net is buggy. */
4771 if (server->server_type != SILC_SERVER)
4774 /* We don't have that client anywhere, add it. The client is added
4775 to global list since server didn't have it in the lists so it must be
4777 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4778 silc_id_dup(&id.u.client_id,
4780 silc_packet_get_context(sock),
4783 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4787 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4790 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4791 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4792 "%s", channel->channel_name));
4796 if (!silc_server_client_on_channel(client, channel, &chl)) {
4797 /* Client was not on the channel, add it. */
4798 chl = silc_calloc(1, sizeof(*chl));
4799 chl->client = client;
4801 chl->channel = channel;
4802 silc_hash_table_add(channel->user_list, chl->client, chl);
4803 silc_hash_table_add(client->channels, chl->channel, chl);
4804 channel->user_count++;
4812 /* Saves channels and channels user modes to the `client'. Removes
4813 the client from those channels that are not sent in the list but
4816 void silc_server_save_user_channels(SilcServer server,
4817 SilcPacketStream sock,
4818 SilcClientEntry client,
4819 SilcBuffer channels,
4820 SilcBuffer channels_user_modes)
4823 SilcUInt32 *chumodes;
4824 SilcChannelPayload entry;
4825 SilcChannelEntry channel;
4826 SilcChannelID channel_id;
4827 SilcChannelClientEntry chl;
4828 SilcHashTable ht = NULL;
4829 SilcHashTableList htl;
4833 if (!channels || !channels_user_modes ||
4834 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4837 ch = silc_channel_payload_parse_list(channels->data,
4838 silc_buffer_len(channels));
4839 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4841 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4842 NULL, NULL, NULL, TRUE);
4843 silc_dlist_start(ch);
4844 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4845 /* Check if we have this channel, and add it if we don't have it.
4846 Also add the client on the channel unless it is there already. */
4847 if (!silc_channel_get_id_parse(entry, &channel_id))
4849 channel = silc_idlist_find_channel_by_id(server->local_list,
4852 channel = silc_idlist_find_channel_by_id(server->global_list,
4855 if (server->server_type != SILC_SERVER) {
4860 /* We don't have that channel anywhere, add it. */
4861 name = silc_channel_get_name(entry, NULL);
4862 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4863 silc_id_dup(&channel_id,
4865 server->router, NULL, NULL, 0);
4872 channel->mode = silc_channel_get_mode(entry);
4874 /* Add the client on the channel */
4875 if (!silc_server_client_on_channel(client, channel, &chl)) {
4876 chl = silc_calloc(1, sizeof(*chl));
4877 chl->client = client;
4878 chl->mode = chumodes[i++];
4879 chl->channel = channel;
4880 silc_hash_table_add(channel->user_list, chl->client, chl);
4881 silc_hash_table_add(client->channels, chl->channel, chl);
4882 channel->user_count++;
4885 chl->mode = chumodes[i++];
4888 silc_hash_table_add(ht, channel, channel);
4890 silc_channel_payload_list_free(ch);
4891 silc_free(chumodes);
4895 /* Go through the list again and remove client from channels that
4896 are no part of the list. */
4898 silc_hash_table_list(client->channels, &htl);
4899 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4900 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4901 silc_hash_table_del(chl->channel->user_list, chl->client);
4902 silc_hash_table_del(chl->client->channels, chl->channel);
4906 silc_hash_table_list_reset(&htl);
4907 silc_hash_table_free(ht);
4909 silc_hash_table_list(client->channels, &htl);
4910 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4911 silc_hash_table_del(chl->channel->user_list, chl->client);
4912 silc_hash_table_del(chl->client->channels, chl->channel);
4915 silc_hash_table_list_reset(&htl);
4919 /* Lookups route to the client indicated by the `id_data'. The connection
4920 object and internal data object is returned. Returns NULL if route
4921 could not be found to the client. If the `client_id' is specified then
4922 it is used and the `id_data' is ignored. */
4925 silc_server_get_client_route(SilcServer server,
4926 unsigned char *id_data,
4928 SilcClientID *client_id,
4929 SilcIDListData *idata,
4930 SilcClientEntry *client_entry)
4932 SilcClientID *id, clid;
4933 SilcClientEntry client;
4935 SILC_LOG_DEBUG(("Start"));
4938 *client_entry = NULL;
4940 /* Decode destination Client ID */
4942 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
4944 id = silc_id_dup(&clid, SILC_ID_CLIENT);
4946 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4949 /* If the destination belongs to our server we don't have to route
4950 the packet anywhere but to send it to the local destination. */
4951 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4955 /* If we are router and the client has router then the client is in
4956 our cell but not directly connected to us. */
4957 if (server->server_type == SILC_ROUTER && client->router) {
4958 /* We are of course in this case the client's router thus the route
4959 to the client is the server who owns the client. So, we will send
4960 the packet to that server. */
4962 *idata = (SilcIDListData)client->router;
4963 return client->router->connection;
4966 /* Seems that client really is directly connected to us */
4968 *idata = (SilcIDListData)client;
4970 *client_entry = client;
4971 return client->connection;
4974 /* Destination belongs to someone not in this server. If we are normal
4975 server our action is to send the packet to our router. */
4976 if (server->server_type != SILC_ROUTER && !server->standalone) {
4979 *idata = (SilcIDListData)server->router;
4980 return SILC_PRIMARY_ROUTE(server);
4983 /* We are router and we will perform route lookup for the destination
4984 and send the packet to fastest route. */
4985 if (server->server_type == SILC_ROUTER && !server->standalone) {
4986 /* Check first that the ID is valid */
4987 client = silc_idlist_find_client_by_id(server->global_list, id,
4990 SilcPacketStream dst_sock;
4992 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4995 if (idata && dst_sock)
4996 *idata = silc_packet_get_context(dst_sock);
5005 /* Encodes and returns channel list of channels the `client' has joined.
5006 Secret channels are not put to the list. */
5008 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5009 SilcClientEntry client,
5010 SilcBool get_private,
5011 SilcBool get_secret,
5012 SilcBuffer *user_mode_list)
5014 SilcBuffer buffer = NULL;
5015 SilcChannelEntry channel;
5016 SilcChannelClientEntry chl;
5017 SilcHashTableList htl;
5018 unsigned char cid[32];
5020 SilcUInt16 name_len;
5024 *user_mode_list = NULL;
5026 silc_hash_table_list(client->channels, &htl);
5027 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5028 channel = chl->channel;
5030 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5032 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5035 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5036 name_len = strlen(channel->channel_name);
5038 len = 4 + name_len + id_len + 4;
5039 buffer = silc_buffer_realloc(buffer,
5041 silc_buffer_truelen(buffer) + len : len));
5042 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5043 silc_buffer_format(buffer,
5044 SILC_STR_UI_SHORT(name_len),
5045 SILC_STR_DATA(channel->channel_name, name_len),
5046 SILC_STR_UI_SHORT(id_len),
5047 SILC_STR_DATA(cid, id_len),
5048 SILC_STR_UI_INT(chl->channel->mode),
5050 silc_buffer_pull(buffer, len);
5052 if (user_mode_list) {
5054 silc_buffer_realloc(*user_mode_list,
5056 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5057 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5058 (*user_mode_list)->data));
5059 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5060 silc_buffer_pull(*user_mode_list, 4);
5063 silc_hash_table_list_reset(&htl);
5066 silc_buffer_push(buffer, buffer->data - buffer->head);
5067 if (user_mode_list && *user_mode_list)
5068 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5069 (*user_mode_list)->head));
5074 /* Task callback used to retrieve network statistical information from
5075 router server once in a while. */
5077 SILC_TASK_CALLBACK(silc_server_get_stats)
5079 SilcServer server = (SilcServer)context;
5080 SilcBuffer idp, packet;
5082 if (!server->standalone) {
5083 SILC_LOG_DEBUG(("Retrieving stats from router"));
5084 server->stat.commands_sent++;
5085 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5087 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5088 ++server->cmd_ident, 1,
5090 silc_buffer_len(idp));
5091 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5092 SILC_PACKET_COMMAND, 0, packet->data,
5093 silc_buffer_len(packet));
5094 silc_buffer_free(packet);
5095 silc_buffer_free(idp);
5099 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,