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;
82 /* Packets we do not handle */
83 switch (packet->type) {
84 case SILC_PACKET_HEARTBEAT:
85 case SILC_PACKET_SUCCESS:
86 case SILC_PACKET_FAILURE:
87 case SILC_PACKET_REJECT:
88 case SILC_PACKET_KEY_EXCHANGE:
89 case SILC_PACKET_KEY_EXCHANGE_1:
90 case SILC_PACKET_KEY_EXCHANGE_2:
91 case SILC_PACKET_REKEY_DONE:
92 case SILC_PACKET_CONNECTION_AUTH:
97 /* Only specific packets can come without source ID present. */
98 if ((!packet->src_id ||
99 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
100 packet->type != SILC_PACKET_NEW_CLIENT &&
101 packet->type != SILC_PACKET_NEW_SERVER &&
102 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
103 packet->type != SILC_PACKET_DISCONNECT)
106 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID
107 and for unregistered connection. */
108 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
109 packet->type == SILC_PACKET_NEW_SERVER) &&
110 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
113 /* Ignore packets from disabled connection */
114 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
115 packet->type != SILC_PACKET_HEARTBEAT &&
116 packet->type != SILC_PACKET_RESUME_ROUTER &&
117 packet->type != SILC_PACKET_REKEY)
120 /* Check that the the current client ID is same as in the client's packet. */
121 if (idata->conn_type == SILC_CONN_CLIENT) {
122 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
123 SilcClientID client_id;
125 if (client->id && packet->src_id &&
126 silc_id_str2id(packet->src_id, packet->src_id_len,
127 packet->src_id_type, &client_id, sizeof(client_id))) {
128 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
129 SILC_LOG_DEBUG(("Packet source is not same as sender"));
135 if (server->server_type == SILC_ROUTER) {
136 /* Route the packet if it is not destined to us. Other ID types but
137 server are handled separately after processing them. */
138 if (packet->dst_id &&
139 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
140 packet->dst_id_type == SILC_ID_SERVER &&
141 idata->conn_type != SILC_CONN_CLIENT &&
142 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
143 SilcPacketStream conn;
144 SilcServerID server_id;
146 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
147 &server_id, sizeof(server_id));
149 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
151 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
152 silc_id_render(&server_id, SILC_ID_SERVER)));
156 silc_server_packet_route(server, conn, packet);
157 silc_packet_free(packet);
162 /* Broadcast packet if it is marked as broadcast packet and it is
163 originated from router and we are router. */
164 if (server->server_type == SILC_ROUTER &&
165 idata->conn_type == SILC_CONN_ROUTER &&
166 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
167 /* Broadcast to our primary route */
168 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
170 /* If we have backup routers then we need to feed all broadcast
171 data to those servers. */
172 silc_server_backup_broadcast(server, stream, packet);
176 silc_server_packet_parse_type(server, stream, packet);
181 /* Packet engine callback to indicate end of stream */
183 static void silc_server_packet_eos(SilcPacketEngine engine,
184 SilcPacketStream stream,
185 void *callback_context,
186 void *stream_context)
188 SilcServer server = callback_context;
189 SilcIDListData idata = silc_packet_get_context(stream);
191 SILC_LOG_DEBUG(("End of stream received"));
196 if (server->router_conn && server->router_conn->sock == stream &&
197 !server->router && server->standalone) {
198 silc_server_create_connections(server);
200 /* If backup disconnected then mark that resuming will not be allowed */
201 if (server->server_type == SILC_ROUTER && !server->backup_router &&
202 idata->conn_type == SILC_CONN_SERVER) {
203 SilcServerEntry server_entry = (SilcServerEntry)idata;
204 if (server_entry->server_type == SILC_BACKUP_ROUTER)
205 server->backup_closed = TRUE;
208 silc_server_free_sock_user_data(server, stream, NULL);
211 silc_server_close_connection(server, stream);
214 /* Packet engine callback to indicate error */
216 static void silc_server_packet_error(SilcPacketEngine engine,
217 SilcPacketStream stream,
218 SilcPacketError error,
219 void *callback_context,
220 void *stream_context)
222 SilcServer server = callback_context;
223 SilcIDListData idata = silc_packet_get_context(stream);
224 SilcStream sock = silc_packet_stream_get_stream(stream);
231 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
234 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
235 SILC_CONNTYPE_STRING(idata->conn_type),
236 silc_packet_error_string(error)));
238 if (server->router_conn && server->router_conn->sock == stream &&
239 !server->router && server->standalone) {
240 silc_server_create_connections(server);
242 /* If backup disconnected then mark that resuming will not be allowed */
243 if (server->server_type == SILC_ROUTER && !server->backup_router &&
244 idata->conn_type == SILC_CONN_SERVER) {
245 SilcServerEntry server_entry = (SilcServerEntry)idata;
246 if (server_entry->server_type == SILC_BACKUP_ROUTER)
247 server->backup_closed = TRUE;
250 silc_server_free_sock_user_data(server, stream, NULL);
253 silc_server_close_connection(server, stream);
256 /* Packet stream callbacks */
257 static SilcPacketCallbacks silc_server_stream_cbs =
259 silc_server_packet_receive,
260 silc_server_packet_eos,
261 silc_server_packet_error
264 /* Parses the packet type and calls what ever routines the packet type
265 requires. This is done for all incoming packets. */
267 static void silc_server_packet_parse_type(SilcServer server,
268 SilcPacketStream sock,
271 SilcPacketType type = packet->type;
272 SilcIDListData idata = silc_packet_get_context(sock);
274 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
275 silc_get_packet_name(type), packet->flags));
277 /* Parse the packet type */
279 case SILC_PACKET_NOTIFY:
281 * Received notify packet. Server can receive notify packets from
282 * router. Server then relays the notify messages to clients if needed.
284 if (packet->flags & SILC_PACKET_FLAG_LIST)
285 silc_server_notify_list(server, sock, packet);
287 silc_server_notify(server, sock, packet);
291 * Private Message packets
293 case SILC_PACKET_PRIVATE_MESSAGE:
295 * Received private message packet. The packet is coming from either
298 if (packet->flags & SILC_PACKET_FLAG_LIST)
300 idata->last_receive = time(NULL);
301 silc_server_private_message(server, sock, packet);
307 case SILC_PACKET_CHANNEL_MESSAGE:
309 * Received channel message. Channel messages are special packets
310 * (although probably most common ones) thus they are handled
313 if (packet->flags & SILC_PACKET_FLAG_LIST)
315 idata->last_receive = time(NULL);
316 silc_server_channel_message(server, sock, packet);
322 case SILC_PACKET_COMMAND:
324 * Recived command. Processes the command request and allocates the
325 * command context and calls the command.
327 if (packet->flags & SILC_PACKET_FLAG_LIST)
329 server->stat.commands_received++;
330 silc_server_command_process(server, sock, packet);
333 case SILC_PACKET_COMMAND_REPLY:
335 * Received command reply packet. Received command reply to command. It
336 * may be reply to command sent by us or reply to command sent by client
337 * that we've routed further.
339 if (packet->flags & SILC_PACKET_FLAG_LIST)
341 server->stat.commands_received++;
342 silc_server_command_reply(server, sock, packet);
345 case SILC_PACKET_DISCONNECT:
348 char *message = NULL;
349 const char *hostname, *ip;
351 if (packet->flags & SILC_PACKET_FLAG_LIST)
353 if (silc_buffer_len(&packet->buffer) < 1)
356 status = (SilcStatus)packet->buffer.data[0];
357 if (silc_buffer_len(&packet->buffer) > 1 &&
358 silc_utf8_valid(packet->buffer.data + 1,
359 silc_buffer_len(&packet->buffer) - 1))
360 message = silc_memdup(packet->buffer.data + 1,
361 silc_buffer_len(&packet->buffer) - 1);
363 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
364 NULL, &hostname, &ip, NULL))
367 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
368 silc_get_status_message(status), status,
369 message ? message : ""));
373 /* Do not switch to backup in case of error */
374 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
376 /* If backup disconnected then mark that resuming will not be allowed */
378 if (server->server_type == SILC_ROUTER && !server->backup_router &&
379 sock->type == SILC_CONN_SERVER && sock->user_data) {
380 SilcServerEntry server_entry = sock->user_data;
381 if (server_entry->server_type == SILC_BACKUP_ROUTER)
382 server->backup_closed = TRUE;
385 /* Handle the disconnection from our end too */
386 if (sock->user_data && SILC_IS_LOCAL(sock->user_data))
387 silc_server_free_sock_user_data(server, sock, NULL);
388 SILC_SET_DISCONNECTING(sock);
389 silc_server_close_connection(server, sock);
390 server->backup_noswitch = FALSE;
395 case SILC_PACKET_CHANNEL_KEY:
397 * Received key for channel. As channels are created by the router
398 * the keys are as well. We will distribute the key to all of our
399 * locally connected clients on the particular channel. Router
400 * never receives this channel and thus is ignored.
402 if (packet->flags & SILC_PACKET_FLAG_LIST)
404 silc_server_channel_key(server, sock, packet);
407 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
409 * Private message key packet.
411 if (packet->flags & SILC_PACKET_FLAG_LIST)
413 silc_server_private_message_key(server, sock, packet);
416 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
418 * Connection authentication request packet. When we receive this packet
419 * we will send to the other end information about our mandatory
420 * authentication method for the connection. This packet maybe received
423 if (packet->flags & SILC_PACKET_FLAG_LIST)
425 silc_server_connection_auth_request(server, sock, packet);
428 case SILC_PACKET_NEW_ID:
430 * Received New ID packet. This includes some new ID that has been
431 * created. It may be for client, server or channel. This is the way
432 * to distribute information about new registered entities in the
435 if (packet->flags & SILC_PACKET_FLAG_LIST)
436 silc_server_new_id_list(server, sock, packet);
438 silc_server_new_id(server, sock, packet);
441 case SILC_PACKET_NEW_CLIENT:
443 * Received new client packet. This includes client information that
444 * we will use to create initial client ID. After creating new
445 * ID we will send it to the client.
447 if (packet->flags & SILC_PACKET_FLAG_LIST)
449 silc_server_new_client(server, sock, packet);
452 case SILC_PACKET_NEW_SERVER:
454 * Received new server packet. This includes Server ID and some other
455 * information that we may save. This is received after server has
458 if (packet->flags & SILC_PACKET_FLAG_LIST)
460 silc_server_new_server(server, sock, packet);
463 case SILC_PACKET_NEW_CHANNEL:
465 * Received new channel packet. Information about new channel in the
466 * network are distributed using this packet.
468 if (packet->flags & SILC_PACKET_FLAG_LIST)
469 silc_server_new_channel_list(server, sock, packet);
471 silc_server_new_channel(server, sock, packet);
474 case SILC_PACKET_HEARTBEAT:
476 * Received heartbeat.
478 if (packet->flags & SILC_PACKET_FLAG_LIST)
482 case SILC_PACKET_KEY_AGREEMENT:
484 * Received heartbeat.
486 if (packet->flags & SILC_PACKET_FLAG_LIST)
488 silc_server_key_agreement(server, sock, packet);
491 case SILC_PACKET_REKEY:
493 * Received re-key packet. The sender wants to regenerate the session
496 if (packet->flags & SILC_PACKET_FLAG_LIST)
498 silc_server_rekey(server, sock, packet);
501 case SILC_PACKET_FTP:
503 if (packet->flags & SILC_PACKET_FLAG_LIST)
505 silc_server_ftp(server, sock, packet);
508 case SILC_PACKET_RESUME_CLIENT:
510 if (packet->flags & SILC_PACKET_FLAG_LIST)
512 silc_server_resume_client(server, sock, packet);
515 case SILC_PACKET_RESUME_ROUTER:
516 /* Resume router packet received. This packet is received for backup
517 router resuming protocol. */
518 if (packet->flags & SILC_PACKET_FLAG_LIST)
521 silc_server_backup_resume_router(server, sock, packet);
526 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
531 /****************************** Server API **********************************/
533 /* Allocates a new SILC server object. This has to be done before the server
534 can be used. After allocation one must call silc_server_init to initialize
535 the server. The new allocated server object is returned to the new_server
538 SilcBool silc_server_alloc(SilcServer *new_server)
542 SILC_LOG_DEBUG(("Allocating new server object"));
544 server = silc_calloc(1, sizeof(*server));
547 server->server_type = SILC_SERVER;
548 server->standalone = TRUE;
549 server->local_list = silc_calloc(1, sizeof(*server->local_list));
550 if (!server->local_list)
552 server->global_list = silc_calloc(1, sizeof(*server->global_list));
553 if (!server->global_list)
555 server->pending_commands = silc_dlist_init();
556 if (!server->pending_commands)
558 server->listeners = silc_dlist_init();
559 if (!server->listeners)
561 server->repository = silc_skr_alloc();
562 if (!server->repository)
564 server->conns = silc_dlist_init();
567 server->expired_clients = silc_dlist_init();
568 if (!server->expired_clients)
571 *new_server = server;
576 /* Free's the SILC server object. This is called at the very end before
579 void silc_server_free(SilcServer server)
582 SilcIDCacheEntry cache;
583 SilcIDListData idata;
585 SILC_LOG_DEBUG(("Free server %p", server));
590 silc_server_backup_free(server);
591 silc_server_config_unref(&server->config_ref);
593 silc_rng_free(server->rng);
594 if (server->public_key)
595 silc_pkcs_public_key_free(server->public_key);
596 if (server->private_key)
597 silc_pkcs_private_key_free(server->private_key);
598 if (server->pending_commands)
599 silc_dlist_uninit(server->pending_commands);
600 if (server->id_entry) {
601 if (server->id_entry->data.sconn)
602 silc_schedule_task_del_by_context(server->schedule,
603 server->id_entry->data.sconn->sock);
604 silc_idlist_del_server(server->local_list, server->id_entry);
607 /* Delete all channels */
608 if (silc_idcache_get_all(server->local_list->channels, &list)) {
609 silc_list_start(list);
610 while ((cache = silc_list_get(list)))
611 silc_idlist_del_channel(server->local_list, cache->context);
613 if (silc_idcache_get_all(server->global_list->channels, &list)) {
614 silc_list_start(list);
615 while ((cache = silc_list_get(list)))
616 silc_idlist_del_channel(server->global_list, cache->context);
619 /* Delete all clients */
620 if (silc_idcache_get_all(server->local_list->clients, &list)) {
621 silc_list_start(list);
622 while ((cache = silc_list_get(list))) {
623 silc_schedule_task_del_by_context(server->schedule, cache->context);
624 silc_idlist_del_client(server->local_list, cache->context);
627 if (silc_idcache_get_all(server->global_list->clients, &list)) {
628 silc_list_start(list);
629 while ((cache = silc_list_get(list))) {
630 silc_schedule_task_del_by_context(server->schedule, cache->context);
631 silc_idlist_del_client(server->global_list, cache->context);
635 /* Delete all servers */
636 if (silc_idcache_get_all(server->local_list->servers, &list)) {
637 silc_list_start(list);
638 while ((cache = silc_list_get(list))) {
639 idata = (SilcIDListData)cache->context;
641 silc_schedule_task_del_by_context(server->schedule,
643 silc_idlist_del_server(server->local_list, cache->context);
646 if (silc_idcache_get_all(server->global_list->servers, &list)) {
647 while ((cache = silc_list_get(list))) {
648 idata = (SilcIDListData)cache->context;
650 silc_schedule_task_del_by_context(server->schedule,
652 silc_idlist_del_server(server->global_list, cache->context);
656 silc_idcache_free(server->local_list->clients);
657 silc_idcache_free(server->local_list->servers);
658 silc_idcache_free(server->local_list->channels);
659 silc_idcache_free(server->global_list->clients);
660 silc_idcache_free(server->global_list->servers);
661 silc_idcache_free(server->global_list->channels);
662 silc_hash_table_free(server->watcher_list);
663 silc_hash_table_free(server->watcher_list_pk);
664 silc_hash_free(server->md5hash);
665 silc_hash_free(server->sha1hash);
667 silc_dlist_uninit(server->listeners);
668 silc_dlist_uninit(server->conns);
669 silc_dlist_uninit(server->expired_clients);
670 silc_skr_free(server->repository);
671 silc_packet_engine_stop(server->packet_engine);
673 silc_schedule_task_del_by_context(server->schedule, server);
674 silc_schedule_uninit(server->schedule);
675 server->schedule = NULL;
677 silc_free(server->local_list);
678 silc_free(server->global_list);
679 silc_free(server->server_name);
682 silc_hmac_unregister_all();
683 silc_hash_unregister_all();
684 silc_cipher_unregister_all();
685 silc_pkcs_unregister_all();
688 /* Creates a new server listener. */
690 static SilcNetListener
691 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
693 SilcNetListener listener;
696 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
697 server->config->require_reverse_lookup,
699 silc_server_accept_new_connection, server);
701 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
709 /* Adds a secondary listener. */
711 SilcBool silc_server_init_secondary(SilcServer server)
716 SilcPacketStream newsocket = NULL;
717 SilcServerConfigServerInfoInterface *interface;
719 for (interface = server->config->server_info->secondary; interface;
720 interface = interface->next, sock++) {
722 if (!silc_server_listen(server,
723 interface->server_ip, interface->port, &sock_list[sock]))
726 /* Set socket to non-blocking mode */
727 silc_net_set_socket_nonblock(sock_list[sock]);
729 /* Add ourselves also to the socket table. The entry allocated above
730 is sent as argument for fast referencing in the future. */
731 silc_socket_alloc(sock_list[sock],
732 SILC_CONN_SERVER, NULL, &newsocket);
733 server->sockets[sock_list[sock]] = newsocket;
734 SILC_SET_LISTENER(newsocket);
736 /* Perform name and address lookups to resolve the listenning address
738 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
740 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
742 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
743 newsocket->hostname ? newsocket->hostname :
744 newsocket->ip ? newsocket->ip : ""));
745 server->stat.conn_failures++;
748 if (!newsocket->hostname)
749 newsocket->hostname = strdup(newsocket->ip);
751 newsocket->port = silc_net_get_local_port(sock);
753 newsocket->user_data = (void *)server->id_entry;
754 silc_schedule_task_add(server->schedule, sock_list[sock],
755 silc_server_accept_new_connection,
756 (void *)server, 0, 0,
758 SILC_TASK_PRI_NORMAL);
764 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
769 /* Initializes the entire SILC server. This is called always before running
770 the server. This is called only once at the initialization of the program.
771 This binds the server to its listenning port. After this function returns
772 one should call silc_server_run to start the server. This returns TRUE
773 when everything is ok to run the server. Configuration file must be
774 read and parsed before calling this. */
776 SilcBool silc_server_init(SilcServer server)
779 SilcServerEntry id_entry;
780 SilcNetListener listener;
784 SILC_LOG_DEBUG(("Initializing server"));
786 server->starttime = time(NULL);
788 /* Take config object for us */
789 silc_server_config_ref(&server->config_ref, server->config,
793 /* Set debugging on if configured */
794 if (server->config->debug_string) {
795 silc_log_debug(TRUE);
796 silc_log_set_debug_string(server->config->debug_string);
798 #endif /* SILC_DEBUG */
800 /* Steal public and private key from the config object */
801 server->public_key = server->config->server_info->public_key;
802 server->private_key = server->config->server_info->private_key;
803 server->config->server_info->public_key = NULL;
804 server->config->server_info->private_key = NULL;
806 /* Register all configured ciphers, PKCS and hash functions. */
807 if (!silc_server_config_register_ciphers(server))
808 silc_cipher_register_default();
809 if (!silc_server_config_register_pkcs(server))
810 silc_pkcs_register_default();
811 if (!silc_server_config_register_hashfuncs(server))
812 silc_hash_register_default();
813 if (!silc_server_config_register_hmacs(server))
814 silc_hmac_register_default();
816 /* Initialize random number generator for the server. */
817 server->rng = silc_rng_alloc();
818 silc_rng_init(server->rng);
819 silc_rng_global_init(server->rng);
821 /* Initialize hash functions for server to use */
822 silc_hash_alloc("md5", &server->md5hash);
823 silc_hash_alloc("sha1", &server->sha1hash);
825 /* Initialize the scheduler */
826 server->schedule = silc_schedule_init(server->config->param.connections_max,
828 if (!server->schedule)
831 /* First, register log files configuration for error output */
832 silc_server_config_setlogfiles(server);
834 /* Initialize ID caches */
835 server->local_list->clients =
836 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
838 server->local_list->servers =
839 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
841 server->local_list->channels =
842 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
845 /* These are allocated for normal server as well as these hold some
846 global information that the server has fetched from its router. For
847 router these are used as they are supposed to be used on router. */
848 server->global_list->clients =
849 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
851 server->global_list->servers =
852 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
854 server->global_list->channels =
855 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
858 /* Init watcher lists */
859 server->watcher_list =
860 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
861 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
863 if (!server->watcher_list)
865 server->watcher_list_pk =
866 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
867 silc_hash_public_key_compare, NULL,
869 if (!server->watcher_list_pk)
872 /* Create TCP listener */
873 listener = silc_server_listen(
875 server->config->server_info->primary == NULL ? NULL :
876 server->config->server_info->primary->server_ip,
877 server->config->server_info->primary == NULL ? 0 :
878 server->config->server_info->primary->port);
882 silc_dlist_add(server->listeners, listener);
884 /* Create a Server ID for the server. */
885 port = silc_net_listener_get_port(listener, NULL);
886 ip = silc_net_listener_get_ip(listener, NULL);
887 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
888 server->config->server_info->primary->public_ip :
889 ip[0], port[0], server->rng, &id);
898 server->server_name = server->config->server_info->server_name;
899 server->config->server_info->server_name = NULL;
900 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
901 sizeof(server->id_string), &server->id_string_len);
903 /* Add ourselves to the server list. We don't have a router yet
904 beacuse we haven't established a route yet. It will be done later.
905 For now, NULL is sent as router. This allocates new entry to
908 silc_idlist_add_server(server->local_list, strdup(server->server_name),
909 server->server_type, server->id, NULL, NULL);
911 SILC_LOG_ERROR(("Could not add local server to cache"));
914 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
915 server->id_entry = id_entry;
917 /* Create secondary TCP listeners */
918 if (silc_server_init_secondary(server) == FALSE)
921 server->listenning = TRUE;
923 /* Create connections to configured routers. */
924 silc_server_create_connections(server);
926 /* If server connections has been configured then we must be router as
927 normal server cannot have server connections, only router connections. */
928 if (server->config->servers) {
929 SilcServerConfigServer *ptr = server->config->servers;
931 server->server_type = SILC_ROUTER;
933 if (ptr->backup_router) {
934 server->server_type = SILC_BACKUP_ROUTER;
935 server->backup_router = TRUE;
936 server->id_entry->server_type = SILC_BACKUP_ROUTER;
944 /* Register the ID Cache purge task. This periodically purges the ID cache
945 and removes the expired cache entries. */
947 /* Clients local list */
948 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
949 purge->cache = server->local_list->clients;
950 purge->timeout = 600;
951 silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
952 (void *)purge, purge->timeout, 0);
954 /* Clients global list */
955 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
956 purge->cache = server->global_list->clients;
957 purge->timeout = 300;
958 silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
959 (void *)purge, purge->timeout, 0);
962 /* If we are normal server we'll retrieve network statisticial information
963 once in a while from the router. */
964 if (server->server_type != SILC_ROUTER)
965 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
968 if (server->server_type == SILC_ROUTER)
969 server->stat.routers++;
971 /* Start packet engine */
972 server->packet_engine =
973 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
974 &silc_server_stream_cbs, server);
975 if (!server->packet_engine)
978 /* Register client entry expiration timeout */
979 silc_schedule_task_add_timeout(server->schedule,
980 silc_server_purge_expired_clients, server,
983 /* Initialize HTTP server */
984 silc_server_http_init(server);
986 SILC_LOG_DEBUG(("Server initialized"));
988 /* We are done here, return succesfully */
992 silc_server_config_unref(&server->config_ref);
997 /* Task callback to close a socket connection after rehash */
999 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
1001 SilcServer server = context;
1002 SilcPacketStream sock = server->sockets[fd];
1007 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
1008 sock->hostname, sock->port,
1009 (sock->type == SILC_CONN_UNKNOWN ? "Unknown" :
1010 sock->type == SILC_CONN_CLIENT ? "Client" :
1011 sock->type == SILC_CONN_SERVER ? "Server" :
1013 silc_schedule_task_del_by_context(server->schedule, sock);
1014 silc_server_disconnect_remote(server, sock,
1015 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1016 "This connection is removed from "
1018 if (sock->user_data)
1019 silc_server_free_sock_user_data(server, sock, NULL);
1023 /* This function basically reads the config file again and switches the config
1024 object pointed by the server object. After that, we have to fix various
1025 things such as the server_name and the listening ports.
1026 Keep in mind that we no longer have the root privileges at this point. */
1028 SilcBool silc_server_rehash(SilcServer server)
1031 SilcServerConfig newconfig;
1033 SILC_LOG_INFO(("Rehashing server"));
1035 /* Reset the logging system */
1036 silc_log_quick(TRUE);
1037 silc_log_flush_all();
1039 /* Start the main rehash phase (read again the config file) */
1040 newconfig = silc_server_config_alloc(server->config_file, server);
1042 SILC_LOG_ERROR(("Rehash FAILED."));
1046 /* Reinit scheduler if necessary */
1047 if (newconfig->param.connections_max > server->config->param.connections_max)
1048 if (!silc_schedule_reinit(server->schedule,
1049 newconfig->param.connections_max))
1052 /* Fix the server_name field */
1053 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1054 silc_free(server->server_name);
1056 /* Check server name */
1057 server->server_name =
1058 silc_identifier_check(newconfig->server_info->server_name,
1059 strlen(newconfig->server_info->server_name),
1060 SILC_STRING_LOCALE, 256, NULL);
1061 if (!server->server_name) {
1062 SILC_LOG_ERROR(("Malformed server name string '%s'",
1063 server->config->server_info->server_name));
1067 /* Update the idcache list with a fresh pointer */
1068 silc_free(server->id_entry->server_name);
1069 server->id_entry->server_name = strdup(server->server_name);
1070 if (!silc_idcache_del_by_context(server->local_list->servers,
1073 if (!silc_idcache_add(server->local_list->servers,
1074 strdup(server->id_entry->server_name),
1075 server->id_entry->id, server->id_entry, 0, NULL))
1080 silc_server_config_setlogfiles(server);
1082 /* Change new key pair if necessary */
1083 if (newconfig->server_info->public_key &&
1084 !silc_pkcs_public_key_compare(server->public_key,
1085 newconfig->server_info->public_key)) {
1086 silc_pkcs_public_key_free(server->public_key);
1087 silc_pkcs_private_key_free(server->private_key);
1088 server->public_key = newconfig->server_info->public_key;
1089 server->private_key = newconfig->server_info->private_key;
1090 newconfig->server_info->public_key = NULL;
1091 newconfig->server_info->private_key = NULL;
1093 /* Allocate PKCS context for local public and private keys */
1094 silc_pkcs_free(server->pkcs);
1095 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
1097 silc_pkcs_public_key_set(server->pkcs, server->public_key);
1098 silc_pkcs_private_key_set(server->pkcs, server->private_key);
1101 /* Check for unconfigured server and router connections and close
1102 connections that were unconfigured. */
1104 if (server->config->routers) {
1105 SilcServerConfigRouter *ptr;
1106 SilcServerConfigRouter *newptr;
1109 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1112 /* Check whether new config has this one too */
1113 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1114 if (silc_string_compare(newptr->host, ptr->host) &&
1115 newptr->port == ptr->port &&
1116 newptr->initiator == ptr->initiator) {
1122 if (!found && ptr->host) {
1123 /* Remove this connection */
1124 SilcPacketStream sock;
1125 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1126 ptr->host, ptr->port);
1127 if (sock && !SILC_IS_LISTENER(sock))
1128 silc_schedule_task_add(server->schedule, sock->sock,
1129 silc_server_rehash_close_connection,
1130 server, 0, 1, SILC_TASK_TIMEOUT,
1131 SILC_TASK_PRI_NORMAL);
1136 if (server->config->servers) {
1137 SilcServerConfigServer *ptr;
1138 SilcServerConfigServer *newptr;
1141 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1144 /* Check whether new config has this one too */
1145 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1146 if (silc_string_compare(newptr->host, ptr->host)) {
1152 if (!found && ptr->host) {
1153 /* Remove this connection */
1154 SilcPacketStream sock;
1155 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1157 if (sock && !SILC_IS_LISTENER(sock))
1158 silc_schedule_task_add(server->schedule, sock->sock,
1159 silc_server_rehash_close_connection,
1160 server, 0, 1, SILC_TASK_TIMEOUT,
1161 SILC_TASK_PRI_NORMAL);
1166 if (server->config->clients) {
1167 SilcServerConfigClient *ptr;
1168 SilcServerConfigClient *newptr;
1171 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1174 /* Check whether new config has this one too */
1175 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1176 if (silc_string_compare(newptr->host, ptr->host)) {
1182 if (!found && ptr->host) {
1183 /* Remove this connection */
1184 SilcPacketStream sock;
1185 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1188 silc_schedule_task_add(server->schedule, sock->sock,
1189 silc_server_rehash_close_connection,
1190 server, 0, 1, SILC_TASK_TIMEOUT,
1191 SILC_TASK_PRI_NORMAL);
1196 /* Create connections after rehash */
1197 silc_server_create_connections(server);
1199 /* Check whether our router status has changed */
1200 if (newconfig->servers) {
1201 SilcServerConfigServer *ptr = newconfig->servers;
1203 server->server_type = SILC_ROUTER;
1205 if (ptr->backup_router) {
1206 server->server_type = SILC_BACKUP_ROUTER;
1207 server->backup_router = TRUE;
1208 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1215 /* Our old config is gone now. We'll unreference our reference made in
1216 silc_server_init and then destroy it since we are destroying it
1217 underneath the application (layer which called silc_server_init). */
1218 silc_server_config_unref(&server->config_ref);
1219 silc_server_config_destroy(server->config);
1221 /* Take new config context */
1222 server->config = newconfig;
1223 silc_server_config_ref(&server->config_ref, server->config, server->config);
1226 /* Set debugging on if configured */
1227 if (server->config->debug_string) {
1228 silc_log_debug(TRUE);
1229 silc_log_set_debug_string(server->config->debug_string);
1231 #endif /* SILC_DEBUG */
1233 SILC_LOG_DEBUG(("Server rehashed"));
1239 /* The heart of the server. This runs the scheduler thus runs the server.
1240 When this returns the server has been stopped and the program will
1243 void silc_server_run(SilcServer server)
1245 SILC_LOG_INFO(("SILC Server started"));
1247 /* Start the scheduler, the heart of the SILC server. When this returns
1248 the program will be terminated. */
1249 silc_schedule(server->schedule);
1252 /* Stops the SILC server. This function is used to shutdown the server.
1253 This is usually called after the scheduler has returned. After stopping
1254 the server one should call silc_server_free. */
1256 void silc_server_stop(SilcServer server)
1259 SilcPacketStream ps;
1260 SilcNetListener listener;
1262 SILC_LOG_INFO(("SILC Server shutting down"));
1264 server->server_shutdown = TRUE;
1266 /* Close all connections */
1267 if (server->packet_engine) {
1268 list = silc_packet_engine_get_streams(server->packet_engine);
1270 silc_dlist_start(list);
1271 while ((ps = silc_dlist_get(list))) {
1272 SilcIDListData idata = silc_packet_get_context(ps);
1275 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1277 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1278 "Server is shutting down");
1279 silc_server_free_sock_user_data(server, ps,
1280 "Server is shutting down");
1282 silc_dlist_uninit(list);
1285 /* We are not connected to network anymore */
1286 server->standalone = TRUE;
1288 silc_dlist_start(server->listeners);
1289 while ((listener = silc_dlist_get(server->listeners)))
1290 silc_net_close_listener(listener);
1292 silc_server_http_uninit(server);
1294 silc_schedule_stop(server->schedule);
1296 SILC_LOG_DEBUG(("Server stopped"));
1299 /* Purge expired client entries from the server */
1301 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1303 SilcServer server = context;
1304 SilcClientEntry client;
1306 SilcUInt64 curtime = silc_time();
1308 SILC_LOG_DEBUG(("Expire timeout"));
1310 silc_dlist_start(server->expired_clients);
1311 while ((client = silc_dlist_get(server->expired_clients))) {
1312 if (client->data.status & SILC_IDLIST_STATUS_REGISTERED)
1315 /* For unregistered clients the created timestamp is actually
1316 unregistered timestamp. Make sure client remains in history
1317 at least 500 seconds. */
1318 if (curtime - client->data.created < 500)
1321 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1322 server->local_list : server->global_list);
1324 silc_idlist_del_data(client);
1325 silc_idlist_del_client(id_list, client);
1326 silc_dlist_del(server->expired_clients, client);
1329 silc_schedule_task_add_timeout(server->schedule,
1330 silc_server_purge_expired_clients, server,
1335 /******************************* Connecting *********************************/
1337 /* Free connection context */
1339 void silc_server_connection_free(SilcServerConnection sconn)
1341 SILC_LOG_DEBUG(("Free connection %p", sconn));
1342 silc_dlist_del(sconn->server->conns, sconn);
1343 silc_server_config_unref(&sconn->conn);
1344 silc_free(sconn->remote_host);
1345 silc_free(sconn->backup_replace_ip);
1349 /* Creates connection to a remote router. */
1351 void silc_server_create_connection(SilcServer server,
1354 const char *remote_host, SilcUInt32 port,
1355 SilcServerConnectCallback callback,
1358 SilcServerConnection sconn;
1360 /* Allocate connection object for hold connection specific stuff. */
1361 sconn = silc_calloc(1, sizeof(*sconn));
1364 sconn->remote_host = strdup(remote_host);
1365 sconn->remote_port = port;
1366 sconn->no_reconnect = reconnect == FALSE;
1367 sconn->callback = callback;
1368 sconn->callback_context = context;
1369 sconn->no_conf = dynamic;
1370 sconn->server = server;
1372 SILC_LOG_DEBUG(("Created connection %p", sconn));
1374 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1378 /* Connection authentication completion callback */
1381 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1384 SilcServerConnection sconn = context;
1385 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1386 SilcServer server = entry->server;
1387 SilcServerConfigServer *conn;
1388 SilcServerConfigConnParams *param;
1389 SilcIDListData idata;
1390 SilcServerEntry id_entry = NULL;
1391 unsigned char id[32];
1395 SILC_LOG_DEBUG(("Connection authentication completed"));
1399 if (success == FALSE) {
1400 /* Authentication failed */
1401 /* XXX retry connecting */
1403 silc_server_disconnect_remote(server, sconn->sock,
1404 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1405 if (sconn->callback)
1406 (*sconn->callback)(server, NULL, sconn->callback_context);
1410 /* XXX For now remote is router always */
1411 entry->data.conn_type = SILC_CONN_ROUTER;
1413 SILC_LOG_INFO(("Connected to %s %s",
1414 SILC_CONNTYPE_STRING(entry->data.conn_type),
1415 sconn->remote_host));
1417 /* Create the actual entry for remote entity */
1418 switch (entry->data.conn_type) {
1419 case SILC_CONN_SERVER:
1420 SILC_LOG_DEBUG(("Remote is SILC server"));
1422 /* Add new server. The server must register itself to us before it
1423 becomes registered to SILC network. */
1424 id_entry = silc_idlist_add_server(server->local_list,
1425 strdup(sconn->remote_host),
1426 SILC_SERVER, NULL, NULL, sconn->sock);
1428 silc_server_disconnect_remote(server, sconn->sock,
1429 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1430 if (sconn->callback)
1431 (*sconn->callback)(server, NULL, sconn->callback_context);
1432 silc_server_connection_free(sconn);
1437 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1440 case SILC_CONN_ROUTER:
1441 SILC_LOG_DEBUG(("Remote is SILC router"));
1443 /* Register to network */
1444 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1445 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1446 SILC_STR_UI_SHORT(id_len),
1447 SILC_STR_DATA(id, id_len),
1448 SILC_STR_UI_SHORT(strlen(server->server_name)),
1449 SILC_STR_DATA(server->server_name,
1450 strlen(server->server_name)),
1452 silc_server_disconnect_remote(server, sconn->sock,
1453 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1454 if (sconn->callback)
1455 (*sconn->callback)(server, NULL, sconn->callback_context);
1456 silc_server_connection_free(sconn);
1462 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1464 /* Check that we do not have this ID already */
1465 id_entry = silc_idlist_find_server_by_id(server->local_list,
1466 &remote_id.u.server_id,
1469 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1471 id_entry = silc_idlist_find_server_by_id(server->global_list,
1472 &remote_id.u.server_id,
1475 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1479 SILC_LOG_DEBUG(("New server id(%s)",
1480 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1482 /* Add the connected router to global server list. Router is sent
1483 as NULL since it's local to us. */
1484 id_entry = silc_idlist_add_server(server->global_list,
1485 strdup(sconn->remote_host),
1487 silc_id_dup(&remote_id.u.server_id,
1491 silc_server_disconnect_remote(server, sconn->sock,
1492 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1493 if (sconn->callback)
1494 (*sconn->callback)(server, NULL, sconn->callback_context);
1495 silc_server_connection_free(sconn);
1501 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1502 idata = (SilcIDListData)id_entry;
1503 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1504 SILC_IDLIST_STATUS_LOCAL);
1505 idata->sconn = sconn;
1507 if (!sconn->backup) {
1508 /* Mark this router our primary router if we're still standalone */
1509 if (server->standalone) {
1510 SILC_LOG_DEBUG(("This connection is our primary router"));
1511 server->id_entry->router = id_entry;
1512 server->router = id_entry;
1513 server->router->server_type = SILC_ROUTER;
1514 server->standalone = FALSE;
1515 server->backup_primary = FALSE;
1517 /* Announce data if we are not backup router (unless not as primary
1518 currently). Backup router announces later at the end of
1519 resuming protocol. */
1520 if (server->backup_router && server->server_type == SILC_ROUTER) {
1521 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1523 /* If we are router then announce our possible servers. Backup
1524 router announces also global servers. */
1525 if (server->server_type == SILC_ROUTER)
1526 silc_server_announce_servers(server,
1527 server->backup_router ? TRUE : FALSE,
1528 0, SILC_PRIMARY_ROUTE(server));
1530 /* Announce our clients and channels to the router */
1531 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1532 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1536 /* If we are backup router then this primary router is whom we are
1538 if (server->server_type == SILC_BACKUP_ROUTER)
1539 silc_server_backup_add(server, server->id_entry, sock->ip,
1540 sconn->remote_port, TRUE);
1544 /* Add this server to be our backup router */
1545 id_entry->server_type = SILC_BACKUP_ROUTER;
1546 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1547 sconn->backup_replace_port, FALSE);
1553 silc_server_disconnect_remote(server, sconn->sock,
1554 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1555 if (sconn->callback)
1556 (*sconn->callback)(server, NULL, sconn->callback_context);
1557 silc_server_connection_free(sconn);
1562 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1564 conn = sconn->conn.ref_ptr;
1565 param = &server->config->param;
1566 if (conn && conn->param)
1567 param = conn->param;
1569 /* Register rekey timeout */
1570 sconn->rekey_timeout = param->key_exchange_rekey;
1571 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1572 sconn->sock, sconn->rekey_timeout, 0);
1575 /* Perform keepalive. */
1576 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
1577 silc_server_perform_heartbeat,
1581 /* Set the entry as packet stream context */
1582 silc_packet_set_context(sconn->sock, id_entry);
1585 /* Call the completion callback to indicate that we've connected to
1587 if (sconn && sconn->callback)
1588 (*sconn->callback)(server, id_entry, sconn->callback_context);
1591 /* Free the temporary connection data context */
1593 silc_server_config_unref(&sconn->conn);
1594 silc_free(sconn->remote_host);
1595 silc_free(sconn->backup_replace_ip);
1598 if (sconn == server->router_conn)
1599 server->router_conn = NULL;
1605 /* SKE completion callback */
1607 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1608 SilcSKESecurityProperties prop,
1609 SilcSKEKeyMaterial keymat,
1610 SilcSKERekeyMaterial rekey,
1613 SilcPacketStream sock = context;
1614 SilcUnknownEntry entry = silc_packet_get_context(sock);
1615 SilcServerConnection sconn = silc_ske_get_context(ske);
1616 SilcServer server = entry->server;
1617 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1618 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1619 void *auth_data = NULL;
1620 SilcUInt32 auth_data_len = 0;
1621 SilcConnAuth connauth;
1622 SilcCipher send_key, receive_key;
1623 SilcHmac hmac_send, hmac_receive;
1628 if (status != SILC_SKE_STATUS_OK) {
1630 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1631 silc_ske_map_status(status), entry->hostname, entry->ip));
1633 /* XXX retry connecting */
1635 silc_server_disconnect_remote(server, sconn->sock,
1636 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1637 if (sconn->callback)
1638 (*sconn->callback)(server, NULL, sconn->callback_context);
1639 silc_server_connection_free(sconn);
1643 SILC_LOG_DEBUG(("Setting keys into use"));
1645 /* Set the keys into use. The data will be encrypted after this. */
1646 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1647 &hmac_send, &hmac_receive, &hash)) {
1649 /* XXX retry connecting */
1651 /* Error setting keys */
1653 silc_server_disconnect_remote(server, sconn->sock,
1654 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1655 if (sconn->callback)
1656 (*sconn->callback)(server, NULL, sconn->callback_context);
1657 silc_server_connection_free(sconn);
1660 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1661 hmac_receive, FALSE);
1663 SILC_LOG_DEBUG(("Starting connection authentication"));
1665 connauth = silc_connauth_alloc(server->schedule, ske,
1666 server->config->conn_auth_timeout);
1668 /* XXX retry connecting */
1670 /** Error allocating auth protocol */
1672 silc_server_disconnect_remote(server, sconn->sock,
1673 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1674 if (sconn->callback)
1675 (*sconn->callback)(server, NULL, sconn->callback_context);
1676 silc_server_connection_free(sconn);
1680 /* Get authentication method */
1682 if (conn->passphrase) {
1683 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1684 auth_meth = SILC_AUTH_PUBLIC_KEY;
1685 auth_data = server->private_key;
1687 auth_meth = SILC_AUTH_PASSWORD;
1688 auth_data = conn->passphrase;
1689 auth_data_len = conn->passphrase_len;
1692 auth_meth = SILC_AUTH_PUBLIC_KEY;
1693 auth_data = server->private_key;
1697 /* Start connection authentication */
1699 silc_connauth_initiator(connauth, server->server_type == SILC_ROUTER ?
1700 SILC_CONN_ROUTER : SILC_CONN_SERVER, auth_meth,
1701 auth_data, auth_data_len,
1702 silc_server_ke_auth_compl, sconn);
1705 /* Function that is called when the network connection to a router has
1706 been established. This will continue with the key exchange protocol
1707 with the remote router. */
1709 void silc_server_start_key_exchange(SilcServerConnection sconn)
1711 SilcServer server = sconn->server;
1712 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1713 SilcUnknownEntry entry;
1714 SilcSKEParamsStruct params;
1717 /* Cancel any possible retry timeouts */
1718 silc_schedule_task_del_by_context(server->schedule, sconn);
1720 /* Create packet stream */
1721 sconn->sock = silc_packet_stream_create(server->packet_engine,
1722 server->schedule, sconn->stream);
1724 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1725 silc_stream_destroy(sconn->stream);
1726 if (sconn->callback)
1727 (*sconn->callback)(server, NULL, sconn->callback_context);
1728 silc_server_connection_free(sconn);
1731 server->stat.conn_num++;
1733 /* Set source ID to packet stream */
1734 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1736 silc_packet_stream_destroy(sconn->sock);
1737 if (sconn->callback)
1738 (*sconn->callback)(server, NULL, sconn->callback_context);
1739 silc_server_connection_free(sconn);
1743 /* Create entry for remote entity */
1744 entry = silc_calloc(1, sizeof(*entry));
1746 silc_packet_stream_destroy(sconn->sock);
1747 silc_server_connection_free(sconn);
1750 entry->server = server;
1751 silc_packet_set_context(sconn->sock, entry);
1753 /* Set Key Exchange flags from configuration, but fall back to global
1755 memset(¶ms, 0, sizeof(params));
1756 SILC_GET_SKE_FLAGS(conn, params.flags);
1757 if (server->config->param.key_exchange_pfs)
1758 params.flags |= SILC_SKE_SP_FLAG_PFS;
1760 /* Start SILC Key Exchange protocol */
1761 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1762 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1763 server->public_key, server->private_key, sconn);
1766 silc_packet_stream_destroy(sconn->sock);
1767 if (sconn->callback)
1768 (*sconn->callback)(server, NULL, sconn->callback_context);
1769 silc_server_connection_free(sconn);
1772 silc_ske_set_callbacks(ske, silc_server_verify_key,
1773 silc_server_ke_completed, sconn->sock);
1775 /* Start key exchange protocol */
1776 params.version = silc_version_string;
1777 params.timeout_secs = server->config->key_exchange_timeout;
1778 sconn->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1781 /* Timeout callback that will be called to retry connecting to remote
1782 router. This is used by both normal and router server. This will wait
1783 before retrying the connecting. The timeout is generated by exponential
1784 backoff algorithm. */
1786 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1788 SilcServerConnection sconn = context;
1789 SilcServer server = sconn->server;
1790 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1791 SilcServerConfigConnParams *param =
1792 (conn->param ? conn->param : &server->config->param);
1794 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1795 sconn->remote_port));
1797 /* Calculate next timeout */
1798 if (sconn->retry_count >= 1) {
1799 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1800 if (sconn->retry_timeout > param->reconnect_interval_max)
1801 sconn->retry_timeout = param->reconnect_interval_max;
1803 sconn->retry_timeout = param->reconnect_interval;
1805 sconn->retry_count++;
1806 sconn->retry_timeout = sconn->retry_timeout +
1807 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1809 /* If we've reached max retry count, give up. */
1810 if ((sconn->retry_count > param->reconnect_count) &&
1811 !param->reconnect_keep_trying) {
1812 SILC_LOG_ERROR(("Could not connect, giving up"));
1814 if (sconn->callback)
1815 (*sconn->callback)(server, NULL, sconn->callback_context);
1816 silc_server_connection_free(sconn);
1820 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1822 /* We will lookup a fresh pointer later */
1823 silc_server_config_unref(&sconn->conn);
1825 /* Wait before retrying */
1826 silc_schedule_task_del_by_context(server->schedule, sconn);
1827 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1828 sconn, sconn->retry_timeout, 0);
1831 /* Callback for async connection to remote router */
1833 static void silc_server_connection_established(SilcNetStatus status,
1837 SilcServerConnection sconn = context;
1838 SilcServer server = sconn->server;
1840 silc_schedule_task_del_by_context(server->schedule, sconn);
1845 SILC_LOG_DEBUG(("Connection to %s:%d established",
1846 sconn->remote_host, sconn->remote_port));
1848 /* Continue with key exchange protocol */
1849 sconn->stream = stream;
1850 silc_server_start_key_exchange(sconn);
1853 case SILC_NET_UNKNOWN_IP:
1854 case SILC_NET_UNKNOWN_HOST:
1855 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1856 sconn->remote_host, sconn->remote_port,
1857 silc_net_get_error_string(status)));
1859 if (sconn->callback)
1860 (*sconn->callback)(server, NULL, sconn->callback_context);
1861 silc_server_connection_free(sconn);
1865 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1866 sconn->remote_host, sconn->remote_port,
1867 silc_net_get_error_string(status)));
1868 if (!sconn->no_reconnect) {
1869 silc_schedule_task_add_timeout(sconn->server->schedule,
1870 silc_server_connect_to_router_retry,
1873 if (sconn->callback)
1874 (*sconn->callback)(server, NULL, sconn->callback_context);
1875 silc_server_connection_free(sconn);
1881 /* Generic routine to use connect to a router. */
1883 SILC_TASK_CALLBACK(silc_server_connect_router)
1885 SilcServerConnection sconn = context;
1886 SilcServer server = sconn->server;
1887 SilcServerConfigRouter *rconn;
1889 silc_schedule_task_del_by_context(server->schedule, sconn);
1891 /* Don't connect if we are shutting down. */
1892 if (server->server_shutdown) {
1893 if (sconn->callback)
1894 (*sconn->callback)(server, NULL, sconn->callback_context);
1895 silc_server_connection_free(sconn);
1899 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1900 (sconn->backup ? "backup router" : "router"),
1901 sconn->remote_host, sconn->remote_port));
1903 if (!sconn->no_conf) {
1904 /* Find connection configuration */
1905 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1906 sconn->remote_port);
1908 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1909 (sconn->backup ? "backup router" : "router"),
1910 sconn->remote_host, sconn->remote_port));
1911 silc_server_connection_free(sconn);
1914 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1917 /* Connect to remote host */
1919 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1920 server->config->server_info->primary->server_ip),
1921 sconn->remote_host, sconn->remote_port,
1922 server->schedule, silc_server_connection_established,
1925 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1926 sconn->remote_host, sconn->remote_port));
1927 silc_server_connection_free(sconn);
1931 /* Add to connection list */
1932 silc_dlist_add(server->conns, sconn);
1935 /* This function connects to our primary router or if we are a router this
1936 establishes all our primary routes. This is called at the start of the
1937 server to do authentication and key exchange with our router - called
1940 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1942 SilcServer server = context;
1943 SilcServerConnection sconn;
1944 SilcServerConfigRouter *ptr;
1946 /* Don't connect if we are shutting down. */
1947 if (server->server_shutdown)
1950 SILC_LOG_DEBUG(("We are %s",
1951 (server->server_type == SILC_SERVER ?
1952 "normal server" : server->server_type == SILC_ROUTER ?
1953 "router" : "backup router/normal server")));
1956 if (!server->config->routers) {
1957 /* There wasn't a configured router, we will continue but we don't
1958 have a connection to outside world. We will be standalone server. */
1959 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1960 server->standalone = TRUE;
1964 /* Create the connections to all our routes */
1965 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1967 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1968 ptr->backup_router ? "Backup router" : "Router",
1969 ptr->initiator ? "Initiator" : "Responder",
1970 ptr->host, ptr->port));
1972 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1973 ptr->initiator == FALSE && !server->backup_router &&
1974 !silc_server_config_get_backup_router(server))
1975 server->wait_backup = TRUE;
1977 if (!ptr->initiator)
1979 if (ptr->dynamic_connection)
1982 /* Check whether we are connecting or connected to this host already */
1983 if (silc_server_num_sockets_by_remote(server,
1984 silc_net_is_ip(ptr->host) ?
1986 silc_net_is_ip(ptr->host) ?
1987 NULL : ptr->host, ptr->port)) {
1988 SILC_LOG_DEBUG(("We are already connected to %s:%d",
1989 ptr->host, ptr->port));
1991 /* If we don't have primary router and this connection is our
1992 primary router we are in desync. Reconnect to the primary. */
1993 if (server->standalone && !server->router) {
1995 SilcPacketStream sock;
1996 SilcServerConfigRouter *primary =
1997 silc_server_config_get_primary_router(server);
2000 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2001 ptr->host, ptr->port);
2004 server->backup_noswitch = TRUE;
2006 if (sock->user_data)
2007 silc_server_free_sock_user_data(server, sock, NULL);
2008 silc_server_disconnect_remote(server, sock, 0, NULL);
2010 server->backup_noswitch = FALSE;
2011 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2017 /* Allocate connection object for hold connection specific stuff. */
2018 sconn = silc_calloc(1, sizeof(*sconn));
2021 sconn->remote_host = strdup(ptr->host);
2022 sconn->remote_port = ptr->port;
2023 sconn->backup = ptr->backup_router;
2024 if (sconn->backup) {
2025 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2026 sconn->backup_replace_port = ptr->backup_replace_port;
2029 SILC_LOG_DEBUG(("Created connection %p", sconn));
2032 if (!server->router_conn && !sconn->backup)
2033 server->router_conn = sconn;
2036 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2042 /************************ Accepting new connection **************************/
2044 /* After this is called, server don't wait for backup router anymore.
2045 This gets called automatically even after we have backup router
2046 connection established. */
2048 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2050 SilcServer server = context;
2051 server->wait_backup = FALSE;
2054 /* Authentication data callback */
2057 silc_server_accept_get_auth(SilcConnAuth connauth,
2058 SilcConnectionType conn_type,
2059 unsigned char **passphrase,
2060 SilcUInt32 *passphrase_len,
2061 SilcSKR *repository,
2064 SilcPacketStream sock = context;
2065 SilcUnknownEntry entry = silc_packet_get_context(sock);
2066 SilcServer server = entry->server;
2068 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2070 /* Remote end is client */
2071 if (conn_type == SILC_CONN_CLIENT) {
2072 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2076 *passphrase = cconfig->passphrase;
2077 *passphrase_len = cconfig->passphrase_len;
2078 if (cconfig->publickeys)
2079 *repository = server->repository;
2081 entry->data.conn_type = conn_type;
2085 /* Remote end is server */
2086 if (conn_type == SILC_CONN_SERVER) {
2087 SilcServerConfigServer *sconfig = entry->sconfig.ref_ptr;
2091 *passphrase = sconfig->passphrase;
2092 *passphrase_len = sconfig->passphrase_len;
2093 if (sconfig->publickeys)
2094 *repository = server->repository;
2096 entry->data.conn_type = conn_type;
2100 /* Remote end is router */
2101 if (conn_type == SILC_CONN_ROUTER) {
2102 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2106 *passphrase = rconfig->passphrase;
2107 *passphrase_len = rconfig->passphrase_len;
2108 if (rconfig->publickeys)
2109 *repository = server->repository;
2111 entry->data.conn_type = conn_type;
2118 /* Authentication completion callback. */
2121 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2124 SilcPacketStream sock = context;
2125 SilcUnknownEntry entry = silc_packet_get_context(sock);
2126 SilcIDListData idata = (SilcIDListData)entry;
2127 SilcServer server = entry->server;
2128 SilcServerConfigConnParams *param = &server->config->param;
2129 SilcServerConnection sconn;
2131 const char *hostname;
2135 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2136 NULL, &hostname, NULL, &port);
2138 if (success == FALSE) {
2139 /* Authentication failed */
2140 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2141 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2142 server->stat.auth_failures++;
2143 silc_server_disconnect_remote(server, sock,
2144 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2148 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2150 switch (entry->data.conn_type) {
2151 case SILC_CONN_CLIENT:
2153 SilcClientEntry client;
2154 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2156 /* Verify whether this connection is after all allowed to connect */
2157 if (!silc_server_connection_allowed(server, sock, entry->data.conn_type,
2158 &server->config->param,
2160 silc_connauth_get_ske(connauth))) {
2161 server->stat.auth_failures++;
2165 /* If we are primary router and we have backup router configured
2166 but it has not connected to use yet, do not accept any other
2168 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2169 !server->backup_router) {
2170 SilcServerConfigRouter *router;
2171 router = silc_server_config_get_backup_router(server);
2172 if (router && strcmp(server->config->server_info->primary->server_ip,
2174 silc_server_find_socket_by_host(server,
2176 router->backup_replace_ip, 0)) {
2177 SILC_LOG_INFO(("Will not accept connections because we do "
2178 "not have backup router connection established"));
2179 silc_server_disconnect_remote(server, sock,
2180 SILC_STATUS_ERR_PERM_DENIED,
2181 "We do not have connection to backup "
2182 "router established, try later");
2183 server->stat.auth_failures++;
2185 /* From here on, wait 20 seconds for the backup router to appear. */
2186 silc_schedule_task_add_timeout(server->schedule,
2187 silc_server_backup_router_wait,
2188 (void *)server, 20, 0);
2193 SILC_LOG_DEBUG(("Remote host is client"));
2194 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2197 /* Add the client to the client ID cache. The nickname and Client ID
2198 and other information is created after we have received NEW_CLIENT
2199 packet from client. */
2200 client = silc_idlist_add_client(server->local_list,
2201 NULL, NULL, NULL, NULL, NULL, sock);
2203 SILC_LOG_ERROR(("Could not add new client to cache"));
2204 server->stat.auth_failures++;
2205 silc_server_disconnect_remote(server, sock,
2206 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2209 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2212 server->stat.my_clients++;
2213 server->stat.clients++;
2214 server->stat.cell_clients++;
2216 /* Get connection parameters */
2218 param = conn->param;
2220 if (!param->keepalive_secs)
2221 param->keepalive_secs = server->config->param.keepalive_secs;
2223 if (!param->qos && server->config->param.qos) {
2224 param->qos = server->config->param.qos;
2225 param->qos_rate_limit = server->config->param.qos_rate_limit;
2226 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2227 param->qos_limit_sec = server->config->param.qos_limit_sec;
2228 param->qos_limit_usec = server->config->param.qos_limit_usec;
2231 /* Check if to be anonymous connection */
2232 if (param->anonymous)
2233 client->mode |= SILC_UMODE_ANONYMOUS;
2236 /* Add public key to repository */
2237 if (!silc_server_get_public_key_by_client(server, client, NULL))
2238 silc_skr_add_public_key_simple(server->repository,
2239 entry->data.public_key,
2240 SILC_SKR_USAGE_IDENTIFICATION, client,
2243 id_entry = (void *)client;
2247 case SILC_CONN_SERVER:
2248 case SILC_CONN_ROUTER:
2250 SilcServerEntry new_server;
2251 SilcBool initiator = FALSE;
2252 SilcBool backup_local = FALSE;
2253 SilcBool backup_router = FALSE;
2254 char *backup_replace_ip = NULL;
2255 SilcUInt16 backup_replace_port = 0;
2256 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2257 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2259 /* If we are backup router and this is incoming server connection
2260 and we do not have connection to primary router, do not allow
2262 if (server->server_type == SILC_BACKUP_ROUTER &&
2263 entry->data.conn_type == SILC_CONN_SERVER &&
2264 !SILC_PRIMARY_ROUTE(server)) {
2265 SILC_LOG_INFO(("Will not accept server connection because we do "
2266 "not have primary router connection established"));
2267 silc_server_disconnect_remote(server, sock,
2268 SILC_STATUS_ERR_PERM_DENIED,
2269 "We do not have connection to primary "
2270 "router established, try later");
2271 server->stat.auth_failures++;
2275 if (entry->data.conn_type == SILC_CONN_ROUTER) {
2276 /* Verify whether this connection is after all allowed to connect */
2277 if (!silc_server_connection_allowed(server, sock,
2278 entry->data.conn_type,
2279 &server->config->param,
2280 rconn ? rconn->param : NULL,
2281 silc_connauth_get_ske(connauth))) {
2282 server->stat.auth_failures++;
2288 param = rconn->param;
2290 if (!param->keepalive_secs)
2291 param->keepalive_secs = server->config->param.keepalive_secs;
2293 if (!param->qos && server->config->param.qos) {
2294 param->qos = server->config->param.qos;
2295 param->qos_rate_limit = server->config->param.qos_rate_limit;
2296 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2297 param->qos_limit_sec = server->config->param.qos_limit_sec;
2298 param->qos_limit_usec = server->config->param.qos_limit_usec;
2302 initiator = rconn->initiator;
2303 backup_local = rconn->backup_local;
2304 backup_router = rconn->backup_router;
2305 backup_replace_ip = rconn->backup_replace_ip;
2306 backup_replace_port = rconn->backup_replace_port;
2310 if (entry->data.conn_type == SILC_CONN_SERVER) {
2311 /* Verify whether this connection is after all allowed to connect */
2312 if (!silc_server_connection_allowed(server, sock,
2313 entry->data.conn_type,
2314 &server->config->param,
2315 srvconn ? srvconn->param : NULL,
2316 silc_connauth_get_ske(connauth))) {
2317 server->stat.auth_failures++;
2321 if (srvconn->param) {
2322 param = srvconn->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 backup_router = srvconn->backup_router;
2340 /* If we are primary router and we have backup router configured
2341 but it has not connected to use yet, do not accept any other
2344 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2345 !server->backup_router && !backup_router) {
2346 SilcServerConfigRouter *router;
2347 router = silc_server_config_get_backup_router(server);
2348 if (router && strcmp(server->config->server_info->primary->server_ip,
2350 silc_server_find_socket_by_host(server,
2352 router->backup_replace_ip, 0)) {
2353 SILC_LOG_INFO(("Will not accept connections because we do "
2354 "not have backup router connection established"));
2355 silc_server_disconnect_remote(server, sock,
2356 SILC_STATUS_ERR_PERM_DENIED,
2357 "We do not have connection to backup "
2358 "router established, try later");
2359 server->stat.auth_failures++;
2361 /* From here on, wait 20 seconds for the backup router to appear. */
2362 silc_schedule_task_add_timeout(server->schedule,
2363 silc_server_backup_router_wait,
2364 (void *)server, 20, 0);
2370 SILC_LOG_DEBUG(("Remote host is %s",
2371 entry->data.conn_type == SILC_CONN_SERVER ?
2372 "server" : (backup_router ?
2373 "backup router" : "router")));
2374 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2375 entry->ip, entry->data.conn_type == SILC_CONN_SERVER ?
2376 "server" : (backup_router ?
2377 "backup router" : "router")));
2379 /* Add the server into server cache. The server name and Server ID
2380 is updated after we have received NEW_SERVER packet from the
2381 server. We mark ourselves as router for this server if we really
2384 silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ?
2385 server->local_list : (backup_router ?
2386 server->local_list :
2387 server->global_list)),
2389 (entry->data.conn_type == SILC_CONN_SERVER ?
2390 SILC_SERVER : SILC_ROUTER),
2392 (entry->data.conn_type == SILC_CONN_SERVER ?
2393 server->id_entry : (backup_router ?
2394 server->id_entry : NULL)),
2397 SILC_LOG_ERROR(("Could not add new server to cache"));
2398 silc_server_disconnect_remote(server, sock,
2399 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2400 server->stat.auth_failures++;
2403 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2405 id_entry = (void *)new_server;
2407 /* If the incoming connection is router and marked as backup router
2408 then add it to be one of our backups */
2409 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2410 /* Change it back to SERVER type since that's what it really is. */
2412 entry->data.conn_type = SILC_CONN_SERVER;
2413 new_server->server_type = SILC_BACKUP_ROUTER;
2415 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2416 ("Backup router %s is now online",
2419 /* Remove the backup waiting with timeout */
2420 silc_schedule_task_add_timeout(server->schedule,
2421 silc_server_backup_router_wait,
2422 (void *)server, 10, 0);
2426 if (entry->data.conn_type == SILC_CONN_SERVER) {
2427 server->stat.my_servers++;
2428 server->stat.servers++;
2430 server->stat.my_routers++;
2431 server->stat.routers++;
2434 /* Check whether this connection is to be our primary router connection
2435 if we do not already have the primary route. */
2436 if (!backup_router &&
2437 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2438 if (silc_server_config_is_primary_route(server) && !initiator)
2441 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2442 server->standalone = FALSE;
2443 if (!server->id_entry->router) {
2444 server->id_entry->router = id_entry;
2445 server->router = id_entry;
2457 /* Add connection to server->conns so that we know we have connection
2459 sconn = silc_calloc(1, sizeof(*sconn));
2460 sconn->server = server;
2462 sconn->remote_host = strdup(hostname);
2463 sconn->remote_port = port;
2464 silc_dlist_add(server->conns, sconn);
2465 idata->sconn = sconn;
2466 idata->last_receive = time(NULL);
2468 /* Add the common data structure to the ID entry. */
2469 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2470 silc_packet_set_context(sock, id_entry);
2472 /* Connection has been fully established now. Everything is ok. */
2473 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2476 /* Perform keepalive. */
2477 if (param->keepalive_secs)
2478 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
2479 silc_server_perform_heartbeat,
2483 /* Perform Quality of Service */
2485 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2486 param->qos_rate_limit, param->qos_bytes_limit,
2487 param->qos_limit_sec, param->qos_limit_usec);
2489 silc_server_config_unref(&entry->cconfig);
2490 silc_server_config_unref(&entry->sconfig);
2491 silc_server_config_unref(&entry->rconfig);
2495 silc_ske_free(silc_connauth_get_ske(connauth));
2496 silc_connauth_free(connauth);
2499 /* SKE completion callback. We set the new keys into use here. */
2502 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2503 SilcSKESecurityProperties prop,
2504 SilcSKEKeyMaterial keymat,
2505 SilcSKERekeyMaterial rekey,
2508 SilcPacketStream sock = context;
2509 SilcUnknownEntry entry = silc_packet_get_context(sock);
2510 SilcIDListData idata = (SilcIDListData)entry;
2511 SilcServer server = entry->server;
2512 SilcConnAuth connauth;
2513 SilcCipher send_key, receive_key;
2514 SilcHmac hmac_send, hmac_receive;
2521 if (status != SILC_SKE_STATUS_OK) {
2523 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2524 silc_ske_map_status(status), entry->hostname, entry->ip));
2526 silc_server_disconnect_remote(server, sock,
2527 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2531 SILC_LOG_DEBUG(("Setting keys into use"));
2533 /* Set the keys into use. The data will be encrypted after this. */
2534 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2535 &hmac_send, &hmac_receive, &hash)) {
2536 /* Error setting keys */
2538 silc_server_disconnect_remote(server, sock,
2539 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2542 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2543 hmac_receive, FALSE);
2545 idata->rekey = rekey;
2546 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2547 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2548 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2550 SILC_LOG_DEBUG(("Starting connection authentication"));
2551 server->stat.auth_attempts++;
2553 connauth = silc_connauth_alloc(server->schedule, ske,
2554 server->config->conn_auth_timeout);
2556 /** Error allocating auth protocol */
2558 silc_server_disconnect_remote(server, sock,
2559 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2563 /* Start connection authentication */
2565 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2566 silc_server_accept_auth_compl, sock);
2569 /* Accept new TCP connection */
2571 static void silc_server_accept_new_connection(SilcNetStatus status,
2575 SilcServer server = context;
2576 SilcPacketStream packet_stream;
2577 SilcServerConfigClient *cconfig = NULL;
2578 SilcServerConfigServer *sconfig = NULL;
2579 SilcServerConfigRouter *rconfig = NULL;
2580 SilcServerConfigDeny *deny;
2581 SilcUnknownEntry entry;
2583 SilcSKEParamsStruct params;
2584 char *hostname, *ip;
2587 SILC_LOG_DEBUG(("Accepting new connection"));
2589 /* Check for maximum allowed connections */
2590 server->stat.conn_attempts++;
2591 if (silc_dlist_count(server->conns) >
2592 server->config->param.connections_max) {
2593 SILC_LOG_ERROR(("Refusing connection, server is full"));
2594 server->stat.conn_failures++;
2595 silc_stream_destroy(stream);
2599 /* Get hostname, IP and port */
2600 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2601 (const char **)&ip, &port)) {
2602 /* Bad socket stream */
2603 server->stat.conn_failures++;
2604 silc_stream_destroy(stream);
2608 /* Create packet stream */
2609 packet_stream = silc_packet_stream_create(server->packet_engine,
2610 server->schedule, stream);
2611 if (!packet_stream) {
2612 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2613 server->stat.conn_failures++;
2614 silc_stream_destroy(stream);
2617 server->stat.conn_num++;
2619 /* Set source ID to packet stream */
2620 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2623 server->stat.conn_failures++;
2624 silc_packet_stream_destroy(packet_stream);
2628 /* Check whether this connection is denied to connect to us. */
2629 deny = silc_server_config_find_denied(server, ip);
2631 deny = silc_server_config_find_denied(server, hostname);
2633 /* The connection is denied */
2634 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2635 silc_server_disconnect_remote(server, packet_stream,
2636 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2641 /* Check whether we have configured this sort of connection at all. We
2642 have to check all configurations since we don't know what type of
2643 connection this is. */
2644 if (!(cconfig = silc_server_config_find_client(server, ip)))
2645 cconfig = silc_server_config_find_client(server, hostname);
2646 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2647 sconfig = silc_server_config_find_server_conn(server, hostname);
2648 if (server->server_type == SILC_ROUTER)
2649 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2650 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2651 if (!cconfig && !sconfig && !rconfig) {
2652 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2653 server->stat.conn_failures++;
2654 silc_server_disconnect_remote(server, packet_stream,
2655 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2659 /* The connection is allowed */
2660 entry = silc_calloc(1, sizeof(*entry));
2662 server->stat.conn_failures++;
2663 silc_server_disconnect_remote(server, packet_stream,
2664 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2667 entry->hostname = hostname;
2670 entry->server = server;
2671 entry->data.conn_type = SILC_CONN_UNKNOWN;
2672 silc_packet_set_context(packet_stream, entry);
2674 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2675 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2676 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2678 /* Take flags for key exchange. Since we do not know what type of connection
2679 this is, we go through all found configurations and use the global ones
2680 as well. This will result always into strictest key exchange flags. */
2681 memset(¶ms, 0, sizeof(params));
2682 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2683 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2684 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2685 if (server->config->param.key_exchange_pfs)
2686 params.flags |= SILC_SKE_SP_FLAG_PFS;
2688 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2689 server->stat.conn_attempts++;
2691 /* Start SILC Key Exchange protocol */
2692 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2693 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2694 server->public_key, server->private_key,
2697 server->stat.conn_failures++;
2698 silc_server_disconnect_remote(server, packet_stream,
2699 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2702 silc_ske_set_callbacks(ske, silc_server_verify_key,
2703 silc_server_accept_completed, packet_stream);
2705 /* Start key exchange protocol */
2706 params.version = silc_version_string;
2707 params.timeout_secs = server->config->key_exchange_timeout;
2708 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2712 /********************************** Rekey ***********************************/
2714 /* Initiator rekey completion callback */
2716 static void silc_server_rekey_completion(SilcSKE ske,
2717 SilcSKEStatus status,
2718 const SilcSKESecurityProperties prop,
2719 const SilcSKEKeyMaterial keymat,
2720 SilcSKERekeyMaterial rekey,
2723 SilcPacketStream sock = context;
2724 SilcIDListData idata = silc_packet_get_context(sock);
2725 SilcServer server = idata->sconn->server;
2727 idata->sconn->op = NULL;
2728 if (status != SILC_SKE_STATUS_OK) {
2729 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2730 idata->sconn->remote_host));
2734 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2735 idata->sconn->remote_host, idata->sconn->remote_port,
2736 SILC_CONNTYPE_STRING(idata->conn_type)));
2738 /* Save rekey data for next rekey */
2739 idata->rekey = rekey;
2741 /* Register new rekey timeout */
2742 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2743 sock, idata->sconn->rekey_timeout, 0);
2746 /* Rekey callback. Start rekey as initiator */
2748 SILC_TASK_CALLBACK(silc_server_do_rekey)
2750 SilcServer server = app_context;
2751 SilcPacketStream sock = context;
2752 SilcIDListData idata = silc_packet_get_context(sock);
2755 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2757 /* Do not execute rekey with disabled connections */
2758 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2761 /* If another protocol is active do not start rekey */
2762 if (idata->sconn->op) {
2763 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2764 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2769 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2770 idata->sconn->remote_host, idata->sconn->remote_port,
2771 SILC_CONNTYPE_STRING(idata->conn_type)));
2774 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2775 server->public_key, server->private_key, sock);
2779 /* Set SKE callbacks */
2780 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2783 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2786 /* Responder rekey completion callback */
2789 silc_server_rekey_resp_completion(SilcSKE ske,
2790 SilcSKEStatus status,
2791 const SilcSKESecurityProperties prop,
2792 const SilcSKEKeyMaterial keymat,
2793 SilcSKERekeyMaterial rekey,
2796 SilcPacketStream sock = context;
2797 SilcIDListData idata = silc_packet_get_context(sock);
2799 idata->sconn->op = NULL;
2800 if (status != SILC_SKE_STATUS_OK) {
2801 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2802 idata->sconn->remote_host));
2806 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2807 idata->sconn->remote_host, idata->sconn->remote_port,
2808 SILC_CONNTYPE_STRING(idata->conn_type)));
2810 /* Save rekey data for next rekey */
2811 idata->rekey = rekey;
2814 /* Start rekey as responder */
2816 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2819 SilcIDListData idata = silc_packet_get_context(sock);
2822 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2823 idata->sconn->remote_host, idata->sconn->remote_port,
2824 SILC_CONNTYPE_STRING(idata->conn_type)));
2827 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2828 server->public_key, server->private_key, sock);
2830 silc_packet_free(packet);
2834 /* Set SKE callbacks */
2835 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2838 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2843 /****************************** Disconnection *******************************/
2845 /* Destroys packet stream. */
2847 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2849 silc_packet_stream_destroy(context);
2852 /* Closes connection to socket connection */
2854 void silc_server_close_connection(SilcServer server,
2855 SilcPacketStream sock)
2857 SilcIDListData idata = silc_packet_get_context(sock);
2859 const char *hostname;
2862 memset(tmp, 0, sizeof(tmp));
2863 // silc_socket_get_error(sock, tmp, sizeof(tmp));
2864 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2865 NULL, &hostname, NULL, &port);
2866 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2867 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
2868 tmp[0] ? tmp : ""));
2870 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2872 if (idata && idata->sconn) {
2873 silc_server_connection_free(idata->sconn);
2874 idata->sconn = NULL;
2877 /* Close connection with timeout */
2878 server->stat.conn_num--;
2879 silc_schedule_task_del_by_all(server->schedule, 0,
2880 silc_server_close_connection_final, sock);
2881 silc_schedule_task_add_timeout(server->schedule,
2882 silc_server_close_connection_final,
2886 /* Sends disconnect message to remote connection and disconnects the
2889 void silc_server_disconnect_remote(SilcServer server,
2890 SilcPacketStream sock,
2891 SilcStatus status, ...)
2893 unsigned char buf[512];
2900 SILC_LOG_DEBUG(("Disconnecting remote host"));
2902 va_start(ap, status);
2903 cp = va_arg(ap, char *);
2905 silc_vsnprintf(buf, sizeof(buf), cp, ap);
2908 /* Send SILC_PACKET_DISCONNECT */
2909 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2910 SILC_STR_UI_CHAR(status),
2911 SILC_STR_UI8_STRING(cp ? buf : NULL),
2914 /* Close connection */
2915 silc_server_close_connection(server, sock);
2918 /* Frees client data and notifies about client's signoff. */
2920 void silc_server_free_client_data(SilcServer server,
2921 SilcPacketStream sock,
2922 SilcClientEntry client,
2924 const char *signoff)
2926 SILC_LOG_DEBUG(("Freeing client %p data", client));
2929 /* Check if anyone is watching this nickname */
2930 if (server->server_type == SILC_ROUTER)
2931 silc_server_check_watcher_list(server, client, NULL,
2932 SILC_NOTIFY_TYPE_SIGNOFF);
2934 /* Send SIGNOFF notify to routers. */
2936 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2937 SILC_BROADCAST(server), client->id,
2941 /* Remove client from all channels */
2943 silc_server_remove_from_channels(server, NULL, client,
2944 TRUE, (char *)signoff, TRUE, FALSE);
2946 silc_server_remove_from_channels(server, NULL, client,
2947 FALSE, NULL, FALSE, FALSE);
2949 /* Remove this client from watcher list if it is */
2950 silc_server_del_from_watcher_list(server, client);
2952 /* Remove client's public key from repository, this will free it too. */
2953 if (client->data.public_key) {
2954 silc_skr_del_public_key(server->repository, client->data.public_key,
2956 client->data.public_key = NULL;
2959 /* Update statistics */
2960 server->stat.my_clients--;
2961 server->stat.clients--;
2962 if (server->stat.cell_clients)
2963 server->stat.cell_clients--;
2964 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2965 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2966 silc_schedule_task_del_by_context(server->schedule, client);
2968 /* We will not delete the client entry right away. We will take it
2969 into history (for WHOWAS command) for 5 minutes, unless we're
2970 shutting down server. */
2971 if (!server->server_shutdown) {
2972 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2974 client->router = NULL;
2975 client->connection = NULL;
2976 client->data.created = silc_time();
2977 silc_dlist_add(server->expired_clients, client);
2979 /* Delete directly since we're shutting down server */
2980 SILC_LOG_DEBUG(("Delete client directly"));
2981 silc_idlist_del_data(client);
2982 silc_idlist_del_client(server->local_list, client);
2986 /* Frees user_data pointer from socket connection object. This also sends
2987 appropriate notify packets to the network to inform about leaving
2990 void silc_server_free_sock_user_data(SilcServer server,
2991 SilcPacketStream sock,
2992 const char *signoff_message)
2994 SilcIDListData idata = silc_packet_get_context(sock);
2996 SILC_LOG_DEBUG(("Start"));
3001 silc_schedule_task_del_by_context(server->schedule, sock);
3003 /* Cancel active protocols */
3005 if (idata->sconn && idata->sconn->op) {
3006 SILC_LOG_DEBUG(("Abort active protocol"));
3007 silc_async_abort(idata->sconn->op, NULL, NULL);
3009 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3010 ((SilcUnknownEntry)idata)->op) {
3011 SILC_LOG_DEBUG(("Abort active protocol"));
3012 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3016 switch (idata->conn_type) {
3017 case SILC_CONN_CLIENT:
3019 SilcClientEntry client_entry = (SilcClientEntry)idata;
3020 silc_server_free_client_data(server, sock, client_entry, TRUE,
3023 silc_server_connection_free(idata->sconn);
3024 silc_packet_set_context(sock, NULL);
3028 case SILC_CONN_SERVER:
3029 case SILC_CONN_ROUTER:
3031 SilcServerEntry user_data = (SilcServerEntry)idata;
3032 SilcServerEntry backup_router = NULL;
3034 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3037 backup_router = silc_server_backup_get(server, user_data->id);
3039 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3040 backup_router == server->id_entry &&
3041 idata->conn_type != SILC_CONN_ROUTER)
3042 backup_router = NULL;
3044 if (server->server_shutdown || server->backup_noswitch)
3045 backup_router = NULL;
3047 /* If this was our primary router connection then we're lost to
3048 the outside world. */
3049 if (server->router == user_data) {
3050 /* Check whether we have a backup router connection */
3051 if (!backup_router || backup_router == user_data) {
3052 if (!server->no_reconnect)
3053 silc_server_create_connections(server);
3054 server->id_entry->router = NULL;
3055 server->router = NULL;
3056 server->standalone = TRUE;
3057 server->backup_primary = FALSE;
3058 backup_router = NULL;
3060 if (server->id_entry != backup_router) {
3061 SILC_LOG_INFO(("New primary router is backup router %s",
3062 backup_router->server_name));
3063 server->id_entry->router = backup_router;
3064 server->router = backup_router;
3065 server->router_connect = time(0);
3066 server->backup_primary = TRUE;
3067 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3069 /* Send START_USE to backup router to indicate we have switched */
3070 silc_server_backup_send_start_use(server,
3071 backup_router->connection,
3074 SILC_LOG_INFO(("We are now new primary router in this cell"));
3075 server->id_entry->router = NULL;
3076 server->router = NULL;
3077 server->standalone = TRUE;
3080 /* We stop here to take a breath */
3084 if (server->backup_router) {
3085 server->server_type = SILC_ROUTER;
3087 /* We'll need to constantly try to reconnect to the primary
3088 router so that we'll see when it comes back online. */
3089 silc_server_backup_reconnect(server, sock->ip, sock->port,
3090 silc_server_backup_connected,
3095 /* Mark this connection as replaced */
3096 silc_server_backup_replaced_add(server, user_data->id,
3099 } else if (backup_router) {
3100 SILC_LOG_INFO(("Enabling the use of backup router %s",
3101 backup_router->server_name));
3103 /* Mark this connection as replaced */
3104 silc_server_backup_replaced_add(server, user_data->id,
3106 } else if (server->server_type == SILC_SERVER &&
3107 idata->conn_type == SILC_CONN_ROUTER) {
3108 /* Reconnect to the router (backup) */
3109 if (!server->no_reconnect)
3110 silc_server_create_connections(server);
3113 if (user_data->server_name)
3114 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3115 ("Server %s signoff", user_data->server_name));
3117 if (!backup_router) {
3118 /* Remove all servers that are originated from this server, and
3119 remove the clients of those servers too. */
3120 silc_server_remove_servers_by_server(server, user_data, TRUE);
3123 /* Remove the clients that this server owns as they will become
3124 invalid now too. For backup router the server is actually
3125 coming from the primary router, so mark that as the owner
3127 if (server->server_type == SILC_BACKUP_ROUTER &&
3128 sock->type == SILC_CONN_SERVER)
3129 silc_server_remove_clients_by_server(server, server->router,
3133 silc_server_remove_clients_by_server(server, user_data,
3136 /* Remove channels owned by this server */
3137 if (server->server_type == SILC_SERVER)
3138 silc_server_remove_channels_by_server(server, user_data);
3140 /* Enable local server connections that may be disabled */
3141 silc_server_local_servers_toggle_enabled(server, TRUE);
3143 /* Update the client entries of this server to the new backup
3144 router. If we are the backup router we also resolve the real
3145 servers for the clients. After updating is over this also
3146 removes the clients that this server explicitly owns. */
3147 silc_server_update_clients_by_server(server, user_data,
3148 backup_router, TRUE);
3150 /* If we are router and just lost our primary router (now standlaone)
3151 we remove everything that was behind it, since we don't know
3153 if (server->server_type == SILC_ROUTER && server->standalone)
3154 /* Remove all servers that are originated from this server, and
3155 remove the clients of those servers too. */
3156 silc_server_remove_servers_by_server(server, user_data, TRUE);
3158 /* Finally remove the clients that are explicitly owned by this
3159 server. They go down with the server. */
3160 silc_server_remove_clients_by_server(server, user_data,
3163 /* Update our server cache to use the new backup router too. */
3164 silc_server_update_servers_by_server(server, user_data, backup_router);
3165 if (server->server_type == SILC_SERVER)
3166 silc_server_update_channels_by_server(server, user_data,
3169 /* Send notify about primary router going down to local operators */
3170 if (server->backup_router)
3171 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3172 SILC_NOTIFY_TYPE_NONE,
3173 ("%s switched to backup router %s "
3174 "(we are primary router now)",
3175 server->server_name, server->server_name));
3176 else if (server->router)
3177 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3178 SILC_NOTIFY_TYPE_NONE,
3179 ("%s switched to backup router %s",
3180 server->server_name,
3181 server->router->server_name));
3183 server->backup_noswitch = FALSE;
3185 /* Free the server entry */
3186 silc_server_backup_del(server, user_data);
3187 silc_server_backup_replaced_del(server, user_data);
3188 silc_idlist_del_data(user_data);
3189 if (!silc_idlist_del_server(server->local_list, user_data))
3190 silc_idlist_del_server(server->global_list, user_data);
3191 if (idata->conn_type == SILC_CONN_SERVER) {
3192 server->stat.my_servers--;
3193 server->stat.servers--;
3195 server->stat.my_routers--;
3196 server->stat.routers--;
3198 if (server->server_type == SILC_ROUTER)
3199 server->stat.cell_servers--;
3201 if (backup_router && backup_router != server->id_entry) {
3202 /* Announce all of our stuff that was created about 5 minutes ago.
3203 The backup router knows all the other stuff already. */
3204 if (server->server_type == SILC_ROUTER)
3205 silc_server_announce_servers(server, FALSE, time(0) - 300,
3206 backup_router->connection);
3208 /* Announce our clients and channels to the router */
3209 silc_server_announce_clients(server, time(0) - 300,
3210 backup_router->connection);
3211 silc_server_announce_channels(server, time(0) - 300,
3212 backup_router->connection);
3216 silc_server_connection_free(idata->sconn);
3217 silc_packet_set_context(sock, NULL);
3223 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3225 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3228 silc_server_connection_free(idata->sconn);
3229 silc_idlist_del_data(idata);
3231 silc_packet_set_context(sock, NULL);
3237 /* Removes client from all channels it has joined. This is used when client
3238 connection is disconnected. If the client on a channel is last, the
3239 channel is removed as well. This sends the SIGNOFF notify types. */
3241 void silc_server_remove_from_channels(SilcServer server,
3242 SilcPacketStream sock,
3243 SilcClientEntry client,
3245 const char *signoff_message,
3249 SilcChannelEntry channel;
3250 SilcChannelClientEntry chl;
3251 SilcHashTableList htl;
3252 SilcBuffer clidp = NULL;
3257 if (notify && !client->id)
3260 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3261 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3264 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3269 /* Remove the client from all channels. The client is removed from
3270 the channels' user list. */
3271 silc_hash_table_list(client->channels, &htl);
3272 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3273 channel = chl->channel;
3275 /* Remove channel if this is last client leaving the channel, unless
3276 the channel is permanent. */
3277 if (server->server_type != SILC_SERVER &&
3278 silc_hash_table_count(channel->user_list) < 2) {
3279 silc_server_channel_delete(server, channel);
3283 silc_hash_table_del(client->channels, channel);
3284 silc_hash_table_del(channel->user_list, client);
3285 channel->user_count--;
3287 /* If there is no global users on the channel anymore mark the channel
3288 as local channel. Do not check if the removed client is local client. */
3289 if (server->server_type == SILC_SERVER && channel->global_users &&
3290 chl->client->router && !silc_server_channel_has_global(channel))
3291 channel->global_users = FALSE;
3293 memset(chl, 'A', sizeof(*chl));
3296 /* Update statistics */
3297 if (SILC_IS_LOCAL(client))
3298 server->stat.my_chanclients--;
3299 if (server->server_type == SILC_ROUTER) {
3300 server->stat.cell_chanclients--;
3301 server->stat.chanclients--;
3304 /* If there is not at least one local user on the channel then we don't
3305 need the channel entry anymore, we can remove it safely, unless the
3306 channel is permanent channel */
3307 if (server->server_type == SILC_SERVER &&
3308 !silc_server_channel_has_local(channel)) {
3309 /* Notify about leaving client if this channel has global users. */
3310 if (notify && channel->global_users)
3311 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3312 SILC_NOTIFY_TYPE_SIGNOFF,
3313 signoff_message ? 2 : 1,
3314 clidp->data, silc_buffer_len(clidp),
3315 signoff_message, signoff_message ?
3316 strlen(signoff_message) : 0);
3318 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3319 silc_server_channel_delete(server, channel);
3323 /* Send notify to channel about client leaving SILC and channel too */
3325 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3326 SILC_NOTIFY_TYPE_SIGNOFF,
3327 signoff_message ? 2 : 1,
3328 clidp->data, silc_buffer_len(clidp),
3329 signoff_message, signoff_message ?
3330 strlen(signoff_message) : 0);
3332 if (killed && clidp) {
3333 /* Remove the client from channel's invite list */
3334 if (channel->invite_list &&
3335 silc_hash_table_count(channel->invite_list)) {
3337 SilcArgumentPayload iargs;
3338 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3339 silc_buffer_len(clidp), 3);
3340 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3341 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3342 silc_buffer_free(ab);
3343 silc_argument_payload_free(iargs);
3347 /* Don't create keys if we are shutting down */
3348 if (server->server_shutdown)
3351 /* Re-generate channel key if needed */
3352 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3353 if (!silc_server_create_channel_key(server, channel, 0))
3356 /* Send the channel key to the channel. The key of course is not sent
3357 to the client who was removed from the channel. */
3358 silc_server_send_channel_key(server, client->connection, channel,
3359 server->server_type == SILC_ROUTER ?
3360 FALSE : !server->standalone);
3364 silc_hash_table_list_reset(&htl);
3366 silc_buffer_free(clidp);
3369 /* Removes client from one channel. This is used for example when client
3370 calls LEAVE command to remove itself from the channel. Returns TRUE
3371 if channel still exists and FALSE if the channel is removed when
3372 last client leaves the channel. If `notify' is FALSE notify messages
3375 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3376 SilcPacketStream sock,
3377 SilcChannelEntry channel,
3378 SilcClientEntry client,
3381 SilcChannelClientEntry chl;
3384 SILC_LOG_DEBUG(("Removing %s from channel %s",
3385 silc_id_render(client->id, SILC_ID_CLIENT),
3386 channel->channel_name));
3388 /* Get the entry to the channel, if this client is not on the channel
3390 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3393 /* Remove channel if this is last client leaving the channel, unless
3394 the channel is permanent. */
3395 if (server->server_type != SILC_SERVER &&
3396 silc_hash_table_count(channel->user_list) < 2) {
3397 silc_server_channel_delete(server, channel);
3401 silc_hash_table_del(client->channels, channel);
3402 silc_hash_table_del(channel->user_list, client);
3403 channel->user_count--;
3405 /* If there is no global users on the channel anymore mark the channel
3406 as local channel. Do not check if the client is local client. */
3407 if (server->server_type == SILC_SERVER && channel->global_users &&
3408 chl->client->router && !silc_server_channel_has_global(channel))
3409 channel->global_users = FALSE;
3411 memset(chl, 'O', sizeof(*chl));
3414 /* Update statistics */
3415 if (SILC_IS_LOCAL(client))
3416 server->stat.my_chanclients--;
3417 if (server->server_type == SILC_ROUTER) {
3418 server->stat.cell_chanclients--;
3419 server->stat.chanclients--;
3422 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3426 /* If there is not at least one local user on the channel then we don't
3427 need the channel entry anymore, we can remove it safely, unless the
3428 channel is permanent channel */
3429 if (server->server_type == SILC_SERVER &&
3430 !silc_server_channel_has_local(channel)) {
3431 /* Notify about leaving client if this channel has global users. */
3432 if (notify && channel->global_users)
3433 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3434 SILC_NOTIFY_TYPE_LEAVE, 1,
3435 clidp->data, silc_buffer_len(clidp));
3437 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3438 silc_server_channel_delete(server, channel);
3439 silc_buffer_free(clidp);
3443 /* Send notify to channel about client leaving the channel */
3445 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3446 SILC_NOTIFY_TYPE_LEAVE, 1,
3447 clidp->data, silc_buffer_len(clidp));
3449 silc_buffer_free(clidp);
3453 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3454 function may be used only by router. In real SILC network all channels
3455 are created by routers thus this function is never used by normal
3458 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3459 SilcServerID *router_id,
3465 SilcChannelID *channel_id;
3466 SilcChannelEntry entry;
3467 SilcCipher send_key, receive_key;
3470 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3473 cipher = SILC_DEFAULT_CIPHER;
3475 hmac = SILC_DEFAULT_HMAC;
3477 /* Allocate cipher */
3478 if (!silc_cipher_alloc(cipher, &send_key))
3480 if (!silc_cipher_alloc(cipher, &receive_key)) {
3481 silc_cipher_free(send_key);
3486 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3487 silc_cipher_free(send_key);
3488 silc_cipher_free(receive_key);
3492 channel_name = strdup(channel_name);
3494 /* Create the channel ID */
3495 if (!silc_id_create_channel_id(server, router_id, server->rng,
3497 silc_free(channel_name);
3498 silc_cipher_free(send_key);
3499 silc_cipher_free(receive_key);
3500 silc_hmac_free(newhmac);
3504 /* Create the channel */
3505 entry = silc_idlist_add_channel(server->local_list, channel_name,
3506 SILC_CHANNEL_MODE_NONE, channel_id,
3507 NULL, send_key, receive_key, newhmac);
3509 silc_free(channel_name);
3510 silc_cipher_free(send_key);
3511 silc_cipher_free(receive_key);
3512 silc_hmac_free(newhmac);
3513 silc_free(channel_id);
3517 entry->cipher = strdup(cipher);
3518 entry->hmac_name = strdup(hmac);
3520 /* Now create the actual key material */
3521 if (!silc_server_create_channel_key(server, entry,
3522 silc_cipher_get_key_len(send_key) / 8)) {
3523 silc_idlist_del_channel(server->local_list, entry);
3527 /* Notify other routers about the new channel. We send the packet
3528 to our primary route. */
3530 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3531 channel_name, entry->id,
3532 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3535 /* Distribute to backup routers */
3536 if (broadcast && server->server_type == SILC_ROUTER) {
3538 unsigned char cid[32];
3539 SilcUInt32 name_len = strlen(channel_name);
3542 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3543 packet = silc_channel_payload_encode(channel_name, name_len,
3544 cid, id_len, entry->mode);
3545 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3546 packet->data, silc_buffer_len(packet), FALSE,
3548 silc_buffer_free(packet);
3551 server->stat.my_channels++;
3552 if (server->server_type == SILC_ROUTER) {
3553 server->stat.channels++;
3554 server->stat.cell_channels++;
3555 entry->users_resolved = TRUE;
3561 /* Same as above but creates the channel with Channel ID `channel_id. */
3564 silc_server_create_new_channel_with_id(SilcServer server,
3568 SilcChannelID *channel_id,
3571 SilcChannelEntry entry;
3572 SilcCipher send_key, receive_key;
3575 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3578 cipher = SILC_DEFAULT_CIPHER;
3580 hmac = SILC_DEFAULT_HMAC;
3582 /* Allocate cipher */
3583 if (!silc_cipher_alloc(cipher, &send_key))
3585 if (!silc_cipher_alloc(cipher, &receive_key)) {
3586 silc_cipher_free(send_key);
3591 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3592 silc_cipher_free(send_key);
3593 silc_cipher_free(receive_key);
3597 channel_name = strdup(channel_name);
3599 /* Create the channel */
3600 entry = silc_idlist_add_channel(server->local_list, channel_name,
3601 SILC_CHANNEL_MODE_NONE, channel_id,
3602 NULL, send_key, receive_key, newhmac);
3604 silc_cipher_free(send_key);
3605 silc_cipher_free(receive_key);
3606 silc_hmac_free(newhmac);
3607 silc_free(channel_name);
3611 /* Now create the actual key material */
3612 if (!silc_server_create_channel_key(server, entry,
3613 silc_cipher_get_key_len(send_key) / 8)) {
3614 silc_idlist_del_channel(server->local_list, entry);
3618 /* Notify other routers about the new channel. We send the packet
3619 to our primary route. */
3621 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3622 channel_name, entry->id,
3623 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3626 /* Distribute to backup routers */
3627 if (broadcast && server->server_type == SILC_ROUTER) {
3629 unsigned char cid[32];
3630 SilcUInt32 name_len = strlen(channel_name);
3633 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3634 packet = silc_channel_payload_encode(channel_name, name_len,
3635 cid, id_len, entry->mode);
3636 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3637 packet->data, silc_buffer_len(packet), FALSE,
3639 silc_buffer_free(packet);
3642 server->stat.my_channels++;
3643 if (server->server_type == SILC_ROUTER) {
3644 server->stat.channels++;
3645 server->stat.cell_channels++;
3646 entry->users_resolved = TRUE;
3652 /* Channel's key re-key timeout callback. */
3654 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3656 SilcServer server = app_context;
3657 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3661 /* Return now if we are shutting down */
3662 if (server->server_shutdown)
3665 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3668 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3671 /* Generates new channel key. This is used to create the initial channel key
3672 but also to re-generate new key for channel. If `key_len' is provided
3673 it is the bytes of the key length. */
3675 SilcBool silc_server_create_channel_key(SilcServer server,
3676 SilcChannelEntry channel,
3680 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3683 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3684 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3688 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3690 if (!channel->send_key)
3691 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3692 channel->send_key = NULL;
3695 if (!channel->receive_key)
3696 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3697 silc_cipher_free(channel->send_key);
3698 channel->send_key = channel->receive_key = NULL;
3704 else if (channel->key_len)
3705 len = channel->key_len / 8;
3707 len = silc_cipher_get_key_len(channel->send_key) / 8;
3709 /* Create channel key */
3710 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3713 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3714 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3716 /* Remove old key if exists */
3718 memset(channel->key, 0, channel->key_len / 8);
3719 silc_free(channel->key);
3723 channel->key_len = len * 8;
3724 channel->key = silc_memdup(channel_key, len);
3725 memset(channel_key, 0, sizeof(channel_key));
3727 /* Generate HMAC key from the channel key data and set it */
3729 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3730 memset(channel->key, 0, channel->key_len / 8);
3731 silc_free(channel->key);
3732 silc_cipher_free(channel->send_key);
3733 silc_cipher_free(channel->receive_key);
3734 channel->send_key = channel->receive_key = NULL;
3737 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3738 silc_hmac_set_key(channel->hmac, hash,
3739 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3740 memset(hash, 0, sizeof(hash));
3742 if (server->server_type == SILC_ROUTER) {
3743 if (!channel->rekey)
3744 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3745 channel->rekey->channel = channel;
3746 channel->rekey->key_len = key_len;
3747 if (channel->rekey->task)
3748 silc_schedule_task_del(server->schedule, channel->rekey->task);
3750 channel->rekey->task =
3751 silc_schedule_task_add_timeout(server->schedule,
3752 silc_server_channel_key_rekey,
3753 (void *)channel->rekey,
3754 server->config->channel_rekey_secs, 0);
3760 /* Saves the channel key found in the encoded `key_payload' buffer. This
3761 function is used when we receive Channel Key Payload and also when we're
3762 processing JOIN command reply. Returns entry to the channel. */
3764 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3765 SilcBuffer key_payload,
3766 SilcChannelEntry channel)
3768 SilcChannelKeyPayload payload = NULL;
3770 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3774 /* Decode channel key payload */
3775 payload = silc_channel_key_payload_parse(key_payload->data,
3776 silc_buffer_len(key_payload));
3778 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3783 /* Get the channel entry */
3786 /* Get channel ID */
3787 tmp = silc_channel_key_get_id(payload, &tmp_len);
3788 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3793 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3795 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3797 if (server->server_type == SILC_ROUTER)
3798 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3799 silc_id_render(&id, SILC_ID_CHANNEL)));
3805 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3807 tmp = silc_channel_key_get_key(payload, &tmp_len);
3813 cipher = silc_channel_key_get_cipher(payload, NULL);
3819 /* Remove old key if exists */
3821 memset(channel->key, 0, channel->key_len / 8);
3822 silc_free(channel->key);
3823 silc_cipher_free(channel->send_key);
3824 silc_cipher_free(channel->receive_key);
3827 /* Create new cipher */
3828 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3829 channel->send_key = NULL;
3833 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3834 silc_cipher_free(channel->send_key);
3835 channel->send_key = channel->receive_key = NULL;
3840 if (channel->cipher)
3841 silc_free(channel->cipher);
3842 channel->cipher = strdup(cipher);
3845 channel->key_len = tmp_len * 8;
3846 channel->key = silc_memdup(tmp, tmp_len);
3847 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3848 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3850 /* Generate HMAC key from the channel key data and set it */
3852 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3853 memset(channel->key, 0, channel->key_len / 8);
3854 silc_free(channel->key);
3855 silc_cipher_free(channel->send_key);
3856 silc_cipher_free(channel->receive_key);
3857 channel->send_key = channel->receive_key = NULL;
3860 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3861 silc_hmac_set_key(channel->hmac, hash,
3862 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3864 memset(hash, 0, sizeof(hash));
3865 memset(tmp, 0, tmp_len);
3867 if (server->server_type == SILC_ROUTER) {
3868 if (!channel->rekey)
3869 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3870 channel->rekey->channel = channel;
3871 if (channel->rekey->task)
3872 silc_schedule_task_del(server->schedule, channel->rekey->task);
3874 channel->rekey->task =
3875 silc_schedule_task_add_timeout(server->schedule,
3876 silc_server_channel_key_rekey,
3877 (void *)channel->rekey,
3878 server->config->channel_rekey_secs, 0);
3883 silc_channel_key_payload_free(payload);
3888 /* Returns assembled of all servers in the given ID list. The packet's
3889 form is dictated by the New ID payload. */
3891 static void silc_server_announce_get_servers(SilcServer server,
3892 SilcServerEntry remote,
3894 SilcBuffer *servers,
3895 unsigned long creation_time)
3898 SilcIDCacheEntry id_cache;
3899 SilcServerEntry entry;
3902 /* Go through all clients in the list */
3903 if (silc_idcache_get_all(id_list->servers, &list)) {
3904 silc_list_start(list);
3905 while ((id_cache = silc_list_get(list))) {
3906 entry = (SilcServerEntry)id_cache->context;
3908 /* Do not announce the one we've sending our announcements and
3909 do not announce ourself. Also check the creation time if it's
3911 if ((entry == remote) || (entry == server->id_entry) ||
3912 (creation_time && entry->data.created < creation_time))
3915 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3917 *servers = silc_buffer_realloc(*servers,
3919 silc_buffer_truelen((*servers)) +
3920 silc_buffer_len(idp) :
3921 silc_buffer_len(idp)));
3922 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3923 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3924 silc_buffer_pull(*servers, silc_buffer_len(idp));
3925 silc_buffer_free(idp);
3931 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3937 p = silc_notify_payload_encode(notify, argc, ap);
3943 /* This function is used by router to announce existing servers to our
3944 primary router when we've connected to it. If `creation_time' is non-zero
3945 then only the servers that has been created after the `creation_time'
3946 will be announced. */
3948 void silc_server_announce_servers(SilcServer server, SilcBool global,
3949 unsigned long creation_time,
3950 SilcPacketStream remote)
3952 SilcBuffer servers = NULL;
3954 SILC_LOG_DEBUG(("Announcing servers"));
3956 /* Get servers in local list */
3957 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3958 server->local_list, &servers,
3962 /* Get servers in global list */
3963 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3964 server->global_list, &servers,
3968 silc_buffer_push(servers, servers->data - servers->head);
3969 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
3971 /* Send the packet */
3972 silc_server_packet_send(server, remote,
3973 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3974 servers->data, silc_buffer_len(servers));
3976 silc_buffer_free(servers);
3980 /* Returns assembled packet of all clients in the given ID list. The
3981 packet's form is dictated by the New ID Payload. */
3983 static void silc_server_announce_get_clients(SilcServer server,
3985 SilcBuffer *clients,
3987 unsigned long creation_time)
3990 SilcIDCacheEntry id_cache;
3991 SilcClientEntry client;
3994 unsigned char mode[4];
3996 /* Go through all clients in the list */
3997 if (silc_idcache_get_all(id_list->clients, &list)) {
3998 silc_list_start(list);
3999 while ((id_cache = silc_list_get(list))) {
4000 client = (SilcClientEntry)id_cache->context;
4002 if (creation_time && client->data.created < creation_time)
4004 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4006 if (!client->connection && !client->router)
4009 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4011 *clients = silc_buffer_realloc(*clients,
4013 silc_buffer_truelen((*clients)) +
4014 silc_buffer_len(idp) :
4015 silc_buffer_len(idp)));
4016 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4017 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4018 silc_buffer_pull(*clients, silc_buffer_len(idp));
4020 SILC_PUT32_MSB(client->mode, mode);
4022 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4023 2, idp->data, silc_buffer_len(idp),
4025 *umodes = silc_buffer_realloc(*umodes,
4027 silc_buffer_truelen((*umodes)) +
4028 silc_buffer_len(tmp) :
4029 silc_buffer_len(tmp)));
4030 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4031 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4032 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4033 silc_buffer_free(tmp);
4035 silc_buffer_free(idp);
4040 /* This function is used to announce our existing clients to our router
4041 when we've connected to it. If `creation_time' is non-zero then only
4042 the clients that has been created after the `creation_time' will be
4045 void silc_server_announce_clients(SilcServer server,
4046 unsigned long creation_time,
4047 SilcPacketStream remote)
4049 SilcBuffer clients = NULL;
4050 SilcBuffer umodes = NULL;
4052 SILC_LOG_DEBUG(("Announcing clients"));
4054 /* Get clients in local list */
4055 silc_server_announce_get_clients(server, server->local_list,
4056 &clients, &umodes, creation_time);
4058 /* As router we announce our global list as well */
4059 if (server->server_type == SILC_ROUTER)
4060 silc_server_announce_get_clients(server, server->global_list,
4061 &clients, &umodes, creation_time);
4064 silc_buffer_push(clients, clients->data - clients->head);
4065 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4067 /* Send the packet */
4068 silc_server_packet_send(server, remote,
4069 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4070 clients->data, silc_buffer_len(clients));
4072 silc_buffer_free(clients);
4076 silc_buffer_push(umodes, umodes->data - umodes->head);
4077 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4079 /* Send the packet */
4080 silc_server_packet_send(server, remote,
4081 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4082 umodes->data, silc_buffer_len(umodes));
4084 silc_buffer_free(umodes);
4088 /* Returns channel's topic for announcing it */
4090 void silc_server_announce_get_channel_topic(SilcServer server,
4091 SilcChannelEntry channel,
4096 if (channel->topic) {
4097 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4098 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4100 silc_buffer_len(chidp),
4102 strlen(channel->topic));
4103 silc_buffer_free(chidp);
4107 /* Returns channel's invite and ban lists */
4109 void silc_server_announce_get_inviteban(SilcServer server,
4110 SilcChannelEntry channel,
4114 SilcBuffer list, idp, idp2, tmp2;
4116 SilcHashTableList htl;
4117 const unsigned char a[1] = { 0x03 };
4119 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4121 /* Encode invite list */
4122 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4123 list = silc_buffer_alloc_size(2);
4124 type = silc_hash_table_count(channel->invite_list);
4125 SILC_PUT16_MSB(type, list->data);
4126 silc_hash_table_list(channel->invite_list, &htl);
4127 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4128 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4130 silc_hash_table_list_reset(&htl);
4132 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4134 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4135 idp->data, silc_buffer_len(idp),
4136 channel->channel_name,
4137 strlen(channel->channel_name),
4138 idp2->data, silc_buffer_len(idp2),
4140 list->data, silc_buffer_len(list));
4141 silc_buffer_free(idp2);
4142 silc_buffer_free(list);
4145 /* Encode ban list */
4146 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4147 list = silc_buffer_alloc_size(2);
4148 type = silc_hash_table_count(channel->ban_list);
4149 SILC_PUT16_MSB(type, list->data);
4150 silc_hash_table_list(channel->ban_list, &htl);
4151 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4152 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4154 silc_hash_table_list_reset(&htl);
4157 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4158 idp->data, silc_buffer_len(idp),
4160 list->data, silc_buffer_len(list));
4161 silc_buffer_free(list);
4164 silc_buffer_free(idp);
4167 /* Returns assembled packets for channel users of the `channel'. */
4169 void silc_server_announce_get_channel_users(SilcServer server,
4170 SilcChannelEntry channel,
4171 SilcBuffer *channel_modes,
4172 SilcBuffer *channel_users,
4173 SilcBuffer *channel_users_modes)
4175 SilcChannelClientEntry chl;
4176 SilcHashTableList htl;
4177 SilcBuffer chidp, clidp, csidp;
4178 SilcBuffer tmp, fkey = NULL, chpklist;
4180 unsigned char mode[4], ulimit[4];
4183 SILC_LOG_DEBUG(("Start"));
4185 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4186 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4187 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4190 SILC_PUT32_MSB(channel->mode, mode);
4191 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4192 SILC_PUT32_MSB(channel->user_limit, ulimit);
4193 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4194 if (channel->founder_key)
4195 fkey = silc_public_key_payload_encode(channel->founder_key);
4197 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4199 silc_buffer_len(csidp),
4202 hmac, hmac ? strlen(hmac) : 0,
4203 channel->passphrase,
4204 channel->passphrase ?
4205 strlen(channel->passphrase) : 0,
4206 fkey ? fkey->data : NULL,
4207 fkey ? silc_buffer_len(fkey) : 0,
4208 chpklist ? chpklist->data : NULL,
4210 silc_buffer_len(chpklist) : 0,
4212 SILC_CHANNEL_MODE_ULIMIT ?
4215 SILC_CHANNEL_MODE_ULIMIT ?
4216 sizeof(ulimit) : 0));
4217 len = silc_buffer_len(tmp);
4219 silc_buffer_realloc(*channel_modes,
4221 silc_buffer_truelen((*channel_modes)) + len : len));
4222 silc_buffer_pull_tail(*channel_modes,
4223 ((*channel_modes)->end -
4224 (*channel_modes)->data));
4225 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4226 silc_buffer_pull(*channel_modes, len);
4227 silc_buffer_free(tmp);
4228 silc_buffer_free(fkey);
4231 /* Now find all users on the channel */
4232 silc_hash_table_list(channel->user_list, &htl);
4233 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4234 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4237 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4239 silc_buffer_len(clidp),
4241 silc_buffer_len(chidp));
4242 len = silc_buffer_len(tmp);
4244 silc_buffer_realloc(*channel_users,
4246 silc_buffer_truelen((*channel_users)) + len : len));
4247 silc_buffer_pull_tail(*channel_users,
4248 ((*channel_users)->end -
4249 (*channel_users)->data));
4251 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4252 silc_buffer_pull(*channel_users, len);
4253 silc_buffer_free(tmp);
4255 /* CUMODE notify for mode change on the channel */
4256 SILC_PUT32_MSB(chl->mode, mode);
4257 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4258 fkey = silc_public_key_payload_encode(channel->founder_key);
4259 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4261 silc_buffer_len(csidp),
4264 silc_buffer_len(clidp),
4265 fkey ? fkey->data : NULL,
4266 fkey ? silc_buffer_len(fkey) : 0);
4267 len = silc_buffer_len(tmp);
4268 *channel_users_modes =
4269 silc_buffer_realloc(*channel_users_modes,
4270 (*channel_users_modes ?
4271 silc_buffer_truelen((*channel_users_modes)) +
4273 silc_buffer_pull_tail(*channel_users_modes,
4274 ((*channel_users_modes)->end -
4275 (*channel_users_modes)->data));
4277 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4278 silc_buffer_pull(*channel_users_modes, len);
4279 silc_buffer_free(tmp);
4280 silc_buffer_free(fkey);
4282 silc_buffer_free(clidp);
4284 silc_hash_table_list_reset(&htl);
4285 silc_buffer_free(chidp);
4286 silc_buffer_free(csidp);
4289 /* Returns assembled packets for all channels and users on those channels
4290 from the given ID List. The packets are in the form dictated by the
4291 New Channel and New Channel User payloads. */
4293 void silc_server_announce_get_channels(SilcServer server,
4295 SilcBuffer *channels,
4296 SilcBuffer **channel_modes,
4297 SilcBuffer *channel_users,
4298 SilcBuffer **channel_users_modes,
4299 SilcUInt32 *channel_users_modes_c,
4300 SilcBuffer **channel_topics,
4301 SilcBuffer **channel_invites,
4302 SilcBuffer **channel_bans,
4303 SilcChannelID ***channel_ids,
4304 unsigned long creation_time)
4307 SilcIDCacheEntry id_cache;
4308 SilcChannelEntry channel;
4309 unsigned char cid[32];
4311 SilcUInt16 name_len;
4313 int i = *channel_users_modes_c;
4316 SILC_LOG_DEBUG(("Start"));
4318 /* Go through all channels in the list */
4319 if (silc_idcache_get_all(id_list->channels, &list)) {
4320 silc_list_start(list);
4321 while ((id_cache = silc_list_get(list))) {
4322 channel = (SilcChannelEntry)id_cache->context;
4324 if (creation_time && channel->created < creation_time)
4329 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4330 name_len = strlen(channel->channel_name);
4333 len = 4 + name_len + id_len + 4;
4335 silc_buffer_realloc(*channels,
4337 silc_buffer_truelen((*channels)) +
4339 silc_buffer_pull_tail(*channels,
4340 ((*channels)->end - (*channels)->data));
4341 silc_buffer_format(*channels,
4342 SILC_STR_UI_SHORT(name_len),
4343 SILC_STR_UI_XNSTRING(channel->channel_name,
4345 SILC_STR_UI_SHORT(id_len),
4346 SILC_STR_UI_XNSTRING(cid, id_len),
4347 SILC_STR_UI_INT(channel->mode),
4349 silc_buffer_pull(*channels, len);
4352 if (creation_time && channel->updated < creation_time)
4358 /* Channel user modes */
4359 *channel_users_modes = silc_realloc(*channel_users_modes,
4360 sizeof(**channel_users_modes) *
4362 (*channel_users_modes)[i] = NULL;
4363 *channel_modes = silc_realloc(*channel_modes,
4364 sizeof(**channel_modes) * (i + 1));
4365 (*channel_modes)[i] = NULL;
4366 *channel_ids = silc_realloc(*channel_ids,
4367 sizeof(**channel_ids) * (i + 1));
4368 (*channel_ids)[i] = NULL;
4369 silc_server_announce_get_channel_users(server, channel,
4370 &(*channel_modes)[i],
4372 &(*channel_users_modes)[i]);
4373 (*channel_ids)[i] = channel->id;
4375 /* Channel's topic */
4376 *channel_topics = silc_realloc(*channel_topics,
4377 sizeof(**channel_topics) * (i + 1));
4378 (*channel_topics)[i] = NULL;
4379 silc_server_announce_get_channel_topic(server, channel,
4380 &(*channel_topics)[i]);
4382 /* Channel's invite and ban list */
4383 *channel_invites = silc_realloc(*channel_invites,
4384 sizeof(**channel_invites) * (i + 1));
4385 (*channel_invites)[i] = NULL;
4386 *channel_bans = silc_realloc(*channel_bans,
4387 sizeof(**channel_bans) * (i + 1));
4388 (*channel_bans)[i] = NULL;
4389 silc_server_announce_get_inviteban(server, channel,
4390 &(*channel_invites)[i],
4391 &(*channel_bans)[i]);
4393 (*channel_users_modes_c)++;
4401 /* This function is used to announce our existing channels to our router
4402 when we've connected to it. This also announces the users on the
4403 channels to the router. If the `creation_time' is non-zero only the
4404 channels that was created after the `creation_time' are announced.
4405 Note that the channel users are still announced even if the `creation_time'
4408 void silc_server_announce_channels(SilcServer server,
4409 unsigned long creation_time,
4410 SilcPacketStream remote)
4412 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4413 SilcBuffer *channel_users_modes = NULL;
4414 SilcBuffer *channel_topics = NULL;
4415 SilcBuffer *channel_invites = NULL;
4416 SilcBuffer *channel_bans = NULL;
4417 SilcUInt32 channel_users_modes_c = 0;
4418 SilcChannelID **channel_ids = NULL;
4420 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4422 /* Get channels and channel users in local list */
4423 silc_server_announce_get_channels(server, server->local_list,
4424 &channels, &channel_modes,
4426 &channel_users_modes,
4427 &channel_users_modes_c,
4431 &channel_ids, creation_time);
4433 /* Get channels and channel users in global list */
4434 if (server->server_type != SILC_SERVER)
4435 silc_server_announce_get_channels(server, server->global_list,
4436 &channels, &channel_modes,
4438 &channel_users_modes,
4439 &channel_users_modes_c,
4443 &channel_ids, creation_time);
4446 silc_buffer_push(channels, channels->data - channels->head);
4447 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4449 /* Send the packet */
4450 silc_server_packet_send(server, remote,
4451 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4452 channels->data, silc_buffer_len(channels));
4454 silc_buffer_free(channels);
4457 if (channel_users) {
4458 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4459 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4460 silc_buffer_len(channel_users));
4462 /* Send the packet */
4463 silc_server_packet_send(server, remote,
4464 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4465 channel_users->data, silc_buffer_len(channel_users));
4467 silc_buffer_free(channel_users);
4470 if (channel_modes) {
4473 for (i = 0; i < channel_users_modes_c; i++) {
4474 if (!channel_modes[i])
4476 silc_buffer_push(channel_modes[i],
4477 channel_modes[i]->data -
4478 channel_modes[i]->head);
4479 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4480 silc_buffer_len(channel_modes[i]));
4481 silc_server_packet_send_dest(server, remote,
4482 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4483 channel_ids[i], SILC_ID_CHANNEL,
4484 channel_modes[i]->data,
4485 silc_buffer_len(channel_modes[i]));
4486 silc_buffer_free(channel_modes[i]);
4488 silc_free(channel_modes);
4491 if (channel_users_modes) {
4494 for (i = 0; i < channel_users_modes_c; i++) {
4495 if (!channel_users_modes[i])
4497 silc_buffer_push(channel_users_modes[i],
4498 channel_users_modes[i]->data -
4499 channel_users_modes[i]->head);
4500 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4501 silc_buffer_len(channel_users_modes[i]));
4502 silc_server_packet_send_dest(server, remote,
4503 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4504 channel_ids[i], SILC_ID_CHANNEL,
4505 channel_users_modes[i]->data,
4506 silc_buffer_len(channel_users_modes[i]));
4507 silc_buffer_free(channel_users_modes[i]);
4509 silc_free(channel_users_modes);
4512 if (channel_topics) {
4515 for (i = 0; i < channel_users_modes_c; i++) {
4516 if (!channel_topics[i])
4519 silc_buffer_push(channel_topics[i],
4520 channel_topics[i]->data -
4521 channel_topics[i]->head);
4522 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4523 silc_buffer_len(channel_topics[i]));
4524 silc_server_packet_send_dest(server, remote,
4525 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4526 channel_ids[i], SILC_ID_CHANNEL,
4527 channel_topics[i]->data,
4528 silc_buffer_len(channel_topics[i]));
4529 silc_buffer_free(channel_topics[i]);
4531 silc_free(channel_topics);
4534 if (channel_invites) {
4537 for (i = 0; i < channel_users_modes_c; i++) {
4538 if (!channel_invites[i])
4541 silc_buffer_push(channel_invites[i],
4542 channel_invites[i]->data -
4543 channel_invites[i]->head);
4544 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4545 silc_buffer_len(channel_invites[i]));
4546 silc_server_packet_send_dest(server, remote,
4547 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4548 channel_ids[i], SILC_ID_CHANNEL,
4549 channel_invites[i]->data,
4550 silc_buffer_len(channel_invites[i]));
4551 silc_buffer_free(channel_invites[i]);
4553 silc_free(channel_invites);
4559 for (i = 0; i < channel_users_modes_c; i++) {
4560 if (!channel_bans[i])
4563 silc_buffer_push(channel_bans[i],
4564 channel_bans[i]->data -
4565 channel_bans[i]->head);
4566 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4567 silc_buffer_len(channel_bans[i]));
4568 silc_server_packet_send_dest(server, remote,
4569 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4570 channel_ids[i], SILC_ID_CHANNEL,
4571 channel_bans[i]->data,
4572 silc_buffer_len(channel_bans[i]));
4573 silc_buffer_free(channel_bans[i]);
4575 silc_free(channel_bans);
4578 silc_free(channel_ids);
4581 /* Announces WATCH list. */
4583 void silc_server_announce_watches(SilcServer server,
4584 SilcPacketStream remote)
4586 SilcHashTableList htl;
4587 SilcBuffer buffer, idp, args, pkp;
4588 SilcClientEntry client;
4591 SILC_LOG_DEBUG(("Announcing watch list"));
4593 /* XXX because way we save the nicks (hash) we cannot announce them. */
4595 /* XXX we should send all public keys in one command if client is
4596 watching more than one key */
4597 silc_hash_table_list(server->watcher_list_pk, &htl);
4598 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4599 if (!client || !client->id)
4602 server->stat.commands_sent++;
4604 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4605 args = silc_buffer_alloc_size(2);
4606 silc_buffer_format(args,
4607 SILC_STR_UI_SHORT(1),
4609 pkp = silc_public_key_payload_encode(key);
4610 args = silc_argument_payload_encode_one(args, pkp->data,
4611 silc_buffer_len(pkp), 0x00);
4612 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4613 ++server->cmd_ident, 2,
4614 1, idp->data, silc_buffer_len(idp),
4616 silc_buffer_len(args));
4619 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4620 buffer->data, silc_buffer_len(buffer));
4622 silc_buffer_free(pkp);
4623 silc_buffer_free(args);
4624 silc_buffer_free(idp);
4625 silc_buffer_free(buffer);
4627 silc_hash_table_list_reset(&htl);
4630 /* Assembles user list and users mode list from the `channel'. */
4632 SilcBool silc_server_get_users_on_channel(SilcServer server,
4633 SilcChannelEntry channel,
4634 SilcBuffer *user_list,
4635 SilcBuffer *mode_list,
4636 SilcUInt32 *user_count)
4638 SilcChannelClientEntry chl;
4639 SilcHashTableList htl;
4640 SilcBuffer client_id_list;
4641 SilcBuffer client_mode_list;
4643 SilcUInt32 list_count = 0, len = 0;
4645 if (!silc_hash_table_count(channel->user_list))
4648 silc_hash_table_list(channel->user_list, &htl);
4649 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4650 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4651 silc_hash_table_list_reset(&htl);
4653 client_id_list = silc_buffer_alloc(len);
4655 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4656 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4657 silc_buffer_pull_tail(client_mode_list,
4658 silc_buffer_truelen(client_mode_list));
4660 silc_hash_table_list(channel->user_list, &htl);
4661 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4663 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4664 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4665 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4666 silc_buffer_free(idp);
4668 /* Client's mode on channel */
4669 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4670 silc_buffer_pull(client_mode_list, 4);
4674 silc_hash_table_list_reset(&htl);
4675 silc_buffer_push(client_id_list,
4676 client_id_list->data - client_id_list->head);
4677 silc_buffer_push(client_mode_list,
4678 client_mode_list->data - client_mode_list->head);
4680 *user_list = client_id_list;
4681 *mode_list = client_mode_list;
4682 *user_count = list_count;
4686 /* Saves users and their modes to the `channel'. */
4688 void silc_server_save_users_on_channel(SilcServer server,
4689 SilcPacketStream sock,
4690 SilcChannelEntry channel,
4691 SilcClientID *noadd,
4692 SilcBuffer user_list,
4693 SilcBuffer mode_list,
4694 SilcUInt32 user_count)
4700 SilcClientEntry client;
4701 SilcIDCacheEntry cache;
4702 SilcChannelClientEntry chl;
4704 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4705 channel->channel_name));
4707 for (i = 0; i < user_count; i++) {
4709 SILC_GET16_MSB(idp_len, user_list->data + 2);
4711 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4713 silc_buffer_pull(user_list, idp_len);
4716 SILC_GET32_MSB(mode, mode_list->data);
4717 silc_buffer_pull(mode_list, 4);
4719 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4724 /* Check if we have this client cached already. */
4725 client = silc_idlist_find_client_by_id(server->local_list,
4727 server->server_type, &cache);
4729 client = silc_idlist_find_client_by_id(server->global_list,
4731 server->server_type, &cache);
4733 /* If router did not find such Client ID in its lists then this must
4734 be bogus client or some router in the net is buggy. */
4735 if (server->server_type != SILC_SERVER)
4738 /* We don't have that client anywhere, add it. The client is added
4739 to global list since server didn't have it in the lists so it must be
4741 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4742 silc_id_dup(&id.u.client_id,
4744 silc_packet_get_context(sock),
4747 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4751 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4754 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4755 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4756 "%s", channel->channel_name));
4760 if (!silc_server_client_on_channel(client, channel, &chl)) {
4761 /* Client was not on the channel, add it. */
4762 chl = silc_calloc(1, sizeof(*chl));
4763 chl->client = client;
4765 chl->channel = channel;
4766 silc_hash_table_add(channel->user_list, chl->client, chl);
4767 silc_hash_table_add(client->channels, chl->channel, chl);
4768 channel->user_count++;
4776 /* Saves channels and channels user modes to the `client'. Removes
4777 the client from those channels that are not sent in the list but
4780 void silc_server_save_user_channels(SilcServer server,
4781 SilcPacketStream sock,
4782 SilcClientEntry client,
4783 SilcBuffer channels,
4784 SilcBuffer channels_user_modes)
4787 SilcUInt32 *chumodes;
4788 SilcChannelPayload entry;
4789 SilcChannelEntry channel;
4790 SilcChannelID channel_id;
4791 SilcChannelClientEntry chl;
4792 SilcHashTable ht = NULL;
4793 SilcHashTableList htl;
4797 if (!channels || !channels_user_modes ||
4798 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4801 ch = silc_channel_payload_parse_list(channels->data,
4802 silc_buffer_len(channels));
4803 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4805 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4806 NULL, NULL, NULL, TRUE);
4807 silc_dlist_start(ch);
4808 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4809 /* Check if we have this channel, and add it if we don't have it.
4810 Also add the client on the channel unless it is there already. */
4811 if (!silc_channel_get_id_parse(entry, &channel_id))
4813 channel = silc_idlist_find_channel_by_id(server->local_list,
4816 channel = silc_idlist_find_channel_by_id(server->global_list,
4819 if (server->server_type != SILC_SERVER) {
4824 /* We don't have that channel anywhere, add it. */
4825 name = silc_channel_get_name(entry, NULL);
4826 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4827 silc_id_dup(&channel_id,
4829 server->router, NULL, NULL, 0);
4836 channel->mode = silc_channel_get_mode(entry);
4838 /* Add the client on the channel */
4839 if (!silc_server_client_on_channel(client, channel, &chl)) {
4840 chl = silc_calloc(1, sizeof(*chl));
4841 chl->client = client;
4842 chl->mode = chumodes[i++];
4843 chl->channel = channel;
4844 silc_hash_table_add(channel->user_list, chl->client, chl);
4845 silc_hash_table_add(client->channels, chl->channel, chl);
4846 channel->user_count++;
4849 chl->mode = chumodes[i++];
4852 silc_hash_table_add(ht, channel, channel);
4854 silc_channel_payload_list_free(ch);
4855 silc_free(chumodes);
4859 /* Go through the list again and remove client from channels that
4860 are no part of the list. */
4862 silc_hash_table_list(client->channels, &htl);
4863 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4864 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4865 silc_hash_table_del(chl->channel->user_list, chl->client);
4866 silc_hash_table_del(chl->client->channels, chl->channel);
4870 silc_hash_table_list_reset(&htl);
4871 silc_hash_table_free(ht);
4873 silc_hash_table_list(client->channels, &htl);
4874 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4875 silc_hash_table_del(chl->channel->user_list, chl->client);
4876 silc_hash_table_del(chl->client->channels, chl->channel);
4879 silc_hash_table_list_reset(&htl);
4883 /* Lookups route to the client indicated by the `id_data'. The connection
4884 object and internal data object is returned. Returns NULL if route
4885 could not be found to the client. If the `client_id' is specified then
4886 it is used and the `id_data' is ignored. */
4889 silc_server_get_client_route(SilcServer server,
4890 unsigned char *id_data,
4892 SilcClientID *client_id,
4893 SilcIDListData *idata,
4894 SilcClientEntry *client_entry)
4896 SilcClientID *id, clid;
4897 SilcClientEntry client;
4899 SILC_LOG_DEBUG(("Start"));
4902 *client_entry = NULL;
4904 /* Decode destination Client ID */
4906 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
4908 id = silc_id_dup(&clid, SILC_ID_CLIENT);
4910 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4913 /* If the destination belongs to our server we don't have to route
4914 the packet anywhere but to send it to the local destination. */
4915 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4919 /* If we are router and the client has router then the client is in
4920 our cell but not directly connected to us. */
4921 if (server->server_type == SILC_ROUTER && client->router) {
4922 /* We are of course in this case the client's router thus the route
4923 to the client is the server who owns the client. So, we will send
4924 the packet to that server. */
4926 *idata = (SilcIDListData)client->router;
4927 return client->router->connection;
4930 /* Seems that client really is directly connected to us */
4932 *idata = (SilcIDListData)client;
4934 *client_entry = client;
4935 return client->connection;
4938 /* Destination belongs to someone not in this server. If we are normal
4939 server our action is to send the packet to our router. */
4940 if (server->server_type != SILC_ROUTER && !server->standalone) {
4943 *idata = (SilcIDListData)server->router;
4944 return SILC_PRIMARY_ROUTE(server);
4947 /* We are router and we will perform route lookup for the destination
4948 and send the packet to fastest route. */
4949 if (server->server_type == SILC_ROUTER && !server->standalone) {
4950 /* Check first that the ID is valid */
4951 client = silc_idlist_find_client_by_id(server->global_list, id,
4954 SilcPacketStream dst_sock;
4956 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4959 if (idata && dst_sock)
4960 *idata = silc_packet_get_context(dst_sock);
4969 /* Encodes and returns channel list of channels the `client' has joined.
4970 Secret channels are not put to the list. */
4972 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4973 SilcClientEntry client,
4974 SilcBool get_private,
4975 SilcBool get_secret,
4976 SilcBuffer *user_mode_list)
4978 SilcBuffer buffer = NULL;
4979 SilcChannelEntry channel;
4980 SilcChannelClientEntry chl;
4981 SilcHashTableList htl;
4982 unsigned char cid[32];
4984 SilcUInt16 name_len;
4988 *user_mode_list = NULL;
4990 silc_hash_table_list(client->channels, &htl);
4991 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4992 channel = chl->channel;
4994 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4996 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4999 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5000 name_len = strlen(channel->channel_name);
5002 len = 4 + name_len + id_len + 4;
5003 buffer = silc_buffer_realloc(buffer,
5005 silc_buffer_truelen(buffer) + len : len));
5006 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5007 silc_buffer_format(buffer,
5008 SILC_STR_UI_SHORT(name_len),
5009 SILC_STR_DATA(channel->channel_name, name_len),
5010 SILC_STR_UI_SHORT(id_len),
5011 SILC_STR_DATA(cid, id_len),
5012 SILC_STR_UI_INT(chl->channel->mode),
5014 silc_buffer_pull(buffer, len);
5016 if (user_mode_list) {
5018 silc_buffer_realloc(*user_mode_list,
5020 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5021 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5022 (*user_mode_list)->data));
5023 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5024 silc_buffer_pull(*user_mode_list, 4);
5027 silc_hash_table_list_reset(&htl);
5030 silc_buffer_push(buffer, buffer->data - buffer->head);
5031 if (user_mode_list && *user_mode_list)
5032 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5033 (*user_mode_list)->head));
5038 /* Task callback used to retrieve network statistical information from
5039 router server once in a while. */
5041 SILC_TASK_CALLBACK(silc_server_get_stats)
5043 SilcServer server = (SilcServer)context;
5044 SilcBuffer idp, packet;
5046 if (!server->standalone) {
5047 SILC_LOG_DEBUG(("Retrieving stats from router"));
5048 server->stat.commands_sent++;
5049 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5051 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5052 ++server->cmd_ident, 1,
5054 silc_buffer_len(idp));
5055 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5056 SILC_PACKET_COMMAND, 0, packet->data,
5057 silc_buffer_len(packet));
5058 silc_buffer_free(packet);
5059 silc_buffer_free(idp);
5063 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,