5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /************************* Types and definitions ****************************/
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
28 SILC_TASK_CALLBACK(silc_server_do_rekey);
29 SILC_TASK_CALLBACK(silc_server_purge_expired_clients);
30 static void silc_server_accept_new_connection(SilcNetStatus status,
33 static void silc_server_packet_parse_type(SilcServer server,
34 SilcPacketStream sock,
36 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
40 /************************ Static utility functions **************************/
42 /* SKE public key verification callback */
45 silc_server_verify_key(SilcSKE ske,
46 SilcPublicKey public_key,
48 SilcSKEVerifyCbCompletion completion,
49 void *completion_context)
51 SilcPacketStream sock = context;
52 SilcUnknownEntry entry = silc_packet_get_context(sock);
54 SILC_LOG_DEBUG(("Verifying public key"));
56 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
57 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
58 entry->hostname, entry->ip, entry->port,
59 silc_pkcs_get_type(public_key)));
60 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
65 /* We accept all keys without explicit verification */
66 completion(ske, SILC_SKE_STATUS_OK, completion_context);
70 /************************ Packet engine callbacks ***************************/
72 /* Packet engine callback to receive a packet */
74 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
75 SilcPacketStream stream,
77 void *callback_context,
80 SilcServer server = callback_context;
81 SilcIDListData idata = stream_context;
86 /* Packets we do not handle */
87 switch (packet->type) {
88 case SILC_PACKET_HEARTBEAT:
89 case SILC_PACKET_SUCCESS:
90 case SILC_PACKET_FAILURE:
91 case SILC_PACKET_REJECT:
92 case SILC_PACKET_KEY_EXCHANGE:
93 case SILC_PACKET_KEY_EXCHANGE_1:
94 case SILC_PACKET_KEY_EXCHANGE_2:
95 case SILC_PACKET_REKEY_DONE:
96 case SILC_PACKET_CONNECTION_AUTH:
101 /* Only specific packets can come without source ID present. */
102 if ((!packet->src_id ||
103 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
104 packet->type != SILC_PACKET_NEW_CLIENT &&
105 packet->type != SILC_PACKET_NEW_SERVER &&
106 packet->type != SILC_PACKET_RESUME_CLIENT &&
107 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
108 packet->type != SILC_PACKET_DISCONNECT)
111 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and
112 for unregistered connection. */
113 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
114 packet->type == SILC_PACKET_NEW_SERVER) &&
115 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
118 /* Ignore packets from disabled connection */
119 if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
120 packet->type != SILC_PACKET_HEARTBEAT &&
121 packet->type != SILC_PACKET_RESUME_ROUTER &&
122 packet->type != SILC_PACKET_REKEY)
125 /* Check that the the current client ID is same as in the client's packet. */
126 if (idata->conn_type == SILC_CONN_CLIENT) {
127 SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
128 SilcClientID client_id;
130 if (client->id && packet->src_id &&
131 silc_id_str2id(packet->src_id, packet->src_id_len,
132 packet->src_id_type, &client_id, sizeof(client_id))) {
133 if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
134 SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
135 silc_get_packet_name(packet->type)));
141 if (server->server_type == SILC_ROUTER) {
142 /* Route the packet if it is not destined to us. Other ID types but
143 server are handled separately after processing them. */
144 if (packet->dst_id &&
145 !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
146 packet->dst_id_type == SILC_ID_SERVER &&
147 idata->conn_type != SILC_CONN_CLIENT &&
148 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
149 SilcPacketStream conn;
150 SilcServerID server_id;
152 silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
153 &server_id, sizeof(server_id));
155 conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
157 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
158 silc_id_render(&server_id, SILC_ID_SERVER)));
162 silc_server_packet_route(server, conn, packet);
163 silc_packet_free(packet);
168 /* Broadcast packet if it is marked as broadcast packet and it is
169 originated from router and we are router. */
170 if (server->server_type == SILC_ROUTER &&
171 idata->conn_type == SILC_CONN_ROUTER &&
172 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
173 /* Broadcast to our primary route */
174 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
176 /* If we have backup routers then we need to feed all broadcast
177 data to those servers. */
178 silc_server_backup_broadcast(server, stream, packet);
182 silc_server_packet_parse_type(server, stream, packet);
187 /* Packet engine callback to indicate end of stream */
189 static void silc_server_packet_eos(SilcPacketEngine engine,
190 SilcPacketStream stream,
191 void *callback_context,
192 void *stream_context)
194 SilcServer server = callback_context;
195 SilcIDListData idata = silc_packet_get_context(stream);
197 SILC_LOG_DEBUG(("End of stream received, sock %p", stream));
202 if (server->router_conn && server->router_conn->sock == stream &&
203 !server->router && server->standalone) {
204 if (idata->sconn && idata->sconn->callback)
205 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
206 silc_server_create_connections(server);
207 silc_server_free_sock_user_data(server, stream, NULL);
209 /* If backup disconnected then mark that resuming will not be allowed */
210 if (server->server_type == SILC_ROUTER && !server->backup_router &&
211 idata->conn_type == SILC_CONN_SERVER) {
212 SilcServerEntry server_entry = (SilcServerEntry)idata;
213 if (server_entry->server_type == SILC_BACKUP_ROUTER)
214 server->backup_closed = TRUE;
217 if (idata->sconn && idata->sconn->callback)
218 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
219 silc_server_free_sock_user_data(server, stream, NULL);
222 silc_server_close_connection(server, stream);
225 SILC_TASK_CALLBACK(silc_server_packet_error_timeout)
227 SilcServer server = app_context;
228 SilcPacketStream stream = context;
229 SilcIDListData idata = silc_packet_get_context(stream);
231 if (!idata || !silc_packet_stream_is_valid(stream)) {
232 silc_packet_stream_unref(stream);
236 if (server->router_conn && server->router_conn->sock == stream &&
237 !server->router && server->standalone) {
238 if (idata->sconn && idata->sconn->callback)
239 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
240 silc_server_create_connections(server);
241 silc_server_free_sock_user_data(server, stream, NULL);
243 /* If backup disconnected then mark that resuming will not be allowed */
244 if (server->server_type == SILC_ROUTER && !server->backup_router &&
245 idata->conn_type == SILC_CONN_SERVER) {
246 SilcServerEntry server_entry = (SilcServerEntry)idata;
247 if (server_entry->server_type == SILC_BACKUP_ROUTER)
248 server->backup_closed = TRUE;
251 if (idata->sconn && idata->sconn->callback)
252 (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context);
253 silc_server_free_sock_user_data(server, stream, NULL);
256 silc_server_close_connection(server, stream);
258 /* Release our stream reference */
259 silc_packet_stream_unref(stream);
262 /* Packet engine callback to indicate error */
264 static void silc_server_packet_error(SilcPacketEngine engine,
265 SilcPacketStream stream,
266 SilcPacketError error,
267 void *callback_context,
268 void *stream_context)
270 SilcServer server = callback_context;
271 SilcIDListData idata = silc_packet_get_context(stream);
272 SilcStream sock = silc_packet_stream_get_stream(stream);
276 SILC_LOG_DEBUG(("Packet error %d, sock %p", error, stream));
281 if (!silc_socket_stream_get_info(sock, NULL, NULL, &ip, &port))
284 SILC_LOG_ERROR(("Connection %s:%d [%s]: %s", ip, port,
285 SILC_CONNTYPE_STRING(idata->conn_type),
286 silc_packet_error_string(error)));
288 if (!silc_packet_stream_is_valid(stream))
291 /* We must take reference of the stream */
292 silc_packet_stream_ref(stream);
294 /* In case we get here many times, register only one timeout */
295 silc_schedule_task_del_by_all(server->schedule, 0,
296 silc_server_packet_error_timeout, stream);
298 /* Close connection with random timeout */
299 silc_schedule_task_add_timeout(server->schedule,
300 silc_server_packet_error_timeout, stream,
301 silc_rng_get_byte(server->rng) % 10, 0);
304 /* Packet stream callbacks */
305 static SilcPacketCallbacks silc_server_stream_cbs =
307 silc_server_packet_receive,
308 silc_server_packet_eos,
309 silc_server_packet_error
312 /* Parses the packet type and calls what ever routines the packet type
313 requires. This is done for all incoming packets. */
315 static void silc_server_packet_parse_type(SilcServer server,
316 SilcPacketStream sock,
319 SilcPacketType type = packet->type;
320 SilcIDListData idata = silc_packet_get_context(sock);
322 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
323 silc_get_packet_name(type), packet->flags));
325 /* Parse the packet type */
327 case SILC_PACKET_NOTIFY:
329 * Received notify packet. Server can receive notify packets from
330 * router. Server then relays the notify messages to clients if needed.
332 if (packet->flags & SILC_PACKET_FLAG_LIST)
333 silc_server_notify_list(server, sock, packet);
335 silc_server_notify(server, sock, packet);
339 * Private Message packets
341 case SILC_PACKET_PRIVATE_MESSAGE:
343 * Received private message packet. The packet is coming from either
346 if (packet->flags & SILC_PACKET_FLAG_LIST)
348 idata->last_receive = time(NULL);
349 silc_server_private_message(server, sock, packet);
355 case SILC_PACKET_CHANNEL_MESSAGE:
357 * Received channel message. Channel messages are special packets
358 * (although probably most common ones) thus they are handled
361 if (packet->flags & SILC_PACKET_FLAG_LIST)
363 idata->last_receive = time(NULL);
364 silc_server_channel_message(server, sock, packet);
370 case SILC_PACKET_COMMAND:
372 * Recived command. Processes the command request and allocates the
373 * command context and calls the command.
375 if (packet->flags & SILC_PACKET_FLAG_LIST)
377 server->stat.commands_received++;
378 silc_server_command_process(server, sock, packet);
381 case SILC_PACKET_COMMAND_REPLY:
383 * Received command reply packet. Received command reply to command. It
384 * may be reply to command sent by us or reply to command sent by client
385 * that we've routed further.
387 if (packet->flags & SILC_PACKET_FLAG_LIST)
389 server->stat.commands_received++;
390 silc_server_command_reply(server, sock, packet);
393 case SILC_PACKET_DISCONNECT:
396 char *message = NULL;
397 const char *hostname, *ip;
399 if (packet->flags & SILC_PACKET_FLAG_LIST)
401 if (silc_buffer_len(&packet->buffer) < 1)
404 status = (SilcStatus)packet->buffer.data[0];
405 if (silc_buffer_len(&packet->buffer) > 1 &&
406 silc_utf8_valid(packet->buffer.data + 1,
407 silc_buffer_len(&packet->buffer) - 1))
408 message = silc_memdup(packet->buffer.data + 1,
409 silc_buffer_len(&packet->buffer) - 1);
411 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
412 NULL, &hostname, &ip, NULL))
415 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
416 silc_get_status_message(status), status,
417 message ? message : ""));
421 /* Do not switch to backup in case of error */
422 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
424 /* If backup disconnected then mark that resuming will not be allowed */
425 if (server->server_type == SILC_ROUTER && !server->backup_router &&
426 idata->conn_type == SILC_CONN_SERVER) {
427 SilcServerEntry server_entry = (SilcServerEntry)idata;
428 if (server_entry->server_type == SILC_BACKUP_ROUTER)
429 server->backup_closed = TRUE;
432 /* Handle the disconnection from our end too */
433 if (SILC_IS_LOCAL(idata))
434 silc_server_free_sock_user_data(server, sock, NULL);
435 silc_server_close_connection(server, sock);
436 server->backup_noswitch = FALSE;
440 case SILC_PACKET_CHANNEL_KEY:
442 * Received key for channel. As channels are created by the router
443 * the keys are as well. We will distribute the key to all of our
444 * locally connected clients on the particular channel. Router
445 * never receives this channel and thus is ignored.
447 if (packet->flags & SILC_PACKET_FLAG_LIST)
449 silc_server_channel_key(server, sock, packet);
452 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
454 * Private message key packet.
456 if (packet->flags & SILC_PACKET_FLAG_LIST)
458 silc_server_private_message_key(server, sock, packet);
461 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
463 * Connection authentication request packet. When we receive this packet
464 * we will send to the other end information about our mandatory
465 * authentication method for the connection. This packet maybe received
468 if (packet->flags & SILC_PACKET_FLAG_LIST)
470 silc_server_connection_auth_request(server, sock, packet);
473 case SILC_PACKET_NEW_ID:
475 * Received New ID packet. This includes some new ID that has been
476 * created. It may be for client, server or channel. This is the way
477 * to distribute information about new registered entities in the
480 if (packet->flags & SILC_PACKET_FLAG_LIST)
481 silc_server_new_id_list(server, sock, packet);
483 silc_server_new_id(server, sock, packet);
486 case SILC_PACKET_NEW_CLIENT:
488 * Received new client packet. This includes client information that
489 * we will use to create initial client ID. After creating new
490 * ID we will send it to the client.
492 if (packet->flags & SILC_PACKET_FLAG_LIST)
494 silc_server_new_client(server, sock, packet);
497 case SILC_PACKET_NEW_SERVER:
499 * Received new server packet. This includes Server ID and some other
500 * information that we may save. This is received after server has
503 if (packet->flags & SILC_PACKET_FLAG_LIST)
505 silc_server_new_server(server, sock, packet);
508 case SILC_PACKET_NEW_CHANNEL:
510 * Received new channel packet. Information about new channel in the
511 * network are distributed using this packet.
513 if (packet->flags & SILC_PACKET_FLAG_LIST)
514 silc_server_new_channel_list(server, sock, packet);
516 silc_server_new_channel(server, sock, packet);
519 case SILC_PACKET_HEARTBEAT:
521 * Received heartbeat.
523 if (packet->flags & SILC_PACKET_FLAG_LIST)
527 case SILC_PACKET_KEY_AGREEMENT:
529 * Received heartbeat.
531 if (packet->flags & SILC_PACKET_FLAG_LIST)
533 silc_server_key_agreement(server, sock, packet);
536 case SILC_PACKET_REKEY:
538 * Received re-key packet. The sender wants to regenerate the session
541 if (packet->flags & SILC_PACKET_FLAG_LIST)
543 silc_server_rekey(server, sock, packet);
546 case SILC_PACKET_FTP:
548 if (packet->flags & SILC_PACKET_FLAG_LIST)
550 silc_server_ftp(server, sock, packet);
553 case SILC_PACKET_RESUME_CLIENT:
555 if (packet->flags & SILC_PACKET_FLAG_LIST)
557 silc_server_resume_client(server, sock, packet);
560 case SILC_PACKET_RESUME_ROUTER:
561 /* Resume router packet received. This packet is received for backup
562 router resuming protocol. */
563 if (packet->flags & SILC_PACKET_FLAG_LIST)
565 silc_server_backup_resume_router(server, sock, packet);
569 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
574 /****************************** Server API **********************************/
576 /* Allocates a new SILC server object. This has to be done before the server
577 can be used. After allocation one must call silc_server_init to initialize
578 the server. The new allocated server object is returned to the new_server
581 SilcBool silc_server_alloc(SilcServer *new_server)
585 SILC_LOG_DEBUG(("Allocating new server object"));
587 server = silc_calloc(1, sizeof(*server));
590 server->server_type = SILC_SERVER;
591 server->standalone = TRUE;
592 server->local_list = silc_calloc(1, sizeof(*server->local_list));
593 if (!server->local_list)
595 server->global_list = silc_calloc(1, sizeof(*server->global_list));
596 if (!server->global_list)
598 server->pending_commands = silc_dlist_init();
599 if (!server->pending_commands)
601 server->listeners = silc_dlist_init();
602 if (!server->listeners)
604 server->repository = silc_skr_alloc();
605 if (!server->repository)
607 server->conns = silc_dlist_init();
610 server->expired_clients = silc_dlist_init();
611 if (!server->expired_clients)
614 *new_server = server;
619 /* Free's the SILC server object. This is called at the very end before
622 void silc_server_free(SilcServer server)
625 SilcIDCacheEntry cache;
626 SilcIDListData idata;
628 SILC_LOG_DEBUG(("Free server %p", server));
633 silc_server_backup_free(server);
634 silc_server_config_unref(&server->config_ref);
636 silc_rng_free(server->rng);
637 if (server->public_key)
638 silc_pkcs_public_key_free(server->public_key);
639 if (server->private_key)
640 silc_pkcs_private_key_free(server->private_key);
641 if (server->pending_commands)
642 silc_dlist_uninit(server->pending_commands);
643 if (server->id_entry) {
644 if (server->id_entry->data.sconn)
645 silc_schedule_task_del_by_context(server->schedule,
646 server->id_entry->data.sconn->sock);
647 silc_idlist_del_server(server->local_list, server->id_entry);
650 /* Delete all channels */
651 if (silc_idcache_get_all(server->local_list->channels, &list)) {
652 silc_list_start(list);
653 while ((cache = silc_list_get(list)))
654 silc_idlist_del_channel(server->local_list, cache->context);
656 if (silc_idcache_get_all(server->global_list->channels, &list)) {
657 silc_list_start(list);
658 while ((cache = silc_list_get(list)))
659 silc_idlist_del_channel(server->global_list, cache->context);
662 /* Delete all clients */
663 if (silc_idcache_get_all(server->local_list->clients, &list)) {
664 silc_list_start(list);
665 while ((cache = silc_list_get(list))) {
666 silc_schedule_task_del_by_context(server->schedule, cache->context);
667 silc_idlist_del_client(server->local_list, cache->context);
670 if (silc_idcache_get_all(server->global_list->clients, &list)) {
671 silc_list_start(list);
672 while ((cache = silc_list_get(list))) {
673 silc_schedule_task_del_by_context(server->schedule, cache->context);
674 silc_idlist_del_client(server->global_list, cache->context);
678 /* Delete all servers */
679 if (silc_idcache_get_all(server->local_list->servers, &list)) {
680 silc_list_start(list);
681 while ((cache = silc_list_get(list))) {
682 idata = (SilcIDListData)cache->context;
684 silc_schedule_task_del_by_context(server->schedule,
686 silc_idlist_del_server(server->local_list, cache->context);
689 if (silc_idcache_get_all(server->global_list->servers, &list)) {
690 while ((cache = silc_list_get(list))) {
691 idata = (SilcIDListData)cache->context;
693 silc_schedule_task_del_by_context(server->schedule,
695 silc_idlist_del_server(server->global_list, cache->context);
699 silc_schedule_task_del_by_context(server->schedule, server);
700 silc_schedule_uninit(server->schedule);
701 server->schedule = NULL;
703 silc_idcache_free(server->local_list->clients);
704 silc_idcache_free(server->local_list->servers);
705 silc_idcache_free(server->local_list->channels);
706 silc_idcache_free(server->global_list->clients);
707 silc_idcache_free(server->global_list->servers);
708 silc_idcache_free(server->global_list->channels);
709 silc_hash_table_free(server->watcher_list);
710 silc_hash_table_free(server->watcher_list_pk);
711 silc_hash_free(server->md5hash);
712 silc_hash_free(server->sha1hash);
714 silc_dlist_uninit(server->listeners);
715 silc_dlist_uninit(server->conns);
716 silc_dlist_uninit(server->expired_clients);
717 silc_skr_free(server->repository);
718 silc_packet_engine_stop(server->packet_engine);
720 silc_free(server->local_list);
721 silc_free(server->global_list);
722 silc_free(server->server_name);
723 silc_free(server->id);
726 silc_hmac_unregister_all();
727 silc_hash_unregister_all();
728 silc_cipher_unregister_all();
729 silc_pkcs_unregister_all();
732 /* Creates a new server listener. */
734 static SilcNetListener
735 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
737 SilcNetListener listener;
740 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
741 server->config->require_reverse_lookup,
743 silc_server_accept_new_connection, server);
745 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
753 /* Adds a secondary listener. */
755 SilcBool silc_server_init_secondary(SilcServer server)
757 SilcServerConfigServerInfoInterface *interface;
758 SilcNetListener listener;
760 for (interface = server->config->server_info->secondary; interface;
761 interface = interface->next) {
762 listener = silc_server_listen(server, interface->server_ip,
766 silc_dlist_add(server->listeners, listener);
772 /* Initializes the entire SILC server. This is called always before running
773 the server. This is called only once at the initialization of the program.
774 This binds the server to its listenning port. After this function returns
775 one should call silc_server_run to start the server. This returns TRUE
776 when everything is ok to run the server. Configuration file must be
777 read and parsed before calling this. */
779 SilcBool silc_server_init(SilcServer server)
782 SilcServerEntry id_entry;
783 SilcNetListener listener;
787 SILC_LOG_DEBUG(("Initializing server"));
789 server->starttime = time(NULL);
791 /* Take config object for us */
792 silc_server_config_ref(&server->config_ref, server->config,
796 /* Set debugging on if configured */
797 if (server->config->debug_string) {
798 silc_log_debug(TRUE);
799 silc_log_set_debug_string(server->config->debug_string);
801 #endif /* SILC_DEBUG */
803 /* Steal public and private key from the config object */
804 server->public_key = server->config->server_info->public_key;
805 server->private_key = server->config->server_info->private_key;
806 server->config->server_info->public_key = NULL;
807 server->config->server_info->private_key = NULL;
809 /* Register all configured ciphers, PKCS and hash functions. */
810 if (!silc_server_config_register_ciphers(server))
811 silc_cipher_register_default();
812 if (!silc_server_config_register_pkcs(server))
813 silc_pkcs_register_default();
814 if (!silc_server_config_register_hashfuncs(server))
815 silc_hash_register_default();
816 if (!silc_server_config_register_hmacs(server))
817 silc_hmac_register_default();
819 /* Initialize random number generator for the server. */
820 server->rng = silc_rng_alloc();
821 silc_rng_init(server->rng);
822 silc_rng_global_init(server->rng);
824 /* Initialize hash functions for server to use */
825 silc_hash_alloc("md5", &server->md5hash);
826 silc_hash_alloc("sha1", &server->sha1hash);
828 /* Initialize the scheduler */
829 server->schedule = silc_schedule_init(server->config->param.connections_max,
831 if (!server->schedule)
834 /* First, register log files configuration for error output */
835 silc_server_config_setlogfiles(server);
837 /* Initialize ID caches */
838 server->local_list->clients =
839 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
841 server->local_list->servers =
842 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
844 server->local_list->channels =
845 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
848 /* These are allocated for normal server as well as these hold some
849 global information that the server has fetched from its router. For
850 router these are used as they are supposed to be used on router. */
851 server->global_list->clients =
852 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
854 server->global_list->servers =
855 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
857 server->global_list->channels =
858 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
861 /* Init watcher lists */
862 server->watcher_list =
863 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
864 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
866 if (!server->watcher_list)
868 server->watcher_list_pk =
869 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
870 silc_hash_public_key_compare, NULL,
872 if (!server->watcher_list_pk)
875 /* Create TCP listener */
876 listener = silc_server_listen(
878 server->config->server_info->primary == NULL ? NULL :
879 server->config->server_info->primary->server_ip,
880 server->config->server_info->primary == NULL ? 0 :
881 server->config->server_info->primary->port);
884 silc_dlist_add(server->listeners, listener);
886 /* Create a Server ID for the server. */
887 port = silc_net_listener_get_port(listener, NULL);
888 ip = silc_net_listener_get_ip(listener, NULL);
889 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
890 server->config->server_info->primary->public_ip :
891 ip[0], port[0], server->rng, &id);
900 server->server_name = server->config->server_info->server_name;
901 server->config->server_info->server_name = NULL;
902 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
903 sizeof(server->id_string), &server->id_string_len);
905 /* Add ourselves to the server list. We don't have a router yet
906 beacuse we haven't established a route yet. It will be done later.
907 For now, NULL is sent as router. This allocates new entry to
910 silc_idlist_add_server(server->local_list, strdup(server->server_name),
912 silc_id_dup(server->id, SILC_ID_SERVER),
915 SILC_LOG_ERROR(("Could not add local server to cache"));
918 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
919 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
920 SILC_CONN_SERVER : SILC_CONN_ROUTER);
921 server->id_entry = id_entry;
923 /* Create secondary TCP listeners */
924 if (silc_server_init_secondary(server) == FALSE)
927 server->listenning = TRUE;
929 /* Create connections to configured routers. */
930 silc_server_create_connections(server);
932 /* If server connections has been configured then we must be router as
933 normal server cannot have server connections, only router connections. */
934 if (server->config->servers) {
935 SilcServerConfigServer *ptr = server->config->servers;
937 server->server_type = SILC_ROUTER;
939 if (ptr->backup_router) {
940 server->server_type = SILC_BACKUP_ROUTER;
941 server->backup_router = TRUE;
942 server->id_entry->server_type = SILC_BACKUP_ROUTER;
949 if (server->server_type != SILC_ROUTER) {
950 server->stat.servers = 1;
951 server->stat.cell_servers = 1;
953 server->stat.routers = 1;
956 /* If we are normal server we'll retrieve network statisticial information
957 once in a while from the router. */
958 if (server->server_type != SILC_ROUTER)
959 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
962 /* Start packet engine */
963 server->packet_engine =
964 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
965 &silc_server_stream_cbs, server);
966 if (!server->packet_engine)
969 /* Register client entry expiration timeout */
970 silc_schedule_task_add_timeout(server->schedule,
971 silc_server_purge_expired_clients, server,
974 /* Initialize HTTP server */
975 silc_server_http_init(server);
977 SILC_LOG_DEBUG(("Server initialized"));
979 /* We are done here, return succesfully */
983 silc_server_config_unref(&server->config_ref);
987 /* Task callback to close a socket connection after rehash */
989 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
991 SilcServer server = app_context;
992 SilcPacketStream sock = context;
993 SilcIDListData idata = silc_packet_get_context(sock);
994 const char *hostname;
997 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
998 NULL, &hostname, NULL, &port);
1000 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
1001 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
1002 silc_schedule_task_del_by_context(server->schedule, sock);
1003 silc_server_disconnect_remote(server, sock,
1004 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1005 "This connection is removed from "
1007 silc_server_free_sock_user_data(server, sock, NULL);
1010 /* This function basically reads the config file again and switches the config
1011 object pointed by the server object. After that, we have to fix various
1012 things such as the server_name and the listening ports.
1013 Keep in mind that we no longer have the root privileges at this point. */
1015 SilcBool silc_server_rehash(SilcServer server)
1017 SilcServerConfig newconfig;
1019 SILC_LOG_INFO(("Rehashing server"));
1021 /* Reset the logging system */
1022 silc_log_quick(TRUE);
1023 silc_log_flush_all();
1025 /* Start the main rehash phase (read again the config file) */
1026 newconfig = silc_server_config_alloc(server->config_file, server);
1028 SILC_LOG_ERROR(("Rehash FAILED."));
1032 /* Fix the server_name field */
1033 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1034 silc_free(server->server_name);
1036 /* Check server name */
1037 server->server_name =
1038 silc_identifier_check(newconfig->server_info->server_name,
1039 strlen(newconfig->server_info->server_name),
1040 SILC_STRING_LOCALE, 256, NULL);
1041 if (!server->server_name) {
1042 SILC_LOG_ERROR(("Malformed server name string '%s'",
1043 server->config->server_info->server_name));
1047 /* Update the idcache list with a fresh pointer */
1048 silc_free(server->id_entry->server_name);
1049 server->id_entry->server_name = strdup(server->server_name);
1050 silc_idcache_update_by_context(server->local_list->servers,
1051 server->id_entry, NULL,
1052 strdup(server->id_entry->server_name),
1057 silc_server_config_setlogfiles(server);
1059 /* Change new key pair if necessary */
1060 if (newconfig->server_info->public_key &&
1061 !silc_pkcs_public_key_compare(server->public_key,
1062 newconfig->server_info->public_key)) {
1063 silc_pkcs_public_key_free(server->public_key);
1064 silc_pkcs_private_key_free(server->private_key);
1065 server->public_key = newconfig->server_info->public_key;
1066 server->private_key = newconfig->server_info->private_key;
1067 newconfig->server_info->public_key = NULL;
1068 newconfig->server_info->private_key = NULL;
1071 /* Check for unconfigured server and router connections and close
1072 connections that were unconfigured. */
1074 if (server->config->routers) {
1075 SilcServerConfigRouter *ptr;
1076 SilcServerConfigRouter *newptr;
1079 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1082 /* Check whether new config has this one too */
1083 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1084 if (silc_string_compare(newptr->host, ptr->host) &&
1085 newptr->port == ptr->port &&
1086 newptr->initiator == ptr->initiator) {
1092 if (!found && ptr->host) {
1093 /* Remove this connection */
1094 SilcPacketStream sock;
1095 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1096 ptr->host, ptr->port);
1098 silc_schedule_task_add_timeout(server->schedule,
1099 silc_server_rehash_close_connection,
1105 if (server->config->servers) {
1106 SilcServerConfigServer *ptr;
1107 SilcServerConfigServer *newptr;
1110 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1113 /* Check whether new config has this one too */
1114 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1115 if (silc_string_compare(newptr->host, ptr->host)) {
1121 if (!found && ptr->host) {
1122 /* Remove this connection */
1123 SilcPacketStream sock;
1124 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1127 silc_schedule_task_add_timeout(server->schedule,
1128 silc_server_rehash_close_connection,
1134 if (server->config->clients) {
1135 SilcServerConfigClient *ptr;
1136 SilcServerConfigClient *newptr;
1139 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1142 /* Check whether new config has this one too */
1143 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1144 if (silc_string_compare(newptr->host, ptr->host)) {
1150 if (!found && ptr->host) {
1151 /* Remove this connection */
1152 SilcPacketStream sock;
1153 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1156 silc_schedule_task_add_timeout(server->schedule,
1157 silc_server_rehash_close_connection,
1163 /* Create connections after rehash */
1164 silc_server_create_connections(server);
1166 /* Check whether our router status has changed */
1167 if (newconfig->servers) {
1168 SilcServerConfigServer *ptr = newconfig->servers;
1170 server->server_type = SILC_ROUTER;
1172 if (ptr->backup_router) {
1173 server->server_type = SILC_BACKUP_ROUTER;
1174 server->backup_router = TRUE;
1175 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1182 /* Our old config is gone now. We'll unreference our reference made in
1183 silc_server_init and then destroy it since we are destroying it
1184 underneath the application (layer which called silc_server_init). */
1185 silc_server_config_unref(&server->config_ref);
1186 silc_server_config_destroy(server->config);
1188 /* Take new config context */
1189 server->config = newconfig;
1190 silc_server_config_ref(&server->config_ref, server->config, server->config);
1193 /* Set debugging on if configured */
1194 if (server->config->debug_string) {
1195 silc_log_debug(TRUE);
1196 silc_log_set_debug_string(server->config->debug_string);
1198 #endif /* SILC_DEBUG */
1200 SILC_LOG_DEBUG(("Server rehashed"));
1205 /* The heart of the server. This runs the scheduler thus runs the server.
1206 When this returns the server has been stopped and the program will
1209 void silc_server_run(SilcServer server)
1211 SILC_LOG_INFO(("SILC Server started"));
1213 /* Start the scheduler, the heart of the SILC server. When this returns
1214 the program will be terminated. */
1215 silc_schedule(server->schedule);
1218 /* Stops the SILC server. This function is used to shutdown the server.
1219 This is usually called after the scheduler has returned. After stopping
1220 the server one should call silc_server_free. */
1222 void silc_server_stop(SilcServer server)
1225 SilcPacketStream ps;
1226 SilcNetListener listener;
1228 SILC_LOG_INFO(("SILC Server shutting down"));
1230 server->server_shutdown = TRUE;
1232 /* Close all connections */
1233 if (server->packet_engine) {
1234 list = silc_packet_engine_get_streams(server->packet_engine);
1236 silc_dlist_start(list);
1237 while ((ps = silc_dlist_get(list))) {
1238 SilcIDListData idata = silc_packet_get_context(ps);
1240 if (!silc_packet_stream_is_valid(ps))
1244 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1246 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1247 "Server is shutting down");
1248 silc_server_free_sock_user_data(server, ps,
1249 "Server is shutting down");
1251 silc_packet_engine_free_streams_list(list);
1254 /* We are not connected to network anymore */
1255 server->standalone = TRUE;
1257 silc_dlist_start(server->listeners);
1258 while ((listener = silc_dlist_get(server->listeners)))
1259 silc_net_close_listener(listener);
1261 silc_server_http_uninit(server);
1263 /* Cancel any possible retry timeouts */
1264 silc_schedule_task_del_by_callback(server->schedule,
1265 silc_server_connect_router);
1266 silc_schedule_task_del_by_callback(server->schedule,
1267 silc_server_connect_to_router_retry);
1268 silc_schedule_task_del_by_callback(server->schedule,
1269 silc_server_connect_to_router);
1271 silc_schedule_stop(server->schedule);
1273 SILC_LOG_DEBUG(("Server stopped"));
1276 /* Purge expired client entries from the server */
1278 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1280 SilcServer server = context;
1281 SilcClientEntry client;
1283 SilcUInt64 curtime = silc_time();
1285 SILC_LOG_DEBUG(("Expire timeout"));
1287 silc_dlist_start(server->expired_clients);
1288 while ((client = silc_dlist_get(server->expired_clients))) {
1289 /* For unregistered clients the created timestamp is actually
1290 unregistered timestamp. Make sure client remains in history
1291 at least 500 seconds. */
1292 if (client->data.created && curtime - client->data.created < 500)
1295 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1296 server->local_list : server->global_list);
1298 silc_idlist_del_data(client);
1299 silc_idlist_del_client(id_list, client);
1300 silc_dlist_del(server->expired_clients, client);
1303 silc_schedule_task_add_timeout(server->schedule,
1304 silc_server_purge_expired_clients, server,
1309 /******************************* Connecting *********************************/
1311 /* Free connection context */
1313 void silc_server_connection_free(SilcServerConnection sconn)
1317 SILC_LOG_DEBUG(("Free connection %p", sconn));
1318 silc_dlist_del(sconn->server->conns, sconn);
1319 silc_server_config_unref(&sconn->conn);
1320 silc_free(sconn->remote_host);
1321 silc_free(sconn->backup_replace_ip);
1325 /* Creates connection to a remote router. */
1327 void silc_server_create_connection(SilcServer server,
1330 const char *remote_host, SilcUInt32 port,
1331 SilcServerConnectCallback callback,
1334 SilcServerConnection sconn;
1336 /* Allocate connection object for hold connection specific stuff. */
1337 sconn = silc_calloc(1, sizeof(*sconn));
1340 sconn->remote_host = strdup(remote_host);
1341 sconn->remote_port = port;
1342 sconn->no_reconnect = reconnect == FALSE;
1343 sconn->callback = callback;
1344 sconn->callback_context = context;
1345 sconn->no_conf = dynamic;
1346 sconn->server = server;
1348 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1349 remote_host, port));
1351 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1355 /* Connection authentication completion callback */
1358 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1361 SilcServerConnection sconn = context;
1362 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1363 SilcServer server = entry->server;
1364 SilcServerConfigServer *conn;
1365 SilcServerConfigConnParams *param;
1366 SilcIDListData idata;
1367 SilcServerEntry id_entry = NULL;
1368 unsigned char id[32];
1373 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1378 if (success == FALSE) {
1379 /* Authentication failed */
1381 /* Try reconnecting if configuration wants it */
1382 if (!sconn->no_reconnect) {
1383 silc_schedule_task_add_timeout(server->schedule,
1384 silc_server_connect_to_router_retry,
1386 silc_dlist_del(server->conns, sconn);
1390 if (sconn->callback)
1391 (*sconn->callback)(server, NULL, sconn->callback_context);
1392 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1393 silc_server_disconnect_remote(server, sconn->sock,
1394 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1398 /* XXX For now remote is router always */
1399 entry->data.conn_type = SILC_CONN_ROUTER;
1401 SILC_LOG_INFO(("Connected to %s %s",
1402 SILC_CONNTYPE_STRING(entry->data.conn_type),
1403 sconn->remote_host));
1405 /* Create the actual entry for remote entity */
1406 switch (entry->data.conn_type) {
1407 case SILC_CONN_SERVER:
1408 SILC_LOG_DEBUG(("Remote is SILC server"));
1410 /* Add new server. The server must register itself to us before it
1411 becomes registered to SILC network. */
1412 id_entry = silc_idlist_add_server(server->local_list,
1413 strdup(sconn->remote_host),
1414 SILC_SERVER, NULL, NULL, sconn->sock);
1416 if (sconn->callback)
1417 (*sconn->callback)(server, NULL, sconn->callback_context);
1418 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1419 silc_server_disconnect_remote(server, sconn->sock,
1420 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1425 server->stat.my_servers++;
1426 if (server->server_type == SILC_ROUTER)
1427 server->stat.servers++;
1428 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1430 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1433 case SILC_CONN_ROUTER:
1434 SILC_LOG_DEBUG(("Remote is SILC router"));
1436 /* Register to network */
1437 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1438 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1439 SILC_STR_UI_SHORT(id_len),
1440 SILC_STR_DATA(id, id_len),
1441 SILC_STR_UI_SHORT(strlen(server->server_name)),
1442 SILC_STR_DATA(server->server_name,
1443 strlen(server->server_name)),
1445 if (sconn->callback)
1446 (*sconn->callback)(server, NULL, sconn->callback_context);
1447 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1448 silc_server_disconnect_remote(server, sconn->sock,
1449 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1454 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1456 /* Check that we do not have this ID already */
1457 id_entry = silc_idlist_find_server_by_id(server->local_list,
1458 &remote_id.u.server_id,
1461 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1463 id_entry = silc_idlist_find_server_by_id(server->global_list,
1464 &remote_id.u.server_id,
1467 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1471 SILC_LOG_DEBUG(("New server id(%s)",
1472 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1474 /* Add the connected router to global server list. Router is sent
1475 as NULL since it's local to us. */
1476 id_entry = silc_idlist_add_server(server->global_list,
1477 strdup(sconn->remote_host),
1479 silc_id_dup(&remote_id.u.server_id,
1483 /* Try reconnecting if configuration wants it */
1484 if (!sconn->no_reconnect) {
1485 silc_schedule_task_add_timeout(server->schedule,
1486 silc_server_connect_to_router_retry,
1488 silc_dlist_del(server->conns, sconn);
1492 if (sconn->callback)
1493 (*sconn->callback)(server, NULL, sconn->callback_context);
1494 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1495 silc_server_disconnect_remote(server, sconn->sock,
1496 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
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;
1506 idata->sconn->callback = NULL;
1509 server->stat.my_routers++;
1510 if (server->server_type == SILC_ROUTER)
1511 server->stat.routers++;
1512 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1514 if (!sconn->backup) {
1515 /* Mark this router our primary router if we're still standalone */
1516 if (server->standalone) {
1517 SILC_LOG_DEBUG(("This connection is our primary router"));
1518 server->id_entry->router = id_entry;
1519 server->router = id_entry;
1520 server->router->server_type = SILC_ROUTER;
1521 server->standalone = FALSE;
1522 server->backup_primary = FALSE;
1524 /* Announce data if we are not backup router (unless not as primary
1525 currently). Backup router announces later at the end of
1526 resuming protocol. */
1527 if (server->backup_router && server->server_type == SILC_ROUTER) {
1528 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1530 /* If we are router then announce our possible servers. Backup
1531 router announces also global servers. */
1532 if (server->server_type == SILC_ROUTER)
1533 silc_server_announce_servers(server,
1534 server->backup_router ? TRUE : FALSE,
1535 0, SILC_PRIMARY_ROUTE(server));
1537 /* Announce our clients and channels to the router */
1538 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1539 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1542 /* If we are backup router then this primary router is whom we are
1544 if (server->server_type == SILC_BACKUP_ROUTER) {
1545 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1547 NULL, NULL, &ip, NULL);
1548 silc_server_backup_add(server, server->id_entry, ip,
1549 sconn->remote_port, TRUE);
1554 /* We already have primary router. Disconnect this connection */
1555 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1556 silc_idlist_del_server(server->global_list, id_entry);
1557 if (sconn->callback)
1558 (*sconn->callback)(server, NULL, sconn->callback_context);
1559 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1560 silc_server_disconnect_remote(server, sconn->sock,
1561 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1566 /* Add this server to be our backup router */
1567 id_entry->server_type = SILC_BACKUP_ROUTER;
1568 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1569 sconn->backup_replace_port, FALSE);
1575 if (sconn->callback)
1576 (*sconn->callback)(server, NULL, sconn->callback_context);
1577 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1578 silc_server_disconnect_remote(server, sconn->sock,
1579 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1583 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1585 conn = sconn->conn.ref_ptr;
1586 param = &server->config->param;
1587 if (conn && conn->param)
1588 param = conn->param;
1590 /* Register rekey timeout */
1591 sconn->rekey_timeout = param->key_exchange_rekey;
1592 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1593 sconn->sock, sconn->rekey_timeout, 0);
1595 /* Set the entry as packet stream context */
1596 silc_packet_set_context(sconn->sock, id_entry);
1598 /* Call the completion callback to indicate that we've connected to
1600 if (sconn && sconn->callback)
1601 (*sconn->callback)(server, id_entry, sconn->callback_context);
1603 if (sconn == server->router_conn)
1604 server->router_conn = NULL;
1609 /* SKE completion callback */
1611 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1612 SilcSKESecurityProperties prop,
1613 SilcSKEKeyMaterial keymat,
1614 SilcSKERekeyMaterial rekey,
1617 SilcPacketStream sock = context;
1618 SilcUnknownEntry entry = silc_packet_get_context(sock);
1619 SilcServerConnection sconn;
1621 SilcServerConfigRouter *conn;
1622 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1623 void *auth_data = NULL;
1624 SilcUInt32 auth_data_len = 0;
1625 SilcConnAuth connauth;
1626 SilcCipher send_key, receive_key;
1627 SilcHmac hmac_send, hmac_receive;
1629 server = entry->server;
1630 sconn = entry->data.sconn;
1631 conn = sconn->conn.ref_ptr;
1634 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1636 if (status != SILC_SKE_STATUS_OK) {
1638 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1639 silc_ske_map_status(status), entry->hostname, entry->ip));
1642 /* Try reconnecting if configuration wants it */
1643 if (!sconn->no_reconnect) {
1644 silc_schedule_task_add_timeout(server->schedule,
1645 silc_server_connect_to_router_retry,
1647 silc_dlist_del(server->conns, sconn);
1651 if (sconn->callback)
1652 (*sconn->callback)(server, NULL, sconn->callback_context);
1653 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1654 silc_server_disconnect_remote(server, sconn->sock,
1655 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1659 SILC_LOG_DEBUG(("Setting keys into use"));
1661 /* Set the keys into use. The data will be encrypted after this. */
1662 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1663 &hmac_send, &hmac_receive, NULL)) {
1666 /* Try reconnecting if configuration wants it */
1667 if (!sconn->no_reconnect) {
1668 silc_schedule_task_add_timeout(server->schedule,
1669 silc_server_connect_to_router_retry,
1671 silc_dlist_del(server->conns, sconn);
1675 /* Error setting keys */
1676 if (sconn->callback)
1677 (*sconn->callback)(server, NULL, sconn->callback_context);
1678 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1679 silc_server_disconnect_remote(server, sconn->sock,
1680 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1683 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1684 hmac_receive, FALSE);
1686 SILC_LOG_DEBUG(("Starting connection authentication"));
1688 connauth = silc_connauth_alloc(server->schedule, ske,
1689 server->config->conn_auth_timeout);
1693 /* Try reconnecting if configuration wants it */
1694 if (!sconn->no_reconnect) {
1695 silc_schedule_task_add_timeout(server->schedule,
1696 silc_server_connect_to_router_retry,
1698 silc_dlist_del(server->conns, sconn);
1702 /** Error allocating auth protocol */
1703 if (sconn->callback)
1704 (*sconn->callback)(server, NULL, sconn->callback_context);
1705 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1706 silc_server_disconnect_remote(server, sconn->sock,
1707 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1711 /* Get authentication method */
1713 if (conn->passphrase) {
1714 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1715 auth_meth = SILC_AUTH_PUBLIC_KEY;
1716 auth_data = server->private_key;
1718 auth_meth = SILC_AUTH_PASSWORD;
1719 auth_data = conn->passphrase;
1720 auth_data_len = conn->passphrase_len;
1723 auth_meth = SILC_AUTH_PUBLIC_KEY;
1724 auth_data = server->private_key;
1728 entry->data.rekey = rekey;
1730 /* Start connection authentication */
1732 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1733 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1734 auth_data, auth_data_len,
1735 silc_server_ke_auth_compl, sconn);
1738 /* Function that is called when the network connection to a router has
1739 been established. This will continue with the key exchange protocol
1740 with the remote router. */
1742 void silc_server_start_key_exchange(SilcServerConnection sconn)
1744 SilcServer server = sconn->server;
1745 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1746 SilcUnknownEntry entry;
1747 SilcSKEParamsStruct params;
1750 /* Cancel any possible retry timeouts */
1751 silc_schedule_task_del_by_context(server->schedule, sconn);
1753 /* Create packet stream */
1754 sconn->sock = silc_packet_stream_create(server->packet_engine,
1755 server->schedule, sconn->stream);
1757 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1758 silc_stream_destroy(sconn->stream);
1760 /* Try reconnecting if configuration wants it */
1761 if (!sconn->no_reconnect) {
1762 silc_schedule_task_add_timeout(server->schedule,
1763 silc_server_connect_to_router_retry,
1765 silc_dlist_del(server->conns, sconn);
1769 if (sconn->callback)
1770 (*sconn->callback)(server, NULL, sconn->callback_context);
1771 silc_server_connection_free(sconn);
1774 server->stat.conn_num++;
1776 /* Set source ID to packet stream */
1777 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1779 silc_packet_stream_destroy(sconn->sock);
1781 /* Try reconnecting if configuration wants it */
1782 if (!sconn->no_reconnect) {
1783 silc_schedule_task_add_timeout(server->schedule,
1784 silc_server_connect_to_router_retry,
1786 silc_dlist_del(server->conns, sconn);
1790 if (sconn->callback)
1791 (*sconn->callback)(server, NULL, sconn->callback_context);
1792 silc_server_connection_free(sconn);
1796 /* Create entry for remote entity */
1797 entry = silc_calloc(1, sizeof(*entry));
1799 silc_packet_stream_destroy(sconn->sock);
1801 /* Try reconnecting if configuration wants it */
1802 if (!sconn->no_reconnect) {
1803 silc_schedule_task_add_timeout(server->schedule,
1804 silc_server_connect_to_router_retry,
1806 silc_dlist_del(server->conns, sconn);
1810 if (sconn->callback)
1811 (*sconn->callback)(server, NULL, sconn->callback_context);
1812 silc_server_connection_free(sconn);
1815 entry->server = server;
1816 entry->data.sconn = sconn;
1817 entry->data.conn_type = SILC_CONN_UNKNOWN;
1818 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1819 silc_packet_set_context(sconn->sock, entry);
1821 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1823 /* Set Key Exchange flags from configuration, but fall back to global
1825 memset(¶ms, 0, sizeof(params));
1826 SILC_GET_SKE_FLAGS(conn, params.flags);
1827 if (server->config->param.key_exchange_pfs)
1828 params.flags |= SILC_SKE_SP_FLAG_PFS;
1830 /* Start SILC Key Exchange protocol */
1831 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1832 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1833 server->public_key, server->private_key, sconn);
1836 silc_packet_stream_destroy(sconn->sock);
1838 /* Try reconnecting if configuration wants it */
1839 if (!sconn->no_reconnect) {
1840 silc_schedule_task_add_timeout(server->schedule,
1841 silc_server_connect_to_router_retry,
1843 silc_dlist_del(server->conns, sconn);
1847 if (sconn->callback)
1848 (*sconn->callback)(server, NULL, sconn->callback_context);
1849 silc_server_connection_free(sconn);
1852 silc_ske_set_callbacks(ske, silc_server_verify_key,
1853 silc_server_ke_completed, sconn->sock);
1855 /* Start key exchange protocol */
1856 params.version = silc_version_string;
1857 params.timeout_secs = server->config->key_exchange_timeout;
1858 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1861 /* Timeout callback that will be called to retry connecting to remote
1862 router. This is used by both normal and router server. This will wait
1863 before retrying the connecting. The timeout is generated by exponential
1864 backoff algorithm. */
1866 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1868 SilcServerConnection sconn = context;
1869 SilcServer server = sconn->server;
1870 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1871 SilcServerConfigConnParams *param =
1872 (conn->param ? conn->param : &server->config->param);
1874 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1875 sconn->remote_port));
1877 /* Calculate next timeout */
1878 if (sconn->retry_count >= 1) {
1879 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1880 if (sconn->retry_timeout > param->reconnect_interval_max)
1881 sconn->retry_timeout = param->reconnect_interval_max;
1883 sconn->retry_timeout = param->reconnect_interval;
1885 sconn->retry_count++;
1886 sconn->retry_timeout = sconn->retry_timeout +
1887 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1889 /* If we've reached max retry count, give up. */
1890 if ((sconn->retry_count > param->reconnect_count) &&
1891 sconn->no_reconnect) {
1892 SILC_LOG_ERROR(("Could not connect, giving up"));
1894 if (sconn->callback)
1895 (*sconn->callback)(server, NULL, sconn->callback_context);
1896 silc_server_connection_free(sconn);
1900 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1902 /* We will lookup a fresh pointer later */
1903 silc_server_config_unref(&sconn->conn);
1905 /* Wait before retrying */
1906 silc_schedule_task_del_by_context(server->schedule, sconn);
1907 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1908 sconn, sconn->retry_timeout, 0);
1911 /* Callback for async connection to remote router */
1913 static void silc_server_connection_established(SilcNetStatus status,
1917 SilcServerConnection sconn = context;
1918 SilcServer server = sconn->server;
1920 silc_schedule_task_del_by_context(server->schedule, sconn);
1925 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1926 sconn->remote_host, sconn->remote_port));
1928 /* Continue with key exchange protocol */
1929 sconn->stream = stream;
1930 silc_server_start_key_exchange(sconn);
1933 case SILC_NET_UNKNOWN_IP:
1934 case SILC_NET_UNKNOWN_HOST:
1935 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1936 sconn->remote_host, sconn->remote_port,
1937 silc_net_get_error_string(status)));
1938 if (!sconn->no_reconnect) {
1939 silc_schedule_task_add_timeout(sconn->server->schedule,
1940 silc_server_connect_to_router_retry,
1942 silc_dlist_del(server->conns, sconn);
1944 if (sconn->callback)
1945 (*sconn->callback)(server, NULL, sconn->callback_context);
1946 silc_server_connection_free(sconn);
1951 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1952 sconn->remote_host, sconn->remote_port,
1953 silc_net_get_error_string(status)));
1954 if (!sconn->no_reconnect) {
1955 silc_schedule_task_add_timeout(sconn->server->schedule,
1956 silc_server_connect_to_router_retry,
1958 silc_dlist_del(server->conns, sconn);
1960 if (sconn->callback)
1961 (*sconn->callback)(server, NULL, sconn->callback_context);
1962 silc_server_connection_free(sconn);
1968 /* Generic routine to use connect to a router. */
1970 SILC_TASK_CALLBACK(silc_server_connect_router)
1972 SilcServerConnection sconn = context;
1973 SilcServer server = sconn->server;
1974 SilcServerConfigRouter *rconn;
1976 silc_schedule_task_del_by_context(server->schedule, sconn);
1978 /* Don't connect if we are shutting down. */
1979 if (server->server_shutdown) {
1980 if (sconn->callback)
1981 (*sconn->callback)(server, NULL, sconn->callback_context);
1982 silc_server_connection_free(sconn);
1986 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1987 (sconn->backup ? "backup router" : "router"),
1988 sconn->remote_host, sconn->remote_port));
1990 if (!sconn->no_conf) {
1991 /* Find connection configuration */
1992 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1993 sconn->remote_port);
1995 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1996 (sconn->backup ? "backup router" : "router"),
1997 sconn->remote_host, sconn->remote_port));
1998 if (sconn->callback)
1999 (*sconn->callback)(server, NULL, sconn->callback_context);
2000 silc_server_connection_free(sconn);
2003 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
2006 /* Connect to remote host */
2008 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
2009 server->config->server_info->primary->server_ip),
2010 sconn->remote_host, sconn->remote_port,
2011 server->schedule, silc_server_connection_established,
2014 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2015 sconn->remote_host, sconn->remote_port));
2016 if (sconn->callback)
2017 (*sconn->callback)(server, NULL, sconn->callback_context);
2018 silc_server_connection_free(sconn);
2022 /* Add to connection list */
2023 silc_dlist_add(server->conns, sconn);
2026 /* This function connects to our primary router or if we are a router this
2027 establishes all our primary routes. This is called at the start of the
2028 server to do authentication and key exchange with our router - called
2031 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2033 SilcServer server = context;
2034 SilcServerConnection sconn;
2035 SilcServerConfigRouter *ptr;
2036 SilcServerConfigConnParams *param;
2038 /* Don't connect if we are shutting down. */
2039 if (server->server_shutdown)
2042 SILC_LOG_DEBUG(("We are %s",
2043 (server->server_type == SILC_SERVER ?
2044 "normal server" : server->server_type == SILC_ROUTER ?
2045 "router" : "backup router/normal server")));
2047 if (!server->config->routers) {
2048 /* There wasn't a configured router, we will continue but we don't
2049 have a connection to outside world. We will be standalone server. */
2050 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2051 server->standalone = TRUE;
2055 /* Cancel any possible retry timeouts */
2056 silc_schedule_task_del_by_callback(server->schedule,
2057 silc_server_connect_router);
2058 silc_schedule_task_del_by_callback(server->schedule,
2059 silc_server_connect_to_router_retry);
2061 /* Create the connections to all our routes */
2062 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2064 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2065 ptr->backup_router ? "Backup router" : "Router",
2066 ptr->initiator ? "Initiator" : "Responder",
2067 ptr->host, ptr->port));
2069 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2070 ptr->initiator == FALSE && !server->backup_router &&
2071 !silc_server_config_get_backup_router(server))
2072 server->wait_backup = TRUE;
2074 if (!ptr->initiator)
2076 if (ptr->dynamic_connection)
2079 /* Check whether we are connecting or connected to this host already */
2080 if (silc_server_num_sockets_by_remote(server,
2081 silc_net_is_ip(ptr->host) ?
2083 silc_net_is_ip(ptr->host) ?
2084 NULL : ptr->host, ptr->port,
2085 SILC_CONN_ROUTER)) {
2086 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2087 ptr->host, ptr->port));
2089 /* If we don't have primary router and this connection is our
2090 primary router we are in desync. Reconnect to the primary. */
2091 if (server->standalone && !server->router) {
2093 SilcPacketStream sock;
2094 SilcServerConfigRouter *primary =
2095 silc_server_config_get_primary_router(server);
2098 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2099 ptr->host, ptr->port);
2102 server->backup_noswitch = TRUE;
2103 silc_server_free_sock_user_data(server, sock, NULL);
2104 silc_server_disconnect_remote(server, sock, 0, NULL);
2105 server->backup_noswitch = FALSE;
2106 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2112 param = (ptr->param ? ptr->param : &server->config->param);
2114 /* Allocate connection object for hold connection specific stuff. */
2115 sconn = silc_calloc(1, sizeof(*sconn));
2118 sconn->server = server;
2119 sconn->remote_host = strdup(ptr->host);
2120 sconn->remote_port = ptr->port;
2121 sconn->backup = ptr->backup_router;
2122 if (sconn->backup) {
2123 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2124 sconn->backup_replace_port = ptr->backup_replace_port;
2126 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2128 SILC_LOG_DEBUG(("Created connection %p", sconn));
2130 if (!server->router_conn && !sconn->backup)
2131 server->router_conn = sconn;
2134 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2140 /************************ Accepting new connection **************************/
2142 /* After this is called, server don't wait for backup router anymore.
2143 This gets called automatically even after we have backup router
2144 connection established. */
2146 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2148 SilcServer server = context;
2149 server->wait_backup = FALSE;
2152 /* Authentication data callback */
2155 silc_server_accept_get_auth(SilcConnAuth connauth,
2156 SilcConnectionType conn_type,
2157 unsigned char **passphrase,
2158 SilcUInt32 *passphrase_len,
2159 SilcSKR *repository,
2162 SilcPacketStream sock = context;
2163 SilcUnknownEntry entry = silc_packet_get_context(sock);
2164 SilcServer server = entry->server;
2166 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2168 /* Remote end is client */
2169 if (conn_type == SILC_CONN_CLIENT) {
2170 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2174 *passphrase = cconfig->passphrase;
2175 *passphrase_len = cconfig->passphrase_len;
2176 if (cconfig->publickeys)
2177 *repository = server->repository;
2179 if (cconfig->publickeys) {
2180 if (server->config->prefer_passphrase_auth) {
2184 *passphrase_len = 0;
2188 entry->conn_type = conn_type;
2192 /* Remote end is server */
2193 if (conn_type == SILC_CONN_SERVER) {
2194 SilcServerConfigServer *sconfig;
2196 /* If we are normal server, don't accept the connection */
2197 if (server->server_type == SILC_SERVER)
2200 sconfig = entry->sconfig.ref_ptr;
2204 *passphrase = sconfig->passphrase;
2205 *passphrase_len = sconfig->passphrase_len;
2206 if (sconfig->publickeys)
2207 *repository = server->repository;
2209 if (sconfig->publickeys) {
2210 if (server->config->prefer_passphrase_auth) {
2214 *passphrase_len = 0;
2218 entry->conn_type = conn_type;
2222 /* Remote end is router */
2223 if (conn_type == SILC_CONN_ROUTER) {
2224 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2228 *passphrase = rconfig->passphrase;
2229 *passphrase_len = rconfig->passphrase_len;
2230 if (rconfig->publickeys)
2231 *repository = server->repository;
2233 if (rconfig->publickeys) {
2234 if (server->config->prefer_passphrase_auth) {
2238 *passphrase_len = 0;
2242 entry->conn_type = conn_type;
2249 /* Authentication completion callback. */
2252 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2255 SilcPacketStream sock = context;
2256 SilcUnknownEntry entry = silc_packet_get_context(sock);
2257 SilcIDListData idata = (SilcIDListData)entry;
2258 SilcServer server = entry->server;
2259 SilcServerConfigConnParams *param = &server->config->param;
2260 SilcServerConnection sconn;
2262 const char *hostname, *ip;
2266 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2267 NULL, &hostname, &ip, &port);
2269 if (success == FALSE) {
2270 /* Authentication failed */
2271 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2272 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2273 server->stat.auth_failures++;
2274 silc_server_disconnect_remote(server, sock,
2275 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2276 silc_server_config_unref(&entry->cconfig);
2277 silc_server_config_unref(&entry->sconfig);
2278 silc_server_config_unref(&entry->rconfig);
2279 silc_server_free_sock_user_data(server, sock, NULL);
2283 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2285 switch (entry->conn_type) {
2286 case SILC_CONN_CLIENT:
2288 SilcClientEntry client;
2289 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2291 /* Verify whether this connection is after all allowed to connect */
2292 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2293 &server->config->param,
2295 silc_connauth_get_ske(connauth))) {
2296 server->stat.auth_failures++;
2300 /* If we are primary router and we have backup router configured
2301 but it has not connected to use yet, do not accept any other
2303 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2304 !server->backup_router) {
2305 SilcServerConfigRouter *router;
2306 router = silc_server_config_get_backup_router(server);
2307 if (router && strcmp(server->config->server_info->primary->server_ip,
2309 silc_server_find_socket_by_host(server,
2311 router->backup_replace_ip, 0)) {
2312 SILC_LOG_INFO(("Will not accept connections because we do "
2313 "not have backup router connection established"));
2314 silc_server_disconnect_remote(server, sock,
2315 SILC_STATUS_ERR_PERM_DENIED,
2316 "We do not have connection to backup "
2317 "router established, try later");
2318 silc_server_config_unref(&entry->cconfig);
2319 silc_server_config_unref(&entry->sconfig);
2320 silc_server_config_unref(&entry->rconfig);
2321 silc_server_free_sock_user_data(server, sock, NULL);
2322 server->stat.auth_failures++;
2324 /* From here on, wait 20 seconds for the backup router to appear. */
2325 silc_schedule_task_add_timeout(server->schedule,
2326 silc_server_backup_router_wait,
2327 (void *)server, 20, 0);
2332 SILC_LOG_DEBUG(("Remote host is client"));
2333 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2336 /* Add the client to the client ID cache. The nickname and Client ID
2337 and other information is created after we have received NEW_CLIENT
2338 packet from client. */
2339 client = silc_idlist_add_client(server->local_list,
2340 NULL, NULL, NULL, NULL, NULL, sock);
2342 SILC_LOG_ERROR(("Could not add new client to cache"));
2343 server->stat.auth_failures++;
2344 silc_server_disconnect_remote(server, sock,
2345 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2346 silc_server_config_unref(&entry->cconfig);
2347 silc_server_config_unref(&entry->sconfig);
2348 silc_server_config_unref(&entry->rconfig);
2349 silc_server_free_sock_user_data(server, sock, NULL);
2352 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2353 entry->data.conn_type = SILC_CONN_CLIENT;
2356 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
2357 server->stat.clients + 1));
2358 server->stat.my_clients++;
2359 server->stat.clients++;
2360 server->stat.cell_clients++;
2362 /* Get connection parameters */
2364 param = conn->param;
2366 if (!param->keepalive_secs)
2367 param->keepalive_secs = server->config->param.keepalive_secs;
2369 if (!param->qos && server->config->param.qos) {
2370 param->qos = server->config->param.qos;
2371 param->qos_rate_limit = server->config->param.qos_rate_limit;
2372 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2373 param->qos_limit_sec = server->config->param.qos_limit_sec;
2374 param->qos_limit_usec = server->config->param.qos_limit_usec;
2377 /* Check if to be anonymous connection */
2378 if (param->anonymous)
2379 client->mode |= SILC_UMODE_ANONYMOUS;
2382 /* Add public key to repository */
2383 SILC_LOG_DEBUG(("Add client public key to repository"));
2384 if (!silc_server_get_public_key_by_client(server, client, NULL))
2385 silc_skr_add_public_key_simple(server->repository,
2386 entry->data.public_key,
2387 SILC_SKR_USAGE_IDENTIFICATION, client,
2390 id_entry = (void *)client;
2394 case SILC_CONN_SERVER:
2395 case SILC_CONN_ROUTER:
2397 SilcServerEntry new_server;
2398 SilcBool initiator = FALSE;
2399 SilcBool backup_local = FALSE;
2400 SilcBool backup_router = FALSE;
2401 char *backup_replace_ip = NULL;
2402 SilcUInt16 backup_replace_port = 0;
2403 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2404 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2406 /* If we are backup router and this is incoming server connection
2407 and we do not have connection to primary router, do not allow
2409 if (server->server_type == SILC_BACKUP_ROUTER &&
2410 entry->conn_type == SILC_CONN_SERVER &&
2411 !SILC_PRIMARY_ROUTE(server)) {
2412 SILC_LOG_INFO(("Will not accept server connection because we do "
2413 "not have primary router connection established"));
2414 silc_server_disconnect_remote(server, sock,
2415 SILC_STATUS_ERR_PERM_DENIED,
2416 "We do not have connection to primary "
2417 "router established, try later");
2418 silc_server_config_unref(&entry->cconfig);
2419 silc_server_config_unref(&entry->sconfig);
2420 silc_server_config_unref(&entry->rconfig);
2421 silc_server_free_sock_user_data(server, sock, NULL);
2422 server->stat.auth_failures++;
2426 if (entry->conn_type == SILC_CONN_ROUTER) {
2427 /* Verify whether this connection is after all allowed to connect */
2428 if (!silc_server_connection_allowed(server, sock,
2430 &server->config->param,
2431 rconn ? rconn->param : NULL,
2432 silc_connauth_get_ske(connauth))) {
2433 silc_server_config_unref(&entry->cconfig);
2434 silc_server_config_unref(&entry->sconfig);
2435 silc_server_config_unref(&entry->rconfig);
2436 server->stat.auth_failures++;
2442 param = rconn->param;
2444 if (!param->keepalive_secs)
2445 param->keepalive_secs = server->config->param.keepalive_secs;
2447 if (!param->qos && server->config->param.qos) {
2448 param->qos = server->config->param.qos;
2449 param->qos_rate_limit = server->config->param.qos_rate_limit;
2450 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2451 param->qos_limit_sec = server->config->param.qos_limit_sec;
2452 param->qos_limit_usec = server->config->param.qos_limit_usec;
2456 initiator = rconn->initiator;
2457 backup_local = rconn->backup_local;
2458 backup_router = rconn->backup_router;
2459 backup_replace_ip = rconn->backup_replace_ip;
2460 backup_replace_port = rconn->backup_replace_port;
2464 if (entry->conn_type == SILC_CONN_SERVER) {
2465 /* Verify whether this connection is after all allowed to connect */
2466 if (!silc_server_connection_allowed(server, sock,
2468 &server->config->param,
2469 srvconn ? srvconn->param : NULL,
2470 silc_connauth_get_ske(connauth))) {
2471 server->stat.auth_failures++;
2475 if (srvconn->param) {
2476 param = srvconn->param;
2478 if (!param->keepalive_secs)
2479 param->keepalive_secs = server->config->param.keepalive_secs;
2481 if (!param->qos && server->config->param.qos) {
2482 param->qos = server->config->param.qos;
2483 param->qos_rate_limit = server->config->param.qos_rate_limit;
2484 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2485 param->qos_limit_sec = server->config->param.qos_limit_sec;
2486 param->qos_limit_usec = server->config->param.qos_limit_usec;
2490 backup_router = srvconn->backup_router;
2494 /* If we are primary router and we have backup router configured
2495 but it has not connected to use yet, do not accept any other
2497 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2498 !server->backup_router && !backup_router) {
2499 SilcServerConfigRouter *router;
2500 router = silc_server_config_get_backup_router(server);
2501 if (router && strcmp(server->config->server_info->primary->server_ip,
2503 silc_server_find_socket_by_host(server,
2505 router->backup_replace_ip, 0)) {
2506 SILC_LOG_INFO(("Will not accept connections because we do "
2507 "not have backup router connection established"));
2508 silc_server_disconnect_remote(server, sock,
2509 SILC_STATUS_ERR_PERM_DENIED,
2510 "We do not have connection to backup "
2511 "router established, try later");
2512 silc_server_config_unref(&entry->cconfig);
2513 silc_server_config_unref(&entry->sconfig);
2514 silc_server_config_unref(&entry->rconfig);
2515 silc_server_free_sock_user_data(server, sock, NULL);
2516 server->stat.auth_failures++;
2518 /* From here on, wait 20 seconds for the backup router to appear. */
2519 silc_schedule_task_add_timeout(server->schedule,
2520 silc_server_backup_router_wait,
2521 (void *)server, 20, 0);
2526 SILC_LOG_DEBUG(("Remote host is %s",
2527 entry->conn_type == SILC_CONN_SERVER ?
2528 "server" : (backup_router ?
2529 "backup router" : "router")));
2530 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2531 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2532 "server" : (backup_router ?
2533 "backup router" : "router")));
2535 /* Add the server into server cache. The server name and Server ID
2536 is updated after we have received NEW_SERVER packet from the
2537 server. We mark ourselves as router for this server if we really
2540 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2541 server->local_list : (backup_router ?
2542 server->local_list :
2543 server->global_list)),
2545 (entry->conn_type == SILC_CONN_SERVER ?
2546 SILC_SERVER : SILC_ROUTER),
2548 (entry->conn_type == SILC_CONN_SERVER ?
2549 server->id_entry : (backup_router ?
2550 server->id_entry : NULL)),
2553 SILC_LOG_ERROR(("Could not add new server to cache"));
2554 silc_server_disconnect_remote(server, sock,
2555 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2556 silc_server_config_unref(&entry->cconfig);
2557 silc_server_config_unref(&entry->sconfig);
2558 silc_server_config_unref(&entry->rconfig);
2559 silc_server_free_sock_user_data(server, sock, NULL);
2560 server->stat.auth_failures++;
2563 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2564 entry->data.conn_type = entry->conn_type;
2566 id_entry = (void *)new_server;
2568 /* If the incoming connection is router and marked as backup router
2569 then add it to be one of our backups */
2570 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2571 /* Change it back to SERVER type since that's what it really is. */
2573 entry->data.conn_type = SILC_CONN_SERVER;
2574 new_server->server_type = SILC_BACKUP_ROUTER;
2576 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2577 ("Backup router %s is now online",
2580 /* Remove the backup waiting with timeout */
2581 silc_schedule_task_add_timeout(server->schedule,
2582 silc_server_backup_router_wait,
2583 (void *)server, 10, 0);
2587 if (entry->data.conn_type == SILC_CONN_SERVER) {
2588 server->stat.my_servers++;
2589 server->stat.servers++;
2590 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2592 server->stat.my_routers++;
2593 server->stat.routers++;
2594 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2597 /* Check whether this connection is to be our primary router connection
2598 if we do not already have the primary route. */
2599 if (!backup_router &&
2600 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2601 if (silc_server_config_is_primary_route(server) && !initiator)
2604 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2605 server->standalone = FALSE;
2606 if (!server->id_entry->router) {
2607 server->id_entry->router = id_entry;
2608 server->router = id_entry;
2620 /* Add connection to server->conns so that we know we have connection
2622 sconn = silc_calloc(1, sizeof(*sconn));
2623 sconn->server = server;
2625 sconn->remote_host = strdup(hostname);
2626 sconn->remote_port = port;
2627 silc_dlist_add(server->conns, sconn);
2628 idata->sconn = sconn;
2629 idata->sconn->callback = NULL;
2630 idata->last_receive = time(NULL);
2632 /* Add the common data structure to the ID entry. */
2633 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2634 silc_packet_set_context(sock, id_entry);
2636 /* Connection has been fully established now. Everything is ok. */
2637 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2639 /* Perform Quality of Service */
2641 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2642 param->qos_rate_limit, param->qos_bytes_limit,
2643 param->qos_limit_sec, param->qos_limit_usec);
2645 silc_server_config_unref(&entry->cconfig);
2646 silc_server_config_unref(&entry->sconfig);
2647 silc_server_config_unref(&entry->rconfig);
2651 silc_ske_free(silc_connauth_get_ske(connauth));
2652 silc_connauth_free(connauth);
2655 /* SKE completion callback. We set the new keys into use here. */
2658 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2659 SilcSKESecurityProperties prop,
2660 SilcSKEKeyMaterial keymat,
2661 SilcSKERekeyMaterial rekey,
2664 SilcPacketStream sock = context;
2665 SilcUnknownEntry entry = silc_packet_get_context(sock);
2666 SilcIDListData idata = (SilcIDListData)entry;
2667 SilcServer server = entry->server;
2668 SilcConnAuth connauth;
2669 SilcCipher send_key, receive_key;
2670 SilcHmac hmac_send, hmac_receive;
2677 if (status != SILC_SKE_STATUS_OK) {
2679 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2680 silc_ske_map_status(status), entry->hostname, entry->ip));
2682 silc_server_disconnect_remote(server, sock,
2683 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2684 silc_server_config_unref(&entry->cconfig);
2685 silc_server_config_unref(&entry->sconfig);
2686 silc_server_config_unref(&entry->rconfig);
2687 silc_server_free_sock_user_data(server, sock, NULL);
2691 SILC_LOG_DEBUG(("Setting keys into use"));
2693 /* Set the keys into use. The data will be encrypted after this. */
2694 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2695 &hmac_send, &hmac_receive, &hash)) {
2696 /* Error setting keys */
2698 silc_server_disconnect_remote(server, sock,
2699 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2700 silc_server_free_sock_user_data(server, sock, NULL);
2703 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2704 hmac_receive, FALSE);
2706 idata->rekey = rekey;
2707 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2708 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2710 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2715 SILC_LOG_DEBUG(("Starting connection authentication"));
2716 server->stat.auth_attempts++;
2718 connauth = silc_connauth_alloc(server->schedule, ske,
2719 server->config->conn_auth_timeout);
2721 /** Error allocating auth protocol */
2723 silc_server_disconnect_remote(server, sock,
2724 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2725 silc_server_config_unref(&entry->cconfig);
2726 silc_server_config_unref(&entry->sconfig);
2727 silc_server_config_unref(&entry->rconfig);
2728 silc_server_free_sock_user_data(server, sock, NULL);
2732 /* Start connection authentication */
2734 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2735 silc_server_accept_auth_compl, sock);
2738 /* Accept new TCP connection */
2740 static void silc_server_accept_new_connection(SilcNetStatus status,
2744 SilcServer server = context;
2745 SilcPacketStream packet_stream;
2746 SilcServerConfigClient *cconfig = NULL;
2747 SilcServerConfigServer *sconfig = NULL;
2748 SilcServerConfigRouter *rconfig = NULL;
2749 SilcServerConfigDeny *deny;
2750 SilcUnknownEntry entry;
2752 SilcSKEParamsStruct params;
2753 char *hostname, *ip;
2756 SILC_LOG_DEBUG(("Accepting new connection"));
2758 /* Check for maximum allowed connections */
2759 server->stat.conn_attempts++;
2760 if (silc_dlist_count(server->conns) >
2761 server->config->param.connections_max) {
2762 SILC_LOG_ERROR(("Refusing connection, server is full"));
2763 server->stat.conn_failures++;
2764 silc_stream_destroy(stream);
2768 /* Get hostname, IP and port */
2769 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2770 (const char **)&ip, &port)) {
2771 /* Bad socket stream */
2772 server->stat.conn_failures++;
2773 silc_stream_destroy(stream);
2777 /* Create packet stream */
2778 packet_stream = silc_packet_stream_create(server->packet_engine,
2779 server->schedule, stream);
2780 if (!packet_stream) {
2781 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2782 server->stat.conn_failures++;
2783 silc_stream_destroy(stream);
2786 server->stat.conn_num++;
2788 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2790 /* Set source ID to packet stream */
2791 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2794 server->stat.conn_failures++;
2795 silc_packet_stream_destroy(packet_stream);
2799 /* Check whether this connection is denied to connect to us. */
2800 deny = silc_server_config_find_denied(server, ip);
2802 deny = silc_server_config_find_denied(server, hostname);
2804 /* The connection is denied */
2805 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2806 silc_server_disconnect_remote(server, packet_stream,
2807 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2809 silc_server_free_sock_user_data(server, packet_stream, NULL);
2813 /* Check whether we have configured this sort of connection at all. We
2814 have to check all configurations since we don't know what type of
2815 connection this is. */
2816 if (!(cconfig = silc_server_config_find_client(server, ip)))
2817 cconfig = silc_server_config_find_client(server, hostname);
2818 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2819 sconfig = silc_server_config_find_server_conn(server, hostname);
2820 if (server->server_type == SILC_ROUTER)
2821 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2822 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2823 if (!cconfig && !sconfig && !rconfig) {
2824 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2825 server->stat.conn_failures++;
2826 silc_server_disconnect_remote(server, packet_stream,
2827 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2828 silc_server_free_sock_user_data(server, packet_stream, NULL);
2832 /* The connection is allowed */
2833 entry = silc_calloc(1, sizeof(*entry));
2835 server->stat.conn_failures++;
2836 silc_server_disconnect_remote(server, packet_stream,
2837 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2838 silc_server_free_sock_user_data(server, packet_stream, NULL);
2841 entry->hostname = hostname;
2844 entry->server = server;
2845 entry->data.conn_type = SILC_CONN_UNKNOWN;
2846 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2847 silc_packet_set_context(packet_stream, entry);
2849 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2851 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2852 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2853 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2855 /* Take flags for key exchange. Since we do not know what type of connection
2856 this is, we go through all found configurations and use the global ones
2857 as well. This will result always into strictest key exchange flags. */
2858 memset(¶ms, 0, sizeof(params));
2859 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2860 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2861 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2862 if (server->config->param.key_exchange_pfs)
2863 params.flags |= SILC_SKE_SP_FLAG_PFS;
2865 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2866 server->stat.conn_attempts++;
2868 /* Start SILC Key Exchange protocol */
2869 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2870 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2871 server->public_key, server->private_key,
2874 server->stat.conn_failures++;
2875 silc_server_disconnect_remote(server, packet_stream,
2876 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2877 silc_server_free_sock_user_data(server, packet_stream, NULL);
2880 silc_ske_set_callbacks(ske, silc_server_verify_key,
2881 silc_server_accept_completed, packet_stream);
2883 /* Start key exchange protocol */
2884 params.version = silc_version_string;
2885 params.timeout_secs = server->config->key_exchange_timeout;
2886 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2890 /********************************** Rekey ***********************************/
2892 /* Initiator rekey completion callback */
2894 static void silc_server_rekey_completion(SilcSKE ske,
2895 SilcSKEStatus status,
2896 const SilcSKESecurityProperties prop,
2897 const SilcSKEKeyMaterial keymat,
2898 SilcSKERekeyMaterial rekey,
2901 SilcPacketStream sock = context;
2902 SilcIDListData idata = silc_packet_get_context(sock);
2903 SilcServer server = idata->sconn->server;
2905 idata->sconn->op = NULL;
2906 if (status != SILC_SKE_STATUS_OK) {
2907 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2908 idata->sconn->remote_host));
2912 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2913 idata->sconn->remote_host, idata->sconn->remote_port,
2914 SILC_CONNTYPE_STRING(idata->conn_type)));
2916 /* Save rekey data for next rekey */
2917 idata->rekey = rekey;
2919 /* Register new rekey timeout */
2920 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2921 sock, idata->sconn->rekey_timeout, 0);
2924 /* Helper to stop future rekeys on a link. */
2925 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2927 if (!client->connection)
2930 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2932 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2933 client->connection);
2936 /* Rekey callback. Start rekey as initiator */
2938 SILC_TASK_CALLBACK(silc_server_do_rekey)
2940 SilcServer server = app_context;
2941 SilcPacketStream sock = context;
2942 SilcIDListData idata = silc_packet_get_context(sock);
2945 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2947 /* Do not execute rekey with disabled connections */
2948 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2951 /* If another protocol is active do not start rekey */
2952 if (idata->sconn->op) {
2953 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2954 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2959 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2960 idata->sconn->remote_host, idata->sconn->remote_port,
2961 SILC_CONNTYPE_STRING(idata->conn_type)));
2964 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2965 server->public_key, NULL, sock);
2969 /* Set SKE callbacks */
2970 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2973 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2976 /* Responder rekey completion callback */
2979 silc_server_rekey_resp_completion(SilcSKE ske,
2980 SilcSKEStatus status,
2981 const SilcSKESecurityProperties prop,
2982 const SilcSKEKeyMaterial keymat,
2983 SilcSKERekeyMaterial rekey,
2986 SilcPacketStream sock = context;
2987 SilcIDListData idata = silc_packet_get_context(sock);
2989 idata->sconn->op = NULL;
2990 if (status != SILC_SKE_STATUS_OK) {
2991 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2992 idata->sconn->remote_host));
2996 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2997 idata->sconn->remote_host, idata->sconn->remote_port,
2998 SILC_CONNTYPE_STRING(idata->conn_type)));
3000 /* Save rekey data for next rekey */
3001 idata->rekey = rekey;
3004 /* Start rekey as responder */
3006 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
3009 SilcIDListData idata = silc_packet_get_context(sock);
3012 if (!idata->rekey) {
3013 silc_packet_free(packet);
3017 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3018 idata->sconn->remote_host, idata->sconn->remote_port,
3019 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3022 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3023 server->public_key, NULL, sock);
3025 silc_packet_free(packet);
3029 /* Set SKE callbacks */
3030 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3033 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3038 /****************************** Disconnection *******************************/
3040 /* Destroys packet stream. */
3042 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3044 silc_packet_stream_unref(context);
3047 /* Closes connection to socket connection */
3049 void silc_server_close_connection(SilcServer server,
3050 SilcPacketStream sock)
3052 SilcIDListData idata = silc_packet_get_context(sock);
3054 const char *hostname;
3057 if (!silc_packet_stream_is_valid(sock))
3060 memset(tmp, 0, sizeof(tmp));
3061 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3062 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3063 NULL, &hostname, NULL, &port);
3064 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3065 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3066 tmp[0] ? tmp : ""));
3068 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3070 if (idata && idata->sconn) {
3071 silc_server_connection_free(idata->sconn);
3072 idata->sconn = NULL;
3075 /* Take a reference and then destroy the stream. The last reference
3076 is released later in a timeout callback. */
3077 silc_packet_stream_ref(sock);
3078 silc_packet_stream_destroy(sock);
3080 /* Close connection with timeout */
3081 server->stat.conn_num--;
3082 silc_schedule_task_del_by_all(server->schedule, 0,
3083 silc_server_close_connection_final, sock);
3084 silc_schedule_task_add_timeout(server->schedule,
3085 silc_server_close_connection_final,
3089 /* Sends disconnect message to remote connection and disconnects the
3092 void silc_server_disconnect_remote(SilcServer server,
3093 SilcPacketStream sock,
3094 SilcStatus status, ...)
3096 unsigned char buf[512];
3103 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p, status %d", sock,
3106 va_start(ap, status);
3107 cp = va_arg(ap, char *);
3109 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3112 /* Send SILC_PACKET_DISCONNECT */
3113 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3114 SILC_STR_UI_CHAR(status),
3115 SILC_STR_UI8_STRING(cp ? buf : NULL),
3118 /* Close connection */
3119 silc_server_close_connection(server, sock);
3122 /* Frees client data and notifies about client's signoff. */
3124 void silc_server_free_client_data(SilcServer server,
3125 SilcPacketStream sock,
3126 SilcClientEntry client,
3128 const char *signoff)
3130 SILC_LOG_DEBUG(("Freeing client %p data", client));
3133 /* Check if anyone is watching this nickname */
3134 if (server->server_type == SILC_ROUTER)
3135 silc_server_check_watcher_list(server, client, NULL,
3136 SILC_NOTIFY_TYPE_SIGNOFF);
3138 /* Send SIGNOFF notify to routers. */
3140 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3141 SILC_BROADCAST(server), client->id,
3145 /* Remove client from all channels */
3147 silc_server_remove_from_channels(server, NULL, client,
3148 TRUE, (char *)signoff, TRUE, FALSE);
3150 silc_server_remove_from_channels(server, NULL, client,
3151 FALSE, NULL, FALSE, FALSE);
3153 /* Remove this client from watcher list if it is */
3154 silc_server_del_from_watcher_list(server, client);
3156 /* Remove client's public key from repository, this will free it too. */
3157 if (client->data.public_key) {
3158 silc_skr_del_public_key(server->repository, client->data.public_key,
3160 client->data.public_key = NULL;
3163 /* Update statistics */
3165 /* Local detached clients aren't counted. */
3166 if (!client->local_detached)
3167 server->stat.my_clients--;
3168 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3169 server->stat.clients - 1));
3170 SILC_VERIFY(server->stat.clients > 0);
3171 server->stat.clients--;
3172 if (server->stat.cell_clients)
3173 server->stat.cell_clients--;
3174 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3175 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3176 silc_schedule_task_del_by_context(server->schedule, client);
3178 if (client->data.sconn) {
3179 silc_server_connection_free(client->data.sconn);
3180 client->data.sconn = NULL;
3183 /* We will not delete the client entry right away. We will take it
3184 into history (for WHOWAS command) for 5 minutes, unless we're
3185 shutting down server. */
3186 if (!server->server_shutdown) {
3187 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3189 client->router = NULL;
3190 client->connection = NULL;
3191 client->data.created = silc_time();
3192 silc_dlist_del(server->expired_clients, client);
3193 silc_dlist_add(server->expired_clients, client);
3195 /* Delete directly since we're shutting down server */
3196 SILC_LOG_DEBUG(("Delete client directly"));
3197 silc_idlist_del_data(client);
3198 silc_idlist_del_client(server->local_list, client);
3202 /* Frees user_data pointer from socket connection object. This also sends
3203 appropriate notify packets to the network to inform about leaving
3206 void silc_server_free_sock_user_data(SilcServer server,
3207 SilcPacketStream sock,
3208 const char *signoff_message)
3210 SilcIDListData idata;
3217 SILC_LOG_DEBUG(("Start, sock %p", sock));
3219 idata = silc_packet_get_context(sock);
3223 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3226 /* Cancel active protocols */
3228 if (idata->sconn && idata->sconn->op) {
3229 SILC_LOG_DEBUG(("Abort active protocol"));
3230 silc_async_abort(idata->sconn->op, NULL, NULL);
3231 idata->sconn->op = NULL;
3233 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3234 ((SilcUnknownEntry)idata)->op) {
3235 SILC_LOG_DEBUG(("Abort active protocol"));
3236 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3237 idata->sconn->op = NULL;
3241 switch (idata->conn_type) {
3242 case SILC_CONN_CLIENT:
3244 SilcClientEntry client_entry = (SilcClientEntry)idata;
3245 silc_server_free_client_data(server, sock, client_entry, TRUE,
3247 silc_packet_set_context(sock, NULL);
3251 case SILC_CONN_SERVER:
3252 case SILC_CONN_ROUTER:
3254 SilcServerEntry user_data = (SilcServerEntry)idata;
3255 SilcServerEntry backup_router = NULL;
3257 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3260 backup_router = silc_server_backup_get(server, user_data->id);
3262 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3263 backup_router == server->id_entry &&
3264 idata->conn_type != SILC_CONN_ROUTER)
3265 backup_router = NULL;
3267 if (server->server_shutdown || server->backup_noswitch)
3268 backup_router = NULL;
3270 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3271 NULL, NULL, &ip, &port);
3273 /* If this was our primary router connection then we're lost to
3274 the outside world. */
3275 if (server->router == user_data) {
3276 /* Check whether we have a backup router connection */
3277 if (!backup_router || backup_router == user_data) {
3278 if (!server->no_reconnect)
3279 silc_server_create_connections(server);
3280 server->id_entry->router = NULL;
3281 server->router = NULL;
3282 server->standalone = TRUE;
3283 server->backup_primary = FALSE;
3284 backup_router = NULL;
3286 if (server->id_entry != backup_router) {
3287 SILC_LOG_INFO(("New primary router is backup router %s",
3288 backup_router->server_name));
3289 server->id_entry->router = backup_router;
3290 server->router = backup_router;
3291 server->router_connect = time(0);
3292 server->backup_primary = TRUE;
3293 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3295 /* Send START_USE to backup router to indicate we have switched */
3296 silc_server_backup_send_start_use(server,
3297 backup_router->connection,
3300 SILC_LOG_INFO(("We are now new primary router in this cell"));
3301 server->id_entry->router = NULL;
3302 server->router = NULL;
3303 server->standalone = TRUE;
3306 /* We stop here to take a breath */
3309 if (server->backup_router) {
3310 server->server_type = SILC_ROUTER;
3312 /* We'll need to constantly try to reconnect to the primary
3313 router so that we'll see when it comes back online. */
3314 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3315 silc_server_backup_connected,
3319 /* Mark this connection as replaced */
3320 silc_server_backup_replaced_add(server, user_data->id,
3323 } else if (backup_router) {
3324 SILC_LOG_INFO(("Enabling the use of backup router %s",
3325 backup_router->server_name));
3327 /* Mark this connection as replaced */
3328 silc_server_backup_replaced_add(server, user_data->id,
3330 } else if (server->server_type == SILC_SERVER &&
3331 idata->conn_type == SILC_CONN_ROUTER) {
3332 /* Reconnect to the router (backup) */
3333 if (!server->no_reconnect)
3334 silc_server_create_connections(server);
3337 if (user_data->server_name)
3338 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3339 ("Server %s signoff", user_data->server_name));
3341 if (!backup_router) {
3342 /* Remove all servers that are originated from this server, and
3343 remove the clients of those servers too. */
3344 silc_server_remove_servers_by_server(server, user_data, TRUE);
3347 /* Remove the clients that this server owns as they will become
3348 invalid now too. For backup router the server is actually
3349 coming from the primary router, so mark that as the owner
3351 if (server->server_type == SILC_BACKUP_ROUTER &&
3352 sock->type == SILC_CONN_SERVER)
3353 silc_server_remove_clients_by_server(server, server->router,
3357 silc_server_remove_clients_by_server(server, user_data,
3360 /* Remove channels owned by this server */
3361 if (server->server_type == SILC_SERVER)
3362 silc_server_remove_channels_by_server(server, user_data);
3364 /* Enable local server connections that may be disabled */
3365 silc_server_local_servers_toggle_enabled(server, TRUE);
3367 /* Update the client entries of this server to the new backup
3368 router. If we are the backup router we also resolve the real
3369 servers for the clients. After updating is over this also
3370 removes the clients that this server explicitly owns. */
3371 silc_server_update_clients_by_server(server, user_data,
3372 backup_router, TRUE);
3374 /* If we are router and just lost our primary router (now standlaone)
3375 we remove everything that was behind it, since we don't know
3377 if (server->server_type == SILC_ROUTER && server->standalone)
3378 /* Remove all servers that are originated from this server, and
3379 remove the clients of those servers too. */
3380 silc_server_remove_servers_by_server(server, user_data, TRUE);
3382 /* Finally remove the clients that are explicitly owned by this
3383 server. They go down with the server. */
3384 silc_server_remove_clients_by_server(server, user_data,
3387 /* Update our server cache to use the new backup router too. */
3388 silc_server_update_servers_by_server(server, user_data, backup_router);
3389 if (server->server_type == SILC_SERVER)
3390 silc_server_update_channels_by_server(server, user_data,
3393 /* Send notify about primary router going down to local operators */
3394 if (server->backup_router)
3395 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3396 SILC_NOTIFY_TYPE_NONE,
3397 ("%s switched to backup router %s "
3398 "(we are primary router now)",
3399 server->server_name, server->server_name));
3400 else if (server->router)
3401 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3402 SILC_NOTIFY_TYPE_NONE,
3403 ("%s switched to backup router %s",
3404 server->server_name,
3405 server->router->server_name));
3407 server->backup_noswitch = FALSE;
3410 silc_server_connection_free(idata->sconn);
3411 idata->sconn = NULL;
3415 if (idata->conn_type == SILC_CONN_SERVER) {
3416 server->stat.my_servers--;
3417 server->stat.servers--;
3418 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3419 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3420 server->stat.my_routers--;
3421 server->stat.routers--;
3422 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3424 if (server->server_type == SILC_ROUTER)
3425 server->stat.cell_servers--;
3427 /* Free the server entry */
3428 silc_server_backup_del(server, user_data);
3429 silc_server_backup_replaced_del(server, user_data);
3430 silc_idlist_del_data(user_data);
3431 if (!silc_idlist_del_server(server->local_list, user_data))
3432 silc_idlist_del_server(server->global_list, user_data);
3434 if (backup_router && backup_router != server->id_entry) {
3435 /* Announce all of our stuff that was created about 5 minutes ago.
3436 The backup router knows all the other stuff already. */
3437 if (server->server_type == SILC_ROUTER)
3438 silc_server_announce_servers(server, FALSE, time(0) - 300,
3439 backup_router->connection);
3441 /* Announce our clients and channels to the router */
3442 silc_server_announce_clients(server, time(0) - 300,
3443 backup_router->connection);
3444 silc_server_announce_channels(server, time(0) - 300,
3445 backup_router->connection);
3448 silc_packet_set_context(sock, NULL);
3454 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3456 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3459 if (server->router_conn == idata->sconn) {
3460 if (!server->no_reconnect)
3461 silc_server_create_connections(server);
3462 server->router_conn = NULL;
3465 silc_server_connection_free(idata->sconn);
3466 idata->sconn = NULL;
3468 silc_idlist_del_data(idata);
3470 silc_packet_set_context(sock, NULL);
3476 /* Removes client from all channels it has joined. This is used when client
3477 connection is disconnected. If the client on a channel is last, the
3478 channel is removed as well. This sends the SIGNOFF notify types. */
3480 void silc_server_remove_from_channels(SilcServer server,
3481 SilcPacketStream sock,
3482 SilcClientEntry client,
3484 const char *signoff_message,
3488 SilcChannelEntry channel;
3489 SilcChannelClientEntry chl;
3490 SilcHashTableList htl;
3491 SilcBuffer clidp = NULL;
3496 if (notify && !client->id)
3499 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3500 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3503 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3508 /* Remove the client from all channels. The client is removed from
3509 the channels' user list. */
3510 silc_hash_table_list(client->channels, &htl);
3511 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3512 channel = chl->channel;
3514 /* Remove channel if this is last client leaving the channel, unless
3515 the channel is permanent. */
3516 if (server->server_type != SILC_SERVER &&
3517 silc_hash_table_count(channel->user_list) < 2) {
3518 silc_server_channel_delete(server, channel);
3522 silc_hash_table_del(client->channels, channel);
3523 silc_hash_table_del(channel->user_list, client);
3524 channel->user_count--;
3526 /* If there is no global users on the channel anymore mark the channel
3527 as local channel. Do not check if the removed client is local client. */
3528 if (server->server_type == SILC_SERVER && channel->global_users &&
3529 chl->client->router && !silc_server_channel_has_global(channel))
3530 channel->global_users = FALSE;
3532 memset(chl, 'A', sizeof(*chl));
3535 /* Update statistics */
3536 if (SILC_IS_LOCAL(client))
3537 server->stat.my_chanclients--;
3538 if (server->server_type == SILC_ROUTER) {
3539 server->stat.cell_chanclients--;
3540 server->stat.chanclients--;
3543 /* If there is not at least one local user on the channel then we don't
3544 need the channel entry anymore, we can remove it safely, unless the
3545 channel is permanent channel */
3546 if (server->server_type == SILC_SERVER &&
3547 !silc_server_channel_has_local(channel)) {
3548 /* Notify about leaving client if this channel has global users. */
3549 if (notify && channel->global_users)
3550 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3551 SILC_NOTIFY_TYPE_SIGNOFF,
3552 signoff_message ? 2 : 1,
3553 clidp->data, silc_buffer_len(clidp),
3554 signoff_message, signoff_message ?
3555 strlen(signoff_message) : 0);
3557 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3558 silc_server_channel_delete(server, channel);
3562 /* Send notify to channel about client leaving SILC and channel too */
3564 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3565 SILC_NOTIFY_TYPE_SIGNOFF,
3566 signoff_message ? 2 : 1,
3567 clidp->data, silc_buffer_len(clidp),
3568 signoff_message, signoff_message ?
3569 strlen(signoff_message) : 0);
3571 if (killed && clidp) {
3572 /* Remove the client from channel's invite list */
3573 if (channel->invite_list &&
3574 silc_hash_table_count(channel->invite_list)) {
3576 SilcArgumentPayload iargs;
3577 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3578 silc_buffer_len(clidp), 3);
3579 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3580 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3581 silc_buffer_free(ab);
3582 silc_argument_payload_free(iargs);
3586 /* Don't create keys if we are shutting down */
3587 if (server->server_shutdown)
3590 /* Re-generate channel key if needed */
3591 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3592 if (!silc_server_create_channel_key(server, channel, 0))
3595 /* Send the channel key to the channel. The key of course is not sent
3596 to the client who was removed from the channel. */
3597 silc_server_send_channel_key(server, client->connection, channel,
3598 server->server_type == SILC_ROUTER ?
3599 FALSE : !server->standalone);
3603 silc_hash_table_list_reset(&htl);
3605 silc_buffer_free(clidp);
3608 /* Removes client from one channel. This is used for example when client
3609 calls LEAVE command to remove itself from the channel. Returns TRUE
3610 if channel still exists and FALSE if the channel is removed when
3611 last client leaves the channel. If `notify' is FALSE notify messages
3614 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3615 SilcPacketStream sock,
3616 SilcChannelEntry channel,
3617 SilcClientEntry client,
3620 SilcChannelClientEntry chl;
3623 SILC_LOG_DEBUG(("Removing %s from channel %s",
3624 silc_id_render(client->id, SILC_ID_CLIENT),
3625 channel->channel_name));
3627 /* Get the entry to the channel, if this client is not on the channel
3629 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3632 /* Remove channel if this is last client leaving the channel, unless
3633 the channel is permanent. */
3634 if (server->server_type != SILC_SERVER &&
3635 silc_hash_table_count(channel->user_list) < 2) {
3636 silc_server_channel_delete(server, channel);
3640 silc_hash_table_del(client->channels, channel);
3641 silc_hash_table_del(channel->user_list, client);
3642 channel->user_count--;
3644 /* If there is no global users on the channel anymore mark the channel
3645 as local channel. Do not check if the client is local client. */
3646 if (server->server_type == SILC_SERVER && channel->global_users &&
3647 chl->client->router && !silc_server_channel_has_global(channel))
3648 channel->global_users = FALSE;
3650 memset(chl, 'O', sizeof(*chl));
3653 /* Update statistics */
3654 if (SILC_IS_LOCAL(client))
3655 server->stat.my_chanclients--;
3656 if (server->server_type == SILC_ROUTER) {
3657 server->stat.cell_chanclients--;
3658 server->stat.chanclients--;
3661 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3665 /* If there is not at least one local user on the channel then we don't
3666 need the channel entry anymore, we can remove it safely, unless the
3667 channel is permanent channel */
3668 if (server->server_type == SILC_SERVER &&
3669 !silc_server_channel_has_local(channel)) {
3670 /* Notify about leaving client if this channel has global users. */
3671 if (notify && channel->global_users)
3672 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3673 SILC_NOTIFY_TYPE_LEAVE, 1,
3674 clidp->data, silc_buffer_len(clidp));
3676 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3677 silc_server_channel_delete(server, channel);
3678 silc_buffer_free(clidp);
3682 /* Send notify to channel about client leaving the channel */
3684 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3685 SILC_NOTIFY_TYPE_LEAVE, 1,
3686 clidp->data, silc_buffer_len(clidp));
3688 silc_buffer_free(clidp);
3692 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3693 function may be used only by router. In real SILC network all channels
3694 are created by routers thus this function is never used by normal
3697 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3698 SilcServerID *router_id,
3704 SilcChannelID *channel_id;
3705 SilcChannelEntry entry;
3706 SilcCipher send_key, receive_key;
3709 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3712 cipher = SILC_DEFAULT_CIPHER;
3714 hmac = SILC_DEFAULT_HMAC;
3716 /* Allocate cipher */
3717 if (!silc_cipher_alloc(cipher, &send_key))
3719 if (!silc_cipher_alloc(cipher, &receive_key)) {
3720 silc_cipher_free(send_key);
3725 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3726 silc_cipher_free(send_key);
3727 silc_cipher_free(receive_key);
3731 channel_name = strdup(channel_name);
3733 /* Create the channel ID */
3734 if (!silc_id_create_channel_id(server, router_id, server->rng,
3736 silc_free(channel_name);
3737 silc_cipher_free(send_key);
3738 silc_cipher_free(receive_key);
3739 silc_hmac_free(newhmac);
3743 /* Create the channel */
3744 entry = silc_idlist_add_channel(server->local_list, channel_name,
3745 SILC_CHANNEL_MODE_NONE, channel_id,
3746 NULL, send_key, receive_key, newhmac);
3748 silc_free(channel_name);
3749 silc_cipher_free(send_key);
3750 silc_cipher_free(receive_key);
3751 silc_hmac_free(newhmac);
3752 silc_free(channel_id);
3756 entry->cipher = strdup(cipher);
3757 entry->hmac_name = strdup(hmac);
3759 /* Now create the actual key material */
3760 if (!silc_server_create_channel_key(server, entry,
3761 silc_cipher_get_key_len(send_key) / 8)) {
3762 silc_idlist_del_channel(server->local_list, entry);
3766 /* Notify other routers about the new channel. We send the packet
3767 to our primary route. */
3769 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3770 channel_name, entry->id,
3771 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3774 /* Distribute to backup routers */
3775 if (broadcast && server->server_type == SILC_ROUTER) {
3777 unsigned char cid[32];
3778 SilcUInt32 name_len = strlen(channel_name);
3781 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3782 packet = silc_channel_payload_encode(channel_name, name_len,
3783 cid, id_len, entry->mode);
3784 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3785 packet->data, silc_buffer_len(packet), FALSE,
3787 silc_buffer_free(packet);
3790 server->stat.my_channels++;
3791 if (server->server_type == SILC_ROUTER) {
3792 server->stat.channels++;
3793 server->stat.cell_channels++;
3794 entry->users_resolved = TRUE;
3800 /* Same as above but creates the channel with Channel ID `channel_id. */
3803 silc_server_create_new_channel_with_id(SilcServer server,
3807 SilcChannelID *channel_id,
3810 SilcChannelEntry entry;
3811 SilcCipher send_key, receive_key;
3814 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3817 cipher = SILC_DEFAULT_CIPHER;
3819 hmac = SILC_DEFAULT_HMAC;
3821 /* Allocate cipher */
3822 if (!silc_cipher_alloc(cipher, &send_key))
3824 if (!silc_cipher_alloc(cipher, &receive_key)) {
3825 silc_cipher_free(send_key);
3830 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3831 silc_cipher_free(send_key);
3832 silc_cipher_free(receive_key);
3836 channel_name = strdup(channel_name);
3838 /* Create the channel */
3839 entry = silc_idlist_add_channel(server->local_list, channel_name,
3840 SILC_CHANNEL_MODE_NONE, channel_id,
3841 NULL, send_key, receive_key, newhmac);
3843 silc_cipher_free(send_key);
3844 silc_cipher_free(receive_key);
3845 silc_hmac_free(newhmac);
3846 silc_free(channel_name);
3850 /* Now create the actual key material */
3851 if (!silc_server_create_channel_key(server, entry,
3852 silc_cipher_get_key_len(send_key) / 8)) {
3853 silc_idlist_del_channel(server->local_list, entry);
3857 /* Notify other routers about the new channel. We send the packet
3858 to our primary route. */
3860 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3861 channel_name, entry->id,
3862 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3865 /* Distribute to backup routers */
3866 if (broadcast && server->server_type == SILC_ROUTER) {
3868 unsigned char cid[32];
3869 SilcUInt32 name_len = strlen(channel_name);
3872 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3873 packet = silc_channel_payload_encode(channel_name, name_len,
3874 cid, id_len, entry->mode);
3875 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3876 packet->data, silc_buffer_len(packet), FALSE,
3878 silc_buffer_free(packet);
3881 server->stat.my_channels++;
3882 if (server->server_type == SILC_ROUTER) {
3883 server->stat.channels++;
3884 server->stat.cell_channels++;
3885 entry->users_resolved = TRUE;
3891 /* Channel's key re-key timeout callback. */
3893 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3895 SilcServer server = app_context;
3896 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3900 /* Return now if we are shutting down */
3901 if (server->server_shutdown)
3904 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3907 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3910 /* Generates new channel key. This is used to create the initial channel key
3911 but also to re-generate new key for channel. If `key_len' is provided
3912 it is the bytes of the key length. */
3914 SilcBool silc_server_create_channel_key(SilcServer server,
3915 SilcChannelEntry channel,
3919 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3922 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3923 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3927 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3929 if (!channel->send_key)
3930 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3931 channel->send_key = NULL;
3934 if (!channel->receive_key)
3935 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3936 silc_cipher_free(channel->send_key);
3937 channel->send_key = channel->receive_key = NULL;
3943 else if (channel->key_len)
3944 len = channel->key_len / 8;
3946 len = silc_cipher_get_key_len(channel->send_key) / 8;
3948 /* Create channel key */
3949 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3952 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3953 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3955 /* Remove old key if exists */
3957 memset(channel->key, 0, channel->key_len / 8);
3958 silc_free(channel->key);
3962 channel->key_len = len * 8;
3963 channel->key = silc_memdup(channel_key, len);
3964 memset(channel_key, 0, sizeof(channel_key));
3966 /* Generate HMAC key from the channel key data and set it */
3968 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3969 memset(channel->key, 0, channel->key_len / 8);
3970 silc_free(channel->key);
3971 silc_cipher_free(channel->send_key);
3972 silc_cipher_free(channel->receive_key);
3973 channel->send_key = channel->receive_key = NULL;
3976 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3977 silc_hmac_set_key(channel->hmac, hash,
3978 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3979 memset(hash, 0, sizeof(hash));
3981 if (server->server_type == SILC_ROUTER) {
3982 if (!channel->rekey)
3983 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3984 channel->rekey->channel = channel;
3985 channel->rekey->key_len = key_len;
3986 if (channel->rekey->task)
3987 silc_schedule_task_del(server->schedule, channel->rekey->task);
3989 channel->rekey->task =
3990 silc_schedule_task_add_timeout(server->schedule,
3991 silc_server_channel_key_rekey,
3992 (void *)channel->rekey,
3993 server->config->channel_rekey_secs, 0);
3999 /* Saves the channel key found in the encoded `key_payload' buffer. This
4000 function is used when we receive Channel Key Payload and also when we're
4001 processing JOIN command reply. Returns entry to the channel. */
4003 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4004 SilcBuffer key_payload,
4005 SilcChannelEntry channel)
4007 SilcChannelKeyPayload payload = NULL;
4009 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4013 /* Decode channel key payload */
4014 payload = silc_channel_key_payload_parse(key_payload->data,
4015 silc_buffer_len(key_payload));
4017 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4022 /* Get the channel entry */
4025 /* Get channel ID */
4026 tmp = silc_channel_key_get_id(payload, &tmp_len);
4027 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4032 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4034 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4036 if (server->server_type == SILC_ROUTER)
4037 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4038 silc_id_render(&id, SILC_ID_CHANNEL)));
4044 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4046 tmp = silc_channel_key_get_key(payload, &tmp_len);
4052 cipher = silc_channel_key_get_cipher(payload, NULL);
4058 /* Remove old key if exists */
4060 memset(channel->key, 0, channel->key_len / 8);
4061 silc_free(channel->key);
4062 silc_cipher_free(channel->send_key);
4063 silc_cipher_free(channel->receive_key);
4066 /* Create new cipher */
4067 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4068 channel->send_key = NULL;
4072 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4073 silc_cipher_free(channel->send_key);
4074 channel->send_key = channel->receive_key = NULL;
4079 if (channel->cipher)
4080 silc_free(channel->cipher);
4081 channel->cipher = strdup(cipher);
4084 channel->key_len = tmp_len * 8;
4085 channel->key = silc_memdup(tmp, tmp_len);
4086 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4087 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4089 /* Generate HMAC key from the channel key data and set it */
4091 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4092 memset(channel->key, 0, channel->key_len / 8);
4093 silc_free(channel->key);
4094 silc_cipher_free(channel->send_key);
4095 silc_cipher_free(channel->receive_key);
4096 channel->send_key = channel->receive_key = NULL;
4099 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4100 silc_hmac_set_key(channel->hmac, hash,
4101 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4103 memset(hash, 0, sizeof(hash));
4104 memset(tmp, 0, tmp_len);
4106 if (server->server_type == SILC_ROUTER) {
4107 if (!channel->rekey)
4108 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4109 channel->rekey->channel = channel;
4110 if (channel->rekey->task)
4111 silc_schedule_task_del(server->schedule, channel->rekey->task);
4113 channel->rekey->task =
4114 silc_schedule_task_add_timeout(server->schedule,
4115 silc_server_channel_key_rekey,
4116 (void *)channel->rekey,
4117 server->config->channel_rekey_secs, 0);
4122 silc_channel_key_payload_free(payload);
4127 /* Returns assembled of all servers in the given ID list. The packet's
4128 form is dictated by the New ID payload. */
4130 static void silc_server_announce_get_servers(SilcServer server,
4131 SilcServerEntry remote,
4133 SilcBuffer *servers,
4134 unsigned long creation_time)
4137 SilcIDCacheEntry id_cache;
4138 SilcServerEntry entry;
4142 /* Go through all clients in the list */
4143 if (silc_idcache_get_all(id_list->servers, &list)) {
4144 silc_list_start(list);
4145 while ((id_cache = silc_list_get(list))) {
4146 entry = (SilcServerEntry)id_cache->context;
4148 /* Do not announce the one we've sending our announcements and
4149 do not announce ourself. Also check the creation time if it's
4151 if ((entry == remote) || (entry == server->id_entry) ||
4152 (creation_time && entry->data.created < creation_time))
4155 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4157 tmp = silc_buffer_realloc(*servers,
4159 silc_buffer_truelen((*servers)) +
4160 silc_buffer_len(idp) :
4161 silc_buffer_len(idp)));
4165 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4166 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4167 silc_buffer_pull(*servers, silc_buffer_len(idp));
4168 silc_buffer_free(idp);
4174 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4180 p = silc_notify_payload_encode(notify, argc, ap);
4186 /* This function is used by router to announce existing servers to our
4187 primary router when we've connected to it. If `creation_time' is non-zero
4188 then only the servers that has been created after the `creation_time'
4189 will be announced. */
4191 void silc_server_announce_servers(SilcServer server, SilcBool global,
4192 unsigned long creation_time,
4193 SilcPacketStream remote)
4195 SilcBuffer servers = NULL;
4197 SILC_LOG_DEBUG(("Announcing servers"));
4199 /* Get servers in local list */
4200 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4201 server->local_list, &servers,
4205 /* Get servers in global list */
4206 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4207 server->global_list, &servers,
4211 silc_buffer_push(servers, servers->data - servers->head);
4212 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4214 /* Send the packet */
4215 silc_server_packet_send(server, remote,
4216 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4217 servers->data, silc_buffer_len(servers));
4219 silc_buffer_free(servers);
4223 /* Returns assembled packet of all clients in the given ID list. The
4224 packet's form is dictated by the New ID Payload. */
4226 static void silc_server_announce_get_clients(SilcServer server,
4228 SilcBuffer *clients,
4230 unsigned long creation_time)
4233 SilcIDCacheEntry id_cache;
4234 SilcClientEntry client;
4237 unsigned char mode[4];
4240 /* Go through all clients in the list */
4241 if (silc_idcache_get_all(id_list->clients, &list)) {
4242 silc_list_start(list);
4243 while ((id_cache = silc_list_get(list))) {
4244 client = (SilcClientEntry)id_cache->context;
4246 if (creation_time && client->data.created < creation_time)
4248 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4250 if (!client->connection && !client->router)
4253 SILC_LOG_DEBUG(("Announce Client ID %s",
4254 silc_id_render(client->id, SILC_ID_CLIENT)));
4256 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4260 tmp2 = silc_buffer_realloc(*clients,
4262 silc_buffer_truelen((*clients)) +
4263 silc_buffer_len(idp) :
4264 silc_buffer_len(idp)));
4268 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4269 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4270 silc_buffer_pull(*clients, silc_buffer_len(idp));
4272 SILC_PUT32_MSB(client->mode, mode);
4274 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4275 2, idp->data, silc_buffer_len(idp),
4277 tmp2 = silc_buffer_realloc(*umodes,
4279 silc_buffer_truelen((*umodes)) +
4280 silc_buffer_len(tmp) :
4281 silc_buffer_len(tmp)));
4285 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4286 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4287 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4288 silc_buffer_free(tmp);
4290 silc_buffer_free(idp);
4295 /* This function is used to announce our existing clients to our router
4296 when we've connected to it. If `creation_time' is non-zero then only
4297 the clients that has been created after the `creation_time' will be
4300 void silc_server_announce_clients(SilcServer server,
4301 unsigned long creation_time,
4302 SilcPacketStream remote)
4304 SilcBuffer clients = NULL;
4305 SilcBuffer umodes = NULL;
4307 SILC_LOG_DEBUG(("Announcing clients"));
4309 /* Get clients in local list */
4310 silc_server_announce_get_clients(server, server->local_list,
4311 &clients, &umodes, creation_time);
4313 /* As router we announce our global list as well */
4314 if (server->server_type == SILC_ROUTER)
4315 silc_server_announce_get_clients(server, server->global_list,
4316 &clients, &umodes, creation_time);
4319 silc_buffer_push(clients, clients->data - clients->head);
4320 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4322 /* Send the packet */
4323 silc_server_packet_send(server, remote,
4324 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4325 clients->data, silc_buffer_len(clients));
4327 silc_buffer_free(clients);
4331 silc_buffer_push(umodes, umodes->data - umodes->head);
4332 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4334 /* Send the packet */
4335 silc_server_packet_send(server, remote,
4336 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4337 umodes->data, silc_buffer_len(umodes));
4339 silc_buffer_free(umodes);
4343 /* Returns channel's topic for announcing it */
4345 void silc_server_announce_get_channel_topic(SilcServer server,
4346 SilcChannelEntry channel,
4351 if (channel->topic) {
4352 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4353 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4355 silc_buffer_len(chidp),
4357 strlen(channel->topic));
4358 silc_buffer_free(chidp);
4362 /* Returns channel's invite and ban lists */
4364 void silc_server_announce_get_inviteban(SilcServer server,
4365 SilcChannelEntry channel,
4369 SilcBuffer list, idp, idp2, tmp2;
4372 SilcHashTableList htl;
4373 const unsigned char a[1] = { 0x03 };
4375 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4377 /* Encode invite list */
4378 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4379 list = silc_buffer_alloc_size(2);
4380 type = silc_hash_table_count(channel->invite_list);
4381 SILC_PUT16_MSB(type, list->data);
4382 silc_hash_table_list(channel->invite_list, &htl);
4383 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4384 list = silc_argument_payload_encode_one(list, tmp2->data,
4385 silc_buffer_len(tmp2),
4386 SILC_PTR_TO_32(ptype));
4387 silc_hash_table_list_reset(&htl);
4389 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4391 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4392 idp->data, silc_buffer_len(idp),
4393 channel->channel_name,
4394 strlen(channel->channel_name),
4395 idp2->data, silc_buffer_len(idp2),
4397 list->data, silc_buffer_len(list));
4398 silc_buffer_free(idp2);
4399 silc_buffer_free(list);
4402 /* Encode ban list */
4403 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4404 list = silc_buffer_alloc_size(2);
4405 type = silc_hash_table_count(channel->ban_list);
4406 SILC_PUT16_MSB(type, list->data);
4407 silc_hash_table_list(channel->ban_list, &htl);
4408 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4409 list = silc_argument_payload_encode_one(list, tmp2->data,
4410 silc_buffer_len(tmp2),
4411 SILC_PTR_TO_32(ptype));
4412 silc_hash_table_list_reset(&htl);
4415 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4416 idp->data, silc_buffer_len(idp),
4418 list->data, silc_buffer_len(list));
4419 silc_buffer_free(list);
4422 silc_buffer_free(idp);
4425 /* Returns assembled packets for channel users of the `channel'. */
4427 void silc_server_announce_get_channel_users(SilcServer server,
4428 SilcChannelEntry channel,
4429 SilcBuffer *channel_modes,
4430 SilcBuffer *channel_users,
4431 SilcBuffer *channel_users_modes)
4433 SilcChannelClientEntry chl;
4434 SilcHashTableList htl;
4435 SilcBuffer chidp, clidp, csidp;
4436 SilcBuffer tmp, fkey = NULL, chpklist;
4438 unsigned char mode[4], ulimit[4];
4442 SILC_LOG_DEBUG(("Start"));
4444 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4445 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4446 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4449 SILC_PUT32_MSB(channel->mode, mode);
4450 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4451 SILC_PUT32_MSB(channel->user_limit, ulimit);
4452 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4453 if (channel->founder_key)
4454 fkey = silc_public_key_payload_encode(channel->founder_key);
4456 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4458 silc_buffer_len(csidp),
4461 hmac, hmac ? strlen(hmac) : 0,
4462 channel->passphrase,
4463 channel->passphrase ?
4464 strlen(channel->passphrase) : 0,
4465 fkey ? fkey->data : NULL,
4466 fkey ? silc_buffer_len(fkey) : 0,
4467 chpklist ? chpklist->data : NULL,
4469 silc_buffer_len(chpklist) : 0,
4471 SILC_CHANNEL_MODE_ULIMIT ?
4474 SILC_CHANNEL_MODE_ULIMIT ?
4475 sizeof(ulimit) : 0));
4476 len = silc_buffer_len(tmp);
4478 silc_buffer_realloc(*channel_modes,
4480 silc_buffer_truelen((*channel_modes)) + len : len));
4483 *channel_modes = tmp2;
4484 silc_buffer_pull_tail(*channel_modes,
4485 ((*channel_modes)->end -
4486 (*channel_modes)->data));
4487 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4488 silc_buffer_pull(*channel_modes, len);
4489 silc_buffer_free(tmp);
4490 silc_buffer_free(fkey);
4493 /* Now find all users on the channel */
4494 silc_hash_table_list(channel->user_list, &htl);
4495 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4496 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4498 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4502 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4504 silc_buffer_len(clidp),
4506 silc_buffer_len(chidp));
4507 len = silc_buffer_len(tmp);
4509 silc_buffer_realloc(*channel_users,
4511 silc_buffer_truelen((*channel_users)) + len : len));
4514 *channel_users = tmp2;
4515 silc_buffer_pull_tail(*channel_users,
4516 ((*channel_users)->end -
4517 (*channel_users)->data));
4519 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4520 silc_buffer_pull(*channel_users, len);
4521 silc_buffer_free(tmp);
4523 /* CUMODE notify for mode change on the channel */
4524 SILC_PUT32_MSB(chl->mode, mode);
4525 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4526 fkey = silc_public_key_payload_encode(channel->founder_key);
4527 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4529 silc_buffer_len(csidp),
4532 silc_buffer_len(clidp),
4533 fkey ? fkey->data : NULL,
4534 fkey ? silc_buffer_len(fkey) : 0);
4535 len = silc_buffer_len(tmp);
4537 silc_buffer_realloc(*channel_users_modes,
4538 (*channel_users_modes ?
4539 silc_buffer_truelen((*channel_users_modes)) +
4543 *channel_users_modes = tmp2;
4544 silc_buffer_pull_tail(*channel_users_modes,
4545 ((*channel_users_modes)->end -
4546 (*channel_users_modes)->data));
4548 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4549 silc_buffer_pull(*channel_users_modes, len);
4550 silc_buffer_free(tmp);
4551 silc_buffer_free(fkey);
4553 silc_buffer_free(clidp);
4555 silc_hash_table_list_reset(&htl);
4556 silc_buffer_free(chidp);
4557 silc_buffer_free(csidp);
4560 /* Returns assembled packets for all channels and users on those channels
4561 from the given ID List. The packets are in the form dictated by the
4562 New Channel and New Channel User payloads. */
4564 void silc_server_announce_get_channels(SilcServer server,
4566 SilcBuffer *channels,
4567 SilcBuffer **channel_modes,
4568 SilcBuffer *channel_users,
4569 SilcBuffer **channel_users_modes,
4570 SilcUInt32 *channel_users_modes_c,
4571 SilcBuffer **channel_topics,
4572 SilcBuffer **channel_invites,
4573 SilcBuffer **channel_bans,
4574 SilcChannelID ***channel_ids,
4575 unsigned long creation_time)
4578 SilcIDCacheEntry id_cache;
4579 SilcChannelEntry channel;
4580 unsigned char cid[32];
4582 SilcUInt16 name_len;
4584 int i = *channel_users_modes_c;
4588 SILC_LOG_DEBUG(("Start"));
4590 /* Go through all channels in the list */
4591 if (silc_idcache_get_all(id_list->channels, &list)) {
4592 silc_list_start(list);
4593 while ((id_cache = silc_list_get(list))) {
4594 channel = (SilcChannelEntry)id_cache->context;
4596 if (creation_time && channel->created < creation_time)
4601 SILC_LOG_DEBUG(("Announce Channel ID %s",
4602 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4604 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4605 name_len = strlen(channel->channel_name);
4608 len = 4 + name_len + id_len + 4;
4610 silc_buffer_realloc(*channels,
4612 silc_buffer_truelen((*channels)) +
4618 silc_buffer_pull_tail(*channels,
4619 ((*channels)->end - (*channels)->data));
4620 silc_buffer_format(*channels,
4621 SILC_STR_UI_SHORT(name_len),
4622 SILC_STR_UI_XNSTRING(channel->channel_name,
4624 SILC_STR_UI_SHORT(id_len),
4625 SILC_STR_UI_XNSTRING(cid, id_len),
4626 SILC_STR_UI_INT(channel->mode),
4628 silc_buffer_pull(*channels, len);
4631 if (creation_time && channel->updated < creation_time)
4637 /* Channel user modes */
4638 tmp = silc_realloc(*channel_users_modes,
4639 sizeof(**channel_users_modes) * (i + 1));
4642 *channel_users_modes = tmp;
4643 (*channel_users_modes)[i] = NULL;
4644 tmp = silc_realloc(*channel_modes,
4645 sizeof(**channel_modes) * (i + 1));
4648 *channel_modes = tmp;
4649 (*channel_modes)[i] = NULL;
4650 tmp = silc_realloc(*channel_ids,
4651 sizeof(**channel_ids) * (i + 1));
4655 (*channel_ids)[i] = NULL;
4656 silc_server_announce_get_channel_users(server, channel,
4657 &(*channel_modes)[i],
4659 &(*channel_users_modes)[i]);
4660 (*channel_ids)[i] = channel->id;
4662 /* Channel's topic */
4663 tmp = silc_realloc(*channel_topics,
4664 sizeof(**channel_topics) * (i + 1));
4667 *channel_topics = tmp;
4668 (*channel_topics)[i] = NULL;
4669 silc_server_announce_get_channel_topic(server, channel,
4670 &(*channel_topics)[i]);
4672 /* Channel's invite and ban list */
4673 tmp = silc_realloc(*channel_invites,
4674 sizeof(**channel_invites) * (i + 1));
4677 *channel_invites = tmp;
4678 (*channel_invites)[i] = NULL;
4679 tmp = silc_realloc(*channel_bans,
4680 sizeof(**channel_bans) * (i + 1));
4683 *channel_bans = tmp;
4684 (*channel_bans)[i] = NULL;
4685 silc_server_announce_get_inviteban(server, channel,
4686 &(*channel_invites)[i],
4687 &(*channel_bans)[i]);
4689 (*channel_users_modes_c)++;
4697 /* This function is used to announce our existing channels to our router
4698 when we've connected to it. This also announces the users on the
4699 channels to the router. If the `creation_time' is non-zero only the
4700 channels that was created after the `creation_time' are announced.
4701 Note that the channel users are still announced even if the `creation_time'
4704 void silc_server_announce_channels(SilcServer server,
4705 unsigned long creation_time,
4706 SilcPacketStream remote)
4708 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4709 SilcBuffer *channel_users_modes = NULL;
4710 SilcBuffer *channel_topics = NULL;
4711 SilcBuffer *channel_invites = NULL;
4712 SilcBuffer *channel_bans = NULL;
4713 SilcUInt32 channel_users_modes_c = 0;
4714 SilcChannelID **channel_ids = NULL;
4716 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4718 /* Get channels and channel users in local list */
4719 silc_server_announce_get_channels(server, server->local_list,
4720 &channels, &channel_modes,
4722 &channel_users_modes,
4723 &channel_users_modes_c,
4727 &channel_ids, creation_time);
4729 /* Get channels and channel users in global list */
4730 if (server->server_type != SILC_SERVER)
4731 silc_server_announce_get_channels(server, server->global_list,
4732 &channels, &channel_modes,
4734 &channel_users_modes,
4735 &channel_users_modes_c,
4739 &channel_ids, creation_time);
4742 silc_buffer_push(channels, channels->data - channels->head);
4743 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4745 /* Send the packet */
4746 silc_server_packet_send(server, remote,
4747 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4748 channels->data, silc_buffer_len(channels));
4750 silc_buffer_free(channels);
4753 if (channel_users) {
4754 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4755 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4756 silc_buffer_len(channel_users));
4758 /* Send the packet */
4759 silc_server_packet_send(server, remote,
4760 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4761 channel_users->data, silc_buffer_len(channel_users));
4763 silc_buffer_free(channel_users);
4766 if (channel_modes) {
4769 for (i = 0; i < channel_users_modes_c; i++) {
4770 if (!channel_modes[i])
4772 silc_buffer_push(channel_modes[i],
4773 channel_modes[i]->data -
4774 channel_modes[i]->head);
4775 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4776 silc_buffer_len(channel_modes[i]));
4777 silc_server_packet_send_dest(server, remote,
4778 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4779 channel_ids[i], SILC_ID_CHANNEL,
4780 channel_modes[i]->data,
4781 silc_buffer_len(channel_modes[i]));
4782 silc_buffer_free(channel_modes[i]);
4784 silc_free(channel_modes);
4787 if (channel_users_modes) {
4790 for (i = 0; i < channel_users_modes_c; i++) {
4791 if (!channel_users_modes[i])
4793 silc_buffer_push(channel_users_modes[i],
4794 channel_users_modes[i]->data -
4795 channel_users_modes[i]->head);
4796 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4797 silc_buffer_len(channel_users_modes[i]));
4798 silc_server_packet_send_dest(server, remote,
4799 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4800 channel_ids[i], SILC_ID_CHANNEL,
4801 channel_users_modes[i]->data,
4802 silc_buffer_len(channel_users_modes[i]));
4803 silc_buffer_free(channel_users_modes[i]);
4805 silc_free(channel_users_modes);
4808 if (channel_topics) {
4811 for (i = 0; i < channel_users_modes_c; i++) {
4812 if (!channel_topics[i])
4815 silc_buffer_push(channel_topics[i],
4816 channel_topics[i]->data -
4817 channel_topics[i]->head);
4818 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4819 silc_buffer_len(channel_topics[i]));
4820 silc_server_packet_send_dest(server, remote,
4821 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4822 channel_ids[i], SILC_ID_CHANNEL,
4823 channel_topics[i]->data,
4824 silc_buffer_len(channel_topics[i]));
4825 silc_buffer_free(channel_topics[i]);
4827 silc_free(channel_topics);
4830 if (channel_invites) {
4833 for (i = 0; i < channel_users_modes_c; i++) {
4834 if (!channel_invites[i])
4837 silc_buffer_push(channel_invites[i],
4838 channel_invites[i]->data -
4839 channel_invites[i]->head);
4840 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4841 silc_buffer_len(channel_invites[i]));
4842 silc_server_packet_send_dest(server, remote,
4843 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4844 channel_ids[i], SILC_ID_CHANNEL,
4845 channel_invites[i]->data,
4846 silc_buffer_len(channel_invites[i]));
4847 silc_buffer_free(channel_invites[i]);
4849 silc_free(channel_invites);
4855 for (i = 0; i < channel_users_modes_c; i++) {
4856 if (!channel_bans[i])
4859 silc_buffer_push(channel_bans[i],
4860 channel_bans[i]->data -
4861 channel_bans[i]->head);
4862 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4863 silc_buffer_len(channel_bans[i]));
4864 silc_server_packet_send_dest(server, remote,
4865 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4866 channel_ids[i], SILC_ID_CHANNEL,
4867 channel_bans[i]->data,
4868 silc_buffer_len(channel_bans[i]));
4869 silc_buffer_free(channel_bans[i]);
4871 silc_free(channel_bans);
4874 silc_free(channel_ids);
4877 /* Announces WATCH list. */
4879 void silc_server_announce_watches(SilcServer server,
4880 SilcPacketStream remote)
4882 SilcHashTableList htl;
4883 SilcBuffer buffer, idp, args, pkp;
4884 SilcClientEntry client;
4887 SILC_LOG_DEBUG(("Announcing watch list"));
4889 /* XXX because way we save the nicks (hash) we cannot announce them. */
4891 /* XXX we should send all public keys in one command if client is
4892 watching more than one key */
4893 silc_hash_table_list(server->watcher_list_pk, &htl);
4894 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4895 if (!client || !client->id)
4898 server->stat.commands_sent++;
4900 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4901 args = silc_buffer_alloc_size(2);
4902 silc_buffer_format(args,
4903 SILC_STR_UI_SHORT(1),
4905 pkp = silc_public_key_payload_encode(key);
4906 args = silc_argument_payload_encode_one(args, pkp->data,
4907 silc_buffer_len(pkp), 0x00);
4908 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4909 ++server->cmd_ident, 2,
4910 1, idp->data, silc_buffer_len(idp),
4912 silc_buffer_len(args));
4915 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4916 buffer->data, silc_buffer_len(buffer));
4918 silc_buffer_free(pkp);
4919 silc_buffer_free(args);
4920 silc_buffer_free(idp);
4921 silc_buffer_free(buffer);
4923 silc_hash_table_list_reset(&htl);
4926 /* Assembles user list and users mode list from the `channel'. */
4928 SilcBool silc_server_get_users_on_channel(SilcServer server,
4929 SilcChannelEntry channel,
4930 SilcBuffer *user_list,
4931 SilcBuffer *mode_list,
4932 SilcUInt32 *user_count)
4934 SilcChannelClientEntry chl;
4935 SilcHashTableList htl;
4936 SilcBuffer client_id_list;
4937 SilcBuffer client_mode_list;
4939 SilcUInt32 list_count = 0, len = 0;
4941 if (!silc_hash_table_count(channel->user_list))
4944 silc_hash_table_list(channel->user_list, &htl);
4945 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4946 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4947 silc_hash_table_list_reset(&htl);
4949 client_id_list = silc_buffer_alloc(len);
4951 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4952 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4953 silc_buffer_pull_tail(client_mode_list,
4954 silc_buffer_truelen(client_mode_list));
4956 silc_hash_table_list(channel->user_list, &htl);
4957 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4959 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4960 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4961 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4962 silc_buffer_free(idp);
4964 /* Client's mode on channel */
4965 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4966 silc_buffer_pull(client_mode_list, 4);
4970 silc_hash_table_list_reset(&htl);
4971 silc_buffer_push(client_id_list,
4972 client_id_list->data - client_id_list->head);
4973 silc_buffer_push(client_mode_list,
4974 client_mode_list->data - client_mode_list->head);
4976 *user_list = client_id_list;
4977 *mode_list = client_mode_list;
4978 *user_count = list_count;
4982 /* Saves users and their modes to the `channel'. */
4984 void silc_server_save_users_on_channel(SilcServer server,
4985 SilcPacketStream sock,
4986 SilcChannelEntry channel,
4987 SilcClientID *noadd,
4988 SilcBuffer user_list,
4989 SilcBuffer mode_list,
4990 SilcUInt32 user_count)
4996 SilcClientEntry client;
4997 SilcIDCacheEntry cache;
4998 SilcChannelClientEntry chl;
5000 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5001 channel->channel_name));
5003 for (i = 0; i < user_count; i++) {
5005 SILC_GET16_MSB(idp_len, user_list->data + 2);
5007 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5009 silc_buffer_pull(user_list, idp_len);
5012 SILC_GET32_MSB(mode, mode_list->data);
5013 silc_buffer_pull(mode_list, 4);
5015 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5020 /* Check if we have this client cached already. */
5021 client = silc_idlist_find_client_by_id(server->local_list,
5023 server->server_type, &cache);
5025 client = silc_idlist_find_client_by_id(server->global_list,
5027 server->server_type, &cache);
5029 /* If router did not find such Client ID in its lists then this must
5030 be bogus client or some router in the net is buggy. */
5031 if (server->server_type != SILC_SERVER)
5034 /* We don't have that client anywhere, add it. The client is added
5035 to global list since server didn't have it in the lists so it must be
5037 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5038 silc_id_dup(&id.u.client_id,
5040 silc_packet_get_context(sock),
5043 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5047 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5050 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5051 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5052 "%s", channel->channel_name));
5056 if (!silc_server_client_on_channel(client, channel, &chl)) {
5057 /* Client was not on the channel, add it. */
5058 chl = silc_calloc(1, sizeof(*chl));
5059 chl->client = client;
5061 chl->channel = channel;
5062 silc_hash_table_add(channel->user_list, chl->client, chl);
5063 silc_hash_table_add(client->channels, chl->channel, chl);
5064 channel->user_count++;
5072 /* Saves channels and channels user modes to the `client'. Removes
5073 the client from those channels that are not sent in the list but
5076 void silc_server_save_user_channels(SilcServer server,
5077 SilcPacketStream sock,
5078 SilcClientEntry client,
5079 SilcBuffer channels,
5080 SilcBuffer channels_user_modes)
5083 SilcUInt32 *chumodes;
5084 SilcChannelPayload entry;
5085 SilcChannelEntry channel;
5086 SilcChannelID channel_id;
5087 SilcChannelClientEntry chl;
5088 SilcHashTable ht = NULL;
5089 SilcHashTableList htl;
5093 if (!channels || !channels_user_modes ||
5094 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5097 ch = silc_channel_payload_parse_list(channels->data,
5098 silc_buffer_len(channels));
5099 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5101 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5102 NULL, NULL, NULL, TRUE);
5103 silc_dlist_start(ch);
5104 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5105 /* Check if we have this channel, and add it if we don't have it.
5106 Also add the client on the channel unless it is there already. */
5107 if (!silc_channel_get_id_parse(entry, &channel_id))
5109 channel = silc_idlist_find_channel_by_id(server->local_list,
5112 channel = silc_idlist_find_channel_by_id(server->global_list,
5115 if (server->server_type != SILC_SERVER) {
5120 /* We don't have that channel anywhere, add it. */
5121 name = silc_channel_get_name(entry, NULL);
5122 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5123 silc_id_dup(&channel_id,
5125 server->router, NULL, NULL, 0);
5132 channel->mode = silc_channel_get_mode(entry);
5134 /* Add the client on the channel */
5135 if (!silc_server_client_on_channel(client, channel, &chl)) {
5136 chl = silc_calloc(1, sizeof(*chl));
5137 chl->client = client;
5138 chl->mode = chumodes[i++];
5139 chl->channel = channel;
5140 silc_hash_table_add(channel->user_list, chl->client, chl);
5141 silc_hash_table_add(client->channels, chl->channel, chl);
5142 channel->user_count++;
5145 chl->mode = chumodes[i++];
5148 silc_hash_table_add(ht, channel, channel);
5150 silc_channel_payload_list_free(ch);
5151 silc_free(chumodes);
5155 /* Go through the list again and remove client from channels that
5156 are no part of the list. */
5158 silc_hash_table_list(client->channels, &htl);
5159 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5160 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5161 silc_hash_table_del(chl->channel->user_list, chl->client);
5162 silc_hash_table_del(chl->client->channels, chl->channel);
5166 silc_hash_table_list_reset(&htl);
5167 silc_hash_table_free(ht);
5169 silc_hash_table_list(client->channels, &htl);
5170 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5171 silc_hash_table_del(chl->channel->user_list, chl->client);
5172 silc_hash_table_del(chl->client->channels, chl->channel);
5175 silc_hash_table_list_reset(&htl);
5179 /* Lookups route to the client indicated by the `id_data'. The connection
5180 object and internal data object is returned. Returns NULL if route
5181 could not be found to the client. If the `client_id' is specified then
5182 it is used and the `id_data' is ignored. */
5185 silc_server_get_client_route(SilcServer server,
5186 unsigned char *id_data,
5188 SilcClientID *client_id,
5189 SilcIDListData *idata,
5190 SilcClientEntry *client_entry)
5192 SilcClientID *id, clid;
5193 SilcClientEntry client;
5195 SILC_LOG_DEBUG(("Start"));
5198 *client_entry = NULL;
5200 /* Decode destination Client ID */
5202 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5204 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5206 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5209 /* If the destination belongs to our server we don't have to route
5210 the packet anywhere but to send it to the local destination. */
5211 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5215 /* If we are router and the client has router then the client is in
5216 our cell but not directly connected to us. */
5217 if (server->server_type == SILC_ROUTER && client->router) {
5218 /* We are of course in this case the client's router thus the route
5219 to the client is the server who owns the client. So, we will send
5220 the packet to that server. */
5222 *idata = (SilcIDListData)client->router;
5223 return client->router->connection;
5226 /* Seems that client really is directly connected to us */
5228 *idata = (SilcIDListData)client;
5230 *client_entry = client;
5231 return client->connection;
5234 /* Destination belongs to someone not in this server. If we are normal
5235 server our action is to send the packet to our router. */
5236 if (server->server_type != SILC_ROUTER && !server->standalone) {
5239 *idata = (SilcIDListData)server->router;
5240 return SILC_PRIMARY_ROUTE(server);
5243 /* We are router and we will perform route lookup for the destination
5244 and send the packet to fastest route. */
5245 if (server->server_type == SILC_ROUTER && !server->standalone) {
5246 /* Check first that the ID is valid */
5247 client = silc_idlist_find_client_by_id(server->global_list, id,
5250 SilcPacketStream dst_sock;
5252 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5255 if (idata && dst_sock)
5256 *idata = silc_packet_get_context(dst_sock);
5265 /* Encodes and returns channel list of channels the `client' has joined.
5266 Secret channels are not put to the list. */
5268 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5269 SilcClientEntry client,
5270 SilcBool get_private,
5271 SilcBool get_secret,
5272 SilcBuffer *user_mode_list)
5274 SilcBuffer buffer = NULL;
5275 SilcChannelEntry channel;
5276 SilcChannelClientEntry chl;
5277 SilcHashTableList htl;
5278 unsigned char cid[32];
5280 SilcUInt16 name_len;
5284 *user_mode_list = NULL;
5286 silc_hash_table_list(client->channels, &htl);
5287 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5288 channel = chl->channel;
5290 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5292 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5295 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5296 name_len = strlen(channel->channel_name);
5298 len = 4 + name_len + id_len + 4;
5299 buffer = silc_buffer_realloc(buffer,
5301 silc_buffer_truelen(buffer) + len : len));
5302 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5303 silc_buffer_format(buffer,
5304 SILC_STR_UI_SHORT(name_len),
5305 SILC_STR_DATA(channel->channel_name, name_len),
5306 SILC_STR_UI_SHORT(id_len),
5307 SILC_STR_DATA(cid, id_len),
5308 SILC_STR_UI_INT(chl->channel->mode),
5310 silc_buffer_pull(buffer, len);
5312 if (user_mode_list) {
5314 silc_buffer_realloc(*user_mode_list,
5316 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5317 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5318 (*user_mode_list)->data));
5319 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5320 silc_buffer_pull(*user_mode_list, 4);
5323 silc_hash_table_list_reset(&htl);
5326 silc_buffer_push(buffer, buffer->data - buffer->head);
5327 if (user_mode_list && *user_mode_list)
5328 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5329 (*user_mode_list)->head));
5334 /* Task callback used to retrieve network statistical information from
5335 router server once in a while. */
5337 SILC_TASK_CALLBACK(silc_server_get_stats)
5339 SilcServer server = (SilcServer)context;
5340 SilcBuffer idp, packet;
5342 if (!server->standalone) {
5343 SILC_LOG_DEBUG(("Retrieving stats from router"));
5344 server->stat.commands_sent++;
5345 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5347 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5348 ++server->cmd_ident, 1,
5350 silc_buffer_len(idp));
5351 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5352 SILC_PACKET_COMMAND, 0, packet->data,
5353 silc_buffer_len(packet));
5354 silc_buffer_free(packet);
5355 silc_buffer_free(idp);
5359 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,