5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2009 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);
325 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
326 NULL, NULL, &ip, &port);
327 #endif /* SILC_DEBUG */
329 SILC_LOG_DEBUG(("Received %s packet [flags %d] from %s:%d",
330 silc_get_packet_name(type), packet->flags, ip, port));
332 /* Parse the packet type */
334 case SILC_PACKET_NOTIFY:
336 * Received notify packet. Server can receive notify packets from
337 * router. Server then relays the notify messages to clients if needed.
339 if (packet->flags & SILC_PACKET_FLAG_LIST)
340 silc_server_notify_list(server, sock, packet);
342 silc_server_notify(server, sock, packet);
346 * Private Message packets
348 case SILC_PACKET_PRIVATE_MESSAGE:
350 * Received private message packet. The packet is coming from either
353 if (packet->flags & SILC_PACKET_FLAG_LIST)
355 idata->last_receive = time(NULL);
356 silc_server_private_message(server, sock, packet);
362 case SILC_PACKET_CHANNEL_MESSAGE:
364 * Received channel message. Channel messages are special packets
365 * (although probably most common ones) thus they are handled
368 if (packet->flags & SILC_PACKET_FLAG_LIST)
370 idata->last_receive = time(NULL);
371 silc_server_channel_message(server, sock, packet);
377 case SILC_PACKET_COMMAND:
379 * Recived command. Processes the command request and allocates the
380 * command context and calls the command.
382 if (packet->flags & SILC_PACKET_FLAG_LIST)
384 server->stat.commands_received++;
385 silc_server_command_process(server, sock, packet);
388 case SILC_PACKET_COMMAND_REPLY:
390 * Received command reply packet. Received command reply to command. It
391 * may be reply to command sent by us or reply to command sent by client
392 * that we've routed further.
394 if (packet->flags & SILC_PACKET_FLAG_LIST)
396 server->stat.commands_received++;
397 silc_server_command_reply(server, sock, packet);
400 case SILC_PACKET_DISCONNECT:
403 char *message = NULL;
404 const char *hostname, *ip;
406 if (packet->flags & SILC_PACKET_FLAG_LIST)
408 if (silc_buffer_len(&packet->buffer) < 1)
411 status = (SilcStatus)packet->buffer.data[0];
412 if (silc_buffer_len(&packet->buffer) > 1 &&
413 silc_utf8_valid(packet->buffer.data + 1,
414 silc_buffer_len(&packet->buffer) - 1))
415 message = silc_memdup(packet->buffer.data + 1,
416 silc_buffer_len(&packet->buffer) - 1);
418 if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
419 NULL, &hostname, &ip, NULL))
422 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", ip, hostname,
423 silc_get_status_message(status), status,
424 message ? message : ""));
428 /* Do not switch to backup in case of error */
429 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
431 /* If backup disconnected then mark that resuming will not be allowed */
432 if (server->server_type == SILC_ROUTER && !server->backup_router &&
433 idata->conn_type == SILC_CONN_SERVER) {
434 SilcServerEntry server_entry = (SilcServerEntry)idata;
435 if (server_entry->server_type == SILC_BACKUP_ROUTER)
436 server->backup_closed = TRUE;
439 /* Handle the disconnection from our end too */
440 if (SILC_IS_LOCAL(idata))
441 silc_server_free_sock_user_data(server, sock, NULL);
442 silc_server_close_connection(server, sock);
443 server->backup_noswitch = FALSE;
447 case SILC_PACKET_CHANNEL_KEY:
449 * Received key for channel. As channels are created by the router
450 * the keys are as well. We will distribute the key to all of our
451 * locally connected clients on the particular channel. Router
452 * never receives this channel and thus is ignored.
454 if (packet->flags & SILC_PACKET_FLAG_LIST)
456 silc_server_channel_key(server, sock, packet);
459 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
461 * Private message key packet.
463 if (packet->flags & SILC_PACKET_FLAG_LIST)
465 silc_server_private_message_key(server, sock, packet);
468 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
470 * Connection authentication request packet. When we receive this packet
471 * we will send to the other end information about our mandatory
472 * authentication method for the connection. This packet maybe received
475 if (packet->flags & SILC_PACKET_FLAG_LIST)
477 silc_server_connection_auth_request(server, sock, packet);
480 case SILC_PACKET_NEW_ID:
482 * Received New ID packet. This includes some new ID that has been
483 * created. It may be for client, server or channel. This is the way
484 * to distribute information about new registered entities in the
487 if (packet->flags & SILC_PACKET_FLAG_LIST)
488 silc_server_new_id_list(server, sock, packet);
490 silc_server_new_id(server, sock, packet);
493 case SILC_PACKET_NEW_CLIENT:
495 * Received new client packet. This includes client information that
496 * we will use to create initial client ID. After creating new
497 * ID we will send it to the client.
499 if (packet->flags & SILC_PACKET_FLAG_LIST)
501 silc_server_new_client(server, sock, packet);
504 case SILC_PACKET_NEW_SERVER:
506 * Received new server packet. This includes Server ID and some other
507 * information that we may save. This is received after server has
510 if (packet->flags & SILC_PACKET_FLAG_LIST)
512 silc_server_new_server(server, sock, packet);
515 case SILC_PACKET_NEW_CHANNEL:
517 * Received new channel packet. Information about new channel in the
518 * network are distributed using this packet.
520 if (packet->flags & SILC_PACKET_FLAG_LIST)
521 silc_server_new_channel_list(server, sock, packet);
523 silc_server_new_channel(server, sock, packet);
526 case SILC_PACKET_HEARTBEAT:
528 * Received heartbeat.
530 if (packet->flags & SILC_PACKET_FLAG_LIST)
534 case SILC_PACKET_KEY_AGREEMENT:
536 * Received heartbeat.
538 if (packet->flags & SILC_PACKET_FLAG_LIST)
540 silc_server_key_agreement(server, sock, packet);
543 case SILC_PACKET_REKEY:
545 * Received re-key packet. The sender wants to regenerate the session
548 if (packet->flags & SILC_PACKET_FLAG_LIST)
550 silc_server_rekey(server, sock, packet);
553 case SILC_PACKET_FTP:
555 if (packet->flags & SILC_PACKET_FLAG_LIST)
557 silc_server_ftp(server, sock, packet);
560 case SILC_PACKET_RESUME_CLIENT:
562 if (packet->flags & SILC_PACKET_FLAG_LIST)
564 silc_server_resume_client(server, sock, packet);
567 case SILC_PACKET_RESUME_ROUTER:
568 /* Resume router packet received. This packet is received for backup
569 router resuming protocol. */
570 if (packet->flags & SILC_PACKET_FLAG_LIST)
572 silc_server_backup_resume_router(server, sock, packet);
576 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
581 /****************************** Server API **********************************/
583 /* Allocates a new SILC server object. This has to be done before the server
584 can be used. After allocation one must call silc_server_init to initialize
585 the server. The new allocated server object is returned to the new_server
588 SilcBool silc_server_alloc(SilcServer *new_server)
592 SILC_LOG_DEBUG(("Allocating new server object"));
594 server = silc_calloc(1, sizeof(*server));
597 server->server_type = SILC_SERVER;
598 server->standalone = TRUE;
599 server->local_list = silc_calloc(1, sizeof(*server->local_list));
600 if (!server->local_list)
602 server->global_list = silc_calloc(1, sizeof(*server->global_list));
603 if (!server->global_list)
605 server->pending_commands = silc_dlist_init();
606 if (!server->pending_commands)
608 server->listeners = silc_dlist_init();
609 if (!server->listeners)
611 server->repository = silc_skr_alloc();
612 if (!server->repository)
614 server->conns = silc_dlist_init();
617 server->expired_clients = silc_dlist_init();
618 if (!server->expired_clients)
621 *new_server = server;
626 /* Free's the SILC server object. This is called at the very end before
629 void silc_server_free(SilcServer server)
632 SilcIDCacheEntry cache;
633 SilcIDListData idata;
635 SILC_LOG_DEBUG(("Free server %p", server));
640 silc_server_backup_free(server);
641 silc_server_config_unref(&server->config_ref);
643 silc_rng_free(server->rng);
644 if (server->public_key)
645 silc_pkcs_public_key_free(server->public_key);
646 if (server->private_key)
647 silc_pkcs_private_key_free(server->private_key);
648 if (server->pending_commands)
649 silc_dlist_uninit(server->pending_commands);
650 if (server->id_entry) {
651 if (server->id_entry->data.sconn)
652 silc_schedule_task_del_by_context(server->schedule,
653 server->id_entry->data.sconn->sock);
654 silc_idlist_del_server(server->local_list, server->id_entry);
657 /* Delete all channels */
658 if (silc_idcache_get_all(server->local_list->channels, &list)) {
659 silc_list_start(list);
660 while ((cache = silc_list_get(list)))
661 silc_idlist_del_channel(server->local_list, cache->context);
663 if (silc_idcache_get_all(server->global_list->channels, &list)) {
664 silc_list_start(list);
665 while ((cache = silc_list_get(list)))
666 silc_idlist_del_channel(server->global_list, cache->context);
669 /* Delete all clients */
670 if (silc_idcache_get_all(server->local_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->local_list, cache->context);
677 if (silc_idcache_get_all(server->global_list->clients, &list)) {
678 silc_list_start(list);
679 while ((cache = silc_list_get(list))) {
680 silc_schedule_task_del_by_context(server->schedule, cache->context);
681 silc_idlist_del_client(server->global_list, cache->context);
685 /* Delete all servers */
686 if (silc_idcache_get_all(server->local_list->servers, &list)) {
687 silc_list_start(list);
688 while ((cache = silc_list_get(list))) {
689 idata = (SilcIDListData)cache->context;
691 silc_schedule_task_del_by_context(server->schedule,
693 silc_idlist_del_server(server->local_list, cache->context);
696 if (silc_idcache_get_all(server->global_list->servers, &list)) {
697 while ((cache = silc_list_get(list))) {
698 idata = (SilcIDListData)cache->context;
700 silc_schedule_task_del_by_context(server->schedule,
702 silc_idlist_del_server(server->global_list, cache->context);
706 silc_schedule_task_del_by_context(server->schedule, server);
707 silc_schedule_uninit(server->schedule);
708 server->schedule = NULL;
710 silc_idcache_free(server->local_list->clients);
711 silc_idcache_free(server->local_list->servers);
712 silc_idcache_free(server->local_list->channels);
713 silc_idcache_free(server->global_list->clients);
714 silc_idcache_free(server->global_list->servers);
715 silc_idcache_free(server->global_list->channels);
716 silc_hash_table_free(server->watcher_list);
717 silc_hash_table_free(server->watcher_list_pk);
718 silc_hash_free(server->md5hash);
719 silc_hash_free(server->sha1hash);
721 silc_dlist_uninit(server->listeners);
722 silc_dlist_uninit(server->conns);
723 silc_dlist_uninit(server->expired_clients);
724 silc_skr_free(server->repository);
725 silc_packet_engine_stop(server->packet_engine);
727 silc_free(server->local_list);
728 silc_free(server->global_list);
729 silc_free(server->server_name);
730 silc_free(server->id);
733 silc_hmac_unregister_all();
734 silc_hash_unregister_all();
735 silc_cipher_unregister_all();
736 silc_pkcs_unregister_all();
739 /* Creates a new server listener. */
741 static SilcNetListener
742 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
744 SilcNetListener listener;
747 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
748 server->config->require_reverse_lookup,
750 silc_server_accept_new_connection, server);
752 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
760 /* Adds a secondary listener. */
762 SilcBool silc_server_init_secondary(SilcServer server)
764 SilcServerConfigServerInfoInterface *interface;
765 SilcNetListener listener;
767 for (interface = server->config->server_info->secondary; interface;
768 interface = interface->next) {
769 listener = silc_server_listen(server, interface->server_ip,
773 silc_dlist_add(server->listeners, listener);
779 /* Initializes the entire SILC server. This is called always before running
780 the server. This is called only once at the initialization of the program.
781 This binds the server to its listenning port. After this function returns
782 one should call silc_server_run to start the server. This returns TRUE
783 when everything is ok to run the server. Configuration file must be
784 read and parsed before calling this. */
786 SilcBool silc_server_init(SilcServer server)
789 SilcServerEntry id_entry;
790 SilcNetListener listener;
794 SILC_LOG_DEBUG(("Initializing server"));
796 server->starttime = time(NULL);
798 /* Take config object for us */
799 silc_server_config_ref(&server->config_ref, server->config,
803 /* Set debugging on if configured */
804 if (server->config->debug_string) {
805 silc_log_debug(TRUE);
806 silc_log_set_debug_string(server->config->debug_string);
808 #endif /* SILC_DEBUG */
810 /* Steal public and private key from the config object */
811 server->public_key = server->config->server_info->public_key;
812 server->private_key = server->config->server_info->private_key;
813 server->config->server_info->public_key = NULL;
814 server->config->server_info->private_key = NULL;
816 /* Register all configured ciphers, PKCS and hash functions. */
817 if (!silc_server_config_register_ciphers(server))
818 silc_cipher_register_default();
819 if (!silc_server_config_register_pkcs(server))
820 silc_pkcs_register_default();
821 if (!silc_server_config_register_hashfuncs(server))
822 silc_hash_register_default();
823 if (!silc_server_config_register_hmacs(server))
824 silc_hmac_register_default();
826 /* Initialize random number generator for the server. */
827 server->rng = silc_rng_alloc();
828 silc_rng_init(server->rng);
829 silc_rng_global_init(server->rng);
831 /* Initialize hash functions for server to use */
832 silc_hash_alloc("md5", &server->md5hash);
833 silc_hash_alloc("sha1", &server->sha1hash);
835 /* Initialize the scheduler */
836 server->schedule = silc_schedule_init(server->config->param.connections_max,
838 if (!server->schedule)
841 /* First, register log files configuration for error output */
842 silc_server_config_setlogfiles(server);
844 /* Initialize ID caches */
845 server->local_list->clients =
846 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
848 server->local_list->servers =
849 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
851 server->local_list->channels =
852 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
855 /* These are allocated for normal server as well as these hold some
856 global information that the server has fetched from its router. For
857 router these are used as they are supposed to be used on router. */
858 server->global_list->clients =
859 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
861 server->global_list->servers =
862 silc_idcache_alloc(0, SILC_ID_SERVER, silc_idlist_server_destructor,
864 server->global_list->channels =
865 silc_idcache_alloc(0, SILC_ID_CHANNEL, silc_idlist_channel_destructor,
868 /* Init watcher lists */
869 server->watcher_list =
870 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
871 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
873 if (!server->watcher_list)
875 server->watcher_list_pk =
876 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
877 silc_hash_public_key_compare, NULL,
879 if (!server->watcher_list_pk)
882 /* Create TCP listener */
883 listener = silc_server_listen(
885 server->config->server_info->primary == NULL ? NULL :
886 server->config->server_info->primary->server_ip,
887 server->config->server_info->primary == NULL ? 0 :
888 server->config->server_info->primary->port);
891 silc_dlist_add(server->listeners, listener);
893 /* Create a Server ID for the server. */
894 port = silc_net_listener_get_port(listener, NULL);
895 ip = silc_net_listener_get_ip(listener, NULL);
896 silc_id_create_server_id(server->config->server_info->primary->public_ip ?
897 server->config->server_info->primary->public_ip :
898 ip[0], port[0], server->rng, &id);
907 server->server_name = server->config->server_info->server_name;
908 server->config->server_info->server_name = NULL;
909 silc_id_id2str(server->id, SILC_ID_SERVER, server->id_string,
910 sizeof(server->id_string), &server->id_string_len);
912 /* Add ourselves to the server list. We don't have a router yet
913 beacuse we haven't established a route yet. It will be done later.
914 For now, NULL is sent as router. This allocates new entry to
917 silc_idlist_add_server(server->local_list, strdup(server->server_name),
919 silc_id_dup(server->id, SILC_ID_SERVER),
922 SILC_LOG_ERROR(("Could not add local server to cache"));
925 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
926 id_entry->data.conn_type = (server->server_type == SILC_SERVER ?
927 SILC_CONN_SERVER : SILC_CONN_ROUTER);
928 server->id_entry = id_entry;
930 /* Create secondary TCP listeners */
931 if (silc_server_init_secondary(server) == FALSE)
934 server->listenning = TRUE;
936 /* Create connections to configured routers. */
937 silc_server_create_connections(server);
939 /* If server connections has been configured then we must be router as
940 normal server cannot have server connections, only router connections. */
941 if (server->config->servers) {
942 SilcServerConfigServer *ptr = server->config->servers;
944 server->server_type = SILC_ROUTER;
946 if (ptr->backup_router) {
947 server->server_type = SILC_BACKUP_ROUTER;
948 server->backup_router = TRUE;
949 server->id_entry->server_type = SILC_BACKUP_ROUTER;
956 if (server->server_type != SILC_ROUTER) {
957 server->stat.servers = 1;
958 server->stat.cell_servers = 1;
960 server->stat.routers = 1;
963 /* If we are normal server we'll retrieve network statisticial information
964 once in a while from the router. */
965 if (server->server_type != SILC_ROUTER)
966 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
969 /* Start packet engine */
970 server->packet_engine =
971 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
972 &silc_server_stream_cbs, server);
973 if (!server->packet_engine)
976 /* Register client entry expiration timeout */
977 silc_schedule_task_add_timeout(server->schedule,
978 silc_server_purge_expired_clients, server,
981 /* Initialize HTTP server */
982 silc_server_http_init(server);
984 SILC_LOG_DEBUG(("Server initialized"));
986 /* We are done here, return succesfully */
990 silc_server_config_unref(&server->config_ref);
994 /* Task callback to close a socket connection after rehash */
996 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
998 SilcServer server = app_context;
999 SilcPacketStream sock = context;
1000 SilcIDListData idata = silc_packet_get_context(sock);
1001 const char *hostname;
1004 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1005 NULL, &hostname, NULL, &port);
1007 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
1008 hostname, port, SILC_CONNTYPE_STRING(idata->conn_type)));
1009 silc_schedule_task_del_by_context(server->schedule, sock);
1010 silc_server_disconnect_remote(server, sock,
1011 SILC_STATUS_ERR_BANNED_FROM_SERVER,
1012 "This connection is removed from "
1014 silc_server_free_sock_user_data(server, sock, NULL);
1017 /* This function basically reads the config file again and switches the config
1018 object pointed by the server object. After that, we have to fix various
1019 things such as the server_name and the listening ports.
1020 Keep in mind that we no longer have the root privileges at this point. */
1022 SilcBool silc_server_rehash(SilcServer server)
1024 SilcServerConfig newconfig;
1026 SILC_LOG_INFO(("Rehashing server"));
1028 /* Reset the logging system */
1029 silc_log_quick(TRUE);
1030 silc_log_flush_all();
1032 /* Start the main rehash phase (read again the config file) */
1033 newconfig = silc_server_config_alloc(server->config_file, server);
1035 SILC_LOG_ERROR(("Rehash FAILED."));
1039 /* Fix the server_name field */
1040 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
1041 silc_free(server->server_name);
1043 /* Check server name */
1044 server->server_name =
1045 silc_identifier_check(newconfig->server_info->server_name,
1046 strlen(newconfig->server_info->server_name),
1047 SILC_STRING_LOCALE, 256, NULL);
1048 if (!server->server_name) {
1049 SILC_LOG_ERROR(("Malformed server name string '%s'",
1050 server->config->server_info->server_name));
1054 /* Update the idcache list with a fresh pointer */
1055 silc_free(server->id_entry->server_name);
1056 server->id_entry->server_name = strdup(server->server_name);
1057 silc_idcache_update_by_context(server->local_list->servers,
1058 server->id_entry, NULL,
1059 strdup(server->id_entry->server_name),
1064 silc_server_config_setlogfiles(server);
1066 /* Change new key pair if necessary */
1067 if (newconfig->server_info->public_key &&
1068 !silc_pkcs_public_key_compare(server->public_key,
1069 newconfig->server_info->public_key)) {
1070 silc_pkcs_public_key_free(server->public_key);
1071 silc_pkcs_private_key_free(server->private_key);
1072 server->public_key = newconfig->server_info->public_key;
1073 server->private_key = newconfig->server_info->private_key;
1074 newconfig->server_info->public_key = NULL;
1075 newconfig->server_info->private_key = NULL;
1078 /* Check for unconfigured server and router connections and close
1079 connections that were unconfigured. */
1081 if (server->config->routers) {
1082 SilcServerConfigRouter *ptr;
1083 SilcServerConfigRouter *newptr;
1086 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1089 /* Check whether new config has this one too */
1090 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
1091 if (silc_string_compare(newptr->host, ptr->host) &&
1092 newptr->port == ptr->port &&
1093 newptr->initiator == ptr->initiator) {
1099 if (!found && ptr->host) {
1100 /* Remove this connection */
1101 SilcPacketStream sock;
1102 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1103 ptr->host, ptr->port);
1105 silc_schedule_task_add_timeout(server->schedule,
1106 silc_server_rehash_close_connection,
1112 if (server->config->servers) {
1113 SilcServerConfigServer *ptr;
1114 SilcServerConfigServer *newptr;
1117 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1120 /* Check whether new config has this one too */
1121 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1122 if (silc_string_compare(newptr->host, ptr->host)) {
1128 if (!found && ptr->host) {
1129 /* Remove this connection */
1130 SilcPacketStream sock;
1131 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1134 silc_schedule_task_add_timeout(server->schedule,
1135 silc_server_rehash_close_connection,
1141 if (server->config->clients) {
1142 SilcServerConfigClient *ptr;
1143 SilcServerConfigClient *newptr;
1146 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1149 /* Check whether new config has this one too */
1150 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1151 if (silc_string_compare(newptr->host, ptr->host)) {
1157 if (!found && ptr->host) {
1158 /* Remove this connection */
1159 SilcPacketStream sock;
1160 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1163 silc_schedule_task_add_timeout(server->schedule,
1164 silc_server_rehash_close_connection,
1170 /* Create connections after rehash */
1171 silc_server_create_connections(server);
1173 /* Check whether our router status has changed */
1174 if (newconfig->servers) {
1175 SilcServerConfigServer *ptr = newconfig->servers;
1177 server->server_type = SILC_ROUTER;
1179 if (ptr->backup_router) {
1180 server->server_type = SILC_BACKUP_ROUTER;
1181 server->backup_router = TRUE;
1182 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1189 /* Our old config is gone now. We'll unreference our reference made in
1190 silc_server_init and then destroy it since we are destroying it
1191 underneath the application (layer which called silc_server_init). */
1192 silc_server_config_unref(&server->config_ref);
1193 silc_server_config_destroy(server->config);
1195 /* Take new config context */
1196 server->config = newconfig;
1197 silc_server_config_ref(&server->config_ref, server->config, server->config);
1200 /* Set debugging on if configured */
1201 if (server->config->debug_string) {
1202 silc_log_debug(TRUE);
1203 silc_log_set_debug_string(server->config->debug_string);
1205 #endif /* SILC_DEBUG */
1207 SILC_LOG_DEBUG(("Server rehashed"));
1212 /* The heart of the server. This runs the scheduler thus runs the server.
1213 When this returns the server has been stopped and the program will
1216 void silc_server_run(SilcServer server)
1218 SILC_LOG_INFO(("SILC Server started"));
1220 /* Start the scheduler, the heart of the SILC server. When this returns
1221 the program will be terminated. */
1222 silc_schedule(server->schedule);
1225 /* Stops the SILC server. This function is used to shutdown the server.
1226 This is usually called after the scheduler has returned. After stopping
1227 the server one should call silc_server_free. */
1229 void silc_server_stop(SilcServer server)
1232 SilcPacketStream ps;
1233 SilcNetListener listener;
1235 SILC_LOG_INFO(("SILC Server shutting down"));
1237 server->server_shutdown = TRUE;
1239 /* Close all connections */
1240 if (server->packet_engine) {
1241 list = silc_packet_engine_get_streams(server->packet_engine);
1243 silc_dlist_start(list);
1244 while ((ps = silc_dlist_get(list))) {
1245 SilcIDListData idata = silc_packet_get_context(ps);
1247 if (!silc_packet_stream_is_valid(ps))
1251 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1253 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1254 "Server is shutting down");
1255 silc_server_free_sock_user_data(server, ps,
1256 "Server is shutting down");
1258 silc_packet_engine_free_streams_list(list);
1261 /* We are not connected to network anymore */
1262 server->standalone = TRUE;
1264 silc_dlist_start(server->listeners);
1265 while ((listener = silc_dlist_get(server->listeners)))
1266 silc_net_close_listener(listener);
1268 silc_server_http_uninit(server);
1270 /* Cancel any possible retry timeouts */
1271 silc_schedule_task_del_by_callback(server->schedule,
1272 silc_server_connect_router);
1273 silc_schedule_task_del_by_callback(server->schedule,
1274 silc_server_connect_to_router_retry);
1275 silc_schedule_task_del_by_callback(server->schedule,
1276 silc_server_connect_to_router);
1278 silc_schedule_stop(server->schedule);
1280 SILC_LOG_DEBUG(("Server stopped"));
1283 /* Purge expired client entries from the server */
1285 SILC_TASK_CALLBACK(silc_server_purge_expired_clients)
1287 SilcServer server = context;
1288 SilcClientEntry client;
1290 SilcUInt64 curtime = silc_time();
1292 SILC_LOG_DEBUG(("Expire timeout"));
1294 silc_dlist_start(server->expired_clients);
1295 while ((client = silc_dlist_get(server->expired_clients))) {
1296 /* For unregistered clients the created timestamp is actually
1297 unregistered timestamp. Make sure client remains in history
1298 at least 500 seconds. */
1299 if (client->data.created && curtime - client->data.created < 500)
1302 id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ?
1303 server->local_list : server->global_list);
1305 silc_idlist_del_data(client);
1306 silc_idlist_del_client(id_list, client);
1307 silc_dlist_del(server->expired_clients, client);
1310 silc_schedule_task_add_timeout(server->schedule,
1311 silc_server_purge_expired_clients, server,
1316 /******************************* Connecting *********************************/
1318 /* Free connection context */
1320 void silc_server_connection_free(SilcServerConnection sconn)
1324 SILC_LOG_DEBUG(("Free connection %p", sconn));
1325 silc_dlist_del(sconn->server->conns, sconn);
1326 silc_server_config_unref(&sconn->conn);
1327 silc_free(sconn->remote_host);
1328 silc_free(sconn->backup_replace_ip);
1332 /* Creates connection to a remote router. */
1334 void silc_server_create_connection(SilcServer server,
1337 const char *remote_host, SilcUInt32 port,
1338 SilcServerConnectCallback callback,
1341 SilcServerConnection sconn;
1343 /* Allocate connection object for hold connection specific stuff. */
1344 sconn = silc_calloc(1, sizeof(*sconn));
1347 sconn->remote_host = strdup(remote_host);
1348 sconn->remote_port = port;
1349 sconn->no_reconnect = reconnect == FALSE;
1350 sconn->callback = callback;
1351 sconn->callback_context = context;
1352 sconn->no_conf = dynamic;
1353 sconn->server = server;
1355 SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn,
1356 remote_host, port));
1358 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1362 /* Connection authentication completion callback */
1365 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1368 SilcServerConnection sconn = context;
1369 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1370 SilcServer server = entry->server;
1371 SilcServerConfigServer *conn;
1372 SilcServerConfigConnParams *param;
1373 SilcIDListData idata;
1374 SilcServerEntry id_entry = NULL;
1375 unsigned char id[32];
1380 SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p",
1385 if (success == FALSE) {
1386 /* Authentication failed */
1388 /* Try reconnecting if configuration wants it */
1389 if (!sconn->no_reconnect) {
1390 silc_schedule_task_add_timeout(server->schedule,
1391 silc_server_connect_to_router_retry,
1393 silc_dlist_del(server->conns, sconn);
1397 if (sconn->callback)
1398 (*sconn->callback)(server, NULL, sconn->callback_context);
1399 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1400 silc_server_disconnect_remote(server, sconn->sock,
1401 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1405 /* XXX For now remote is router always */
1406 entry->data.conn_type = SILC_CONN_ROUTER;
1408 SILC_LOG_INFO(("Connected to %s %s",
1409 SILC_CONNTYPE_STRING(entry->data.conn_type),
1410 sconn->remote_host));
1412 /* Create the actual entry for remote entity */
1413 switch (entry->data.conn_type) {
1414 case SILC_CONN_SERVER:
1415 SILC_LOG_DEBUG(("Remote is SILC server"));
1417 /* Add new server. The server must register itself to us before it
1418 becomes registered to SILC network. */
1419 id_entry = silc_idlist_add_server(server->local_list,
1420 strdup(sconn->remote_host),
1421 SILC_SERVER, NULL, NULL, sconn->sock);
1423 if (sconn->callback)
1424 (*sconn->callback)(server, NULL, sconn->callback_context);
1425 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1426 silc_server_disconnect_remote(server, sconn->sock,
1427 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1432 server->stat.my_servers++;
1433 if (server->server_type == SILC_ROUTER)
1434 server->stat.servers++;
1435 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
1437 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1440 case SILC_CONN_ROUTER:
1441 SILC_LOG_DEBUG(("Remote is SILC router"));
1443 /* Register to network */
1444 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1445 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1446 SILC_STR_UI_SHORT(id_len),
1447 SILC_STR_DATA(id, id_len),
1448 SILC_STR_UI_SHORT(strlen(server->server_name)),
1449 SILC_STR_DATA(server->server_name,
1450 strlen(server->server_name)),
1452 if (sconn->callback)
1453 (*sconn->callback)(server, NULL, sconn->callback_context);
1454 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1455 silc_server_disconnect_remote(server, sconn->sock,
1456 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1461 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1463 /* Check that we do not have this ID already */
1464 id_entry = silc_idlist_find_server_by_id(server->local_list,
1465 &remote_id.u.server_id,
1468 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1470 id_entry = silc_idlist_find_server_by_id(server->global_list,
1471 &remote_id.u.server_id,
1474 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1478 SILC_LOG_DEBUG(("New server id(%s)",
1479 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1481 /* Add the connected router to global server list. Router is sent
1482 as NULL since it's local to us. */
1483 id_entry = silc_idlist_add_server(server->global_list,
1484 strdup(sconn->remote_host),
1486 silc_id_dup(&remote_id.u.server_id,
1490 /* Try reconnecting if configuration wants it */
1491 if (!sconn->no_reconnect) {
1492 silc_schedule_task_add_timeout(server->schedule,
1493 silc_server_connect_to_router_retry,
1495 silc_dlist_del(server->conns, sconn);
1499 if (sconn->callback)
1500 (*sconn->callback)(server, NULL, sconn->callback_context);
1501 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1502 silc_server_disconnect_remote(server, sconn->sock,
1503 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1508 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1509 idata = (SilcIDListData)id_entry;
1510 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1511 SILC_IDLIST_STATUS_LOCAL);
1512 idata->sconn = sconn;
1513 idata->sconn->callback = NULL;
1516 server->stat.my_routers++;
1517 if (server->server_type == SILC_ROUTER)
1518 server->stat.routers++;
1519 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
1521 if (!sconn->backup) {
1522 /* Mark this router our primary router if we're still standalone */
1523 if (server->standalone) {
1524 SILC_LOG_DEBUG(("This connection is our primary router"));
1525 server->id_entry->router = id_entry;
1526 server->router = id_entry;
1527 server->router->server_type = SILC_ROUTER;
1528 server->standalone = FALSE;
1529 server->backup_primary = FALSE;
1531 /* Announce data if we are not backup router (unless not as primary
1532 currently). Backup router announces later at the end of
1533 resuming protocol. */
1534 if (server->backup_router && server->server_type == SILC_ROUTER) {
1535 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1537 /* If we are router then announce our possible servers. Backup
1538 router announces also global servers. */
1539 if (server->server_type == SILC_ROUTER)
1540 silc_server_announce_servers(server,
1541 server->backup_router ? TRUE : FALSE,
1542 0, SILC_PRIMARY_ROUTE(server));
1544 /* Announce our clients and channels to the router */
1545 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1546 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1549 /* If we are backup router then this primary router is whom we are
1551 if (server->server_type == SILC_BACKUP_ROUTER) {
1552 silc_socket_stream_get_info(silc_packet_stream_get_stream(sconn->
1554 NULL, NULL, &ip, NULL);
1555 silc_server_backup_add(server, server->id_entry, ip,
1556 sconn->remote_port, TRUE);
1561 /* We already have primary router. Disconnect this connection */
1562 SILC_LOG_DEBUG(("We already have primary router, disconnect"));
1563 silc_idlist_del_server(server->global_list, id_entry);
1564 if (sconn->callback)
1565 (*sconn->callback)(server, NULL, sconn->callback_context);
1566 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1567 silc_server_disconnect_remote(server, sconn->sock,
1568 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1573 /* Add this server to be our backup router */
1574 id_entry->server_type = SILC_BACKUP_ROUTER;
1575 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1576 sconn->backup_replace_port, FALSE);
1582 if (sconn->callback)
1583 (*sconn->callback)(server, NULL, sconn->callback_context);
1584 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1585 silc_server_disconnect_remote(server, sconn->sock,
1586 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1590 SILC_LOG_DEBUG(("Connection established, sock %p", sconn->sock));
1592 conn = sconn->conn.ref_ptr;
1593 param = &server->config->param;
1594 if (conn && conn->param)
1595 param = conn->param;
1597 /* Register rekey timeout */
1598 sconn->rekey_timeout = param->key_exchange_rekey;
1599 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1600 sconn->sock, sconn->rekey_timeout, 0);
1602 /* Set the entry as packet stream context */
1603 silc_packet_set_context(sconn->sock, id_entry);
1605 /* Call the completion callback to indicate that we've connected to
1607 if (sconn && sconn->callback)
1608 (*sconn->callback)(server, id_entry, sconn->callback_context);
1610 if (sconn == server->router_conn)
1611 server->router_conn = NULL;
1616 /* SKE completion callback */
1618 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1619 SilcSKESecurityProperties prop,
1620 SilcSKEKeyMaterial keymat,
1621 SilcSKERekeyMaterial rekey,
1624 SilcPacketStream sock = context;
1625 SilcUnknownEntry entry = silc_packet_get_context(sock);
1626 SilcServerConnection sconn;
1628 SilcServerConfigRouter *conn;
1629 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1630 void *auth_data = NULL;
1631 SilcUInt32 auth_data_len = 0;
1632 SilcConnAuth connauth;
1633 SilcCipher send_key, receive_key;
1634 SilcHmac hmac_send, hmac_receive;
1636 server = entry->server;
1637 sconn = entry->data.sconn;
1638 conn = sconn->conn.ref_ptr;
1641 SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry));
1643 if (status != SILC_SKE_STATUS_OK) {
1645 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1646 silc_ske_map_status(status), entry->hostname, entry->ip));
1649 /* Try reconnecting if configuration wants it */
1650 if (!sconn->no_reconnect) {
1651 silc_schedule_task_add_timeout(server->schedule,
1652 silc_server_connect_to_router_retry,
1654 silc_dlist_del(server->conns, sconn);
1658 if (sconn->callback)
1659 (*sconn->callback)(server, NULL, sconn->callback_context);
1660 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1661 silc_server_disconnect_remote(server, sconn->sock,
1662 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1666 SILC_LOG_DEBUG(("Setting keys into use"));
1668 /* Set the keys into use. The data will be encrypted after this. */
1669 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1670 &hmac_send, &hmac_receive, NULL)) {
1673 /* Try reconnecting if configuration wants it */
1674 if (!sconn->no_reconnect) {
1675 silc_schedule_task_add_timeout(server->schedule,
1676 silc_server_connect_to_router_retry,
1678 silc_dlist_del(server->conns, sconn);
1682 /* Error setting keys */
1683 if (sconn->callback)
1684 (*sconn->callback)(server, NULL, sconn->callback_context);
1685 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1686 silc_server_disconnect_remote(server, sconn->sock,
1687 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1690 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1691 hmac_receive, FALSE);
1693 SILC_LOG_DEBUG(("Starting connection authentication"));
1695 connauth = silc_connauth_alloc(server->schedule, ske,
1696 server->config->conn_auth_timeout);
1700 /* Try reconnecting if configuration wants it */
1701 if (!sconn->no_reconnect) {
1702 silc_schedule_task_add_timeout(server->schedule,
1703 silc_server_connect_to_router_retry,
1705 silc_dlist_del(server->conns, sconn);
1709 /** Error allocating auth protocol */
1710 if (sconn->callback)
1711 (*sconn->callback)(server, NULL, sconn->callback_context);
1712 silc_server_free_sock_user_data(server, sconn->sock, NULL);
1713 silc_server_disconnect_remote(server, sconn->sock,
1714 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1718 /* Get authentication method */
1720 if (conn->passphrase) {
1721 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1722 auth_meth = SILC_AUTH_PUBLIC_KEY;
1723 auth_data = server->private_key;
1725 auth_meth = SILC_AUTH_PASSWORD;
1726 auth_data = conn->passphrase;
1727 auth_data_len = conn->passphrase_len;
1730 auth_meth = SILC_AUTH_PUBLIC_KEY;
1731 auth_data = server->private_key;
1735 entry->data.rekey = rekey;
1737 /* Start connection authentication */
1739 silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
1740 SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
1741 auth_data, auth_data_len,
1742 silc_server_ke_auth_compl, sconn);
1745 /* Function that is called when the network connection to a router has
1746 been established. This will continue with the key exchange protocol
1747 with the remote router. */
1749 void silc_server_start_key_exchange(SilcServerConnection sconn)
1751 SilcServer server = sconn->server;
1752 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1753 SilcUnknownEntry entry;
1754 SilcSKEParamsStruct params;
1757 /* Cancel any possible retry timeouts */
1758 silc_schedule_task_del_by_context(server->schedule, sconn);
1760 /* Create packet stream */
1761 sconn->sock = silc_packet_stream_create(server->packet_engine,
1762 server->schedule, sconn->stream);
1764 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1765 silc_stream_destroy(sconn->stream);
1767 /* Try reconnecting if configuration wants it */
1768 if (!sconn->no_reconnect) {
1769 silc_schedule_task_add_timeout(server->schedule,
1770 silc_server_connect_to_router_retry,
1772 silc_dlist_del(server->conns, sconn);
1776 if (sconn->callback)
1777 (*sconn->callback)(server, NULL, sconn->callback_context);
1778 silc_server_connection_free(sconn);
1781 server->stat.conn_num++;
1783 /* Set source ID to packet stream */
1784 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1786 silc_packet_stream_destroy(sconn->sock);
1788 /* Try reconnecting if configuration wants it */
1789 if (!sconn->no_reconnect) {
1790 silc_schedule_task_add_timeout(server->schedule,
1791 silc_server_connect_to_router_retry,
1793 silc_dlist_del(server->conns, sconn);
1797 if (sconn->callback)
1798 (*sconn->callback)(server, NULL, sconn->callback_context);
1799 silc_server_connection_free(sconn);
1803 /* Create entry for remote entity */
1804 entry = silc_calloc(1, sizeof(*entry));
1806 silc_packet_stream_destroy(sconn->sock);
1808 /* Try reconnecting if configuration wants it */
1809 if (!sconn->no_reconnect) {
1810 silc_schedule_task_add_timeout(server->schedule,
1811 silc_server_connect_to_router_retry,
1813 silc_dlist_del(server->conns, sconn);
1817 if (sconn->callback)
1818 (*sconn->callback)(server, NULL, sconn->callback_context);
1819 silc_server_connection_free(sconn);
1822 entry->server = server;
1823 entry->data.sconn = sconn;
1824 entry->data.conn_type = SILC_CONN_UNKNOWN;
1825 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
1826 silc_packet_set_context(sconn->sock, entry);
1828 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
1830 /* Set Key Exchange flags from configuration, but fall back to global
1832 memset(¶ms, 0, sizeof(params));
1833 SILC_GET_SKE_FLAGS(conn, params.flags);
1834 if (server->config->param.key_exchange_pfs)
1835 params.flags |= SILC_SKE_SP_FLAG_PFS;
1837 /* Start SILC Key Exchange protocol */
1838 SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
1839 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1840 server->public_key, server->private_key, sconn);
1843 silc_packet_stream_destroy(sconn->sock);
1845 /* Try reconnecting if configuration wants it */
1846 if (!sconn->no_reconnect) {
1847 silc_schedule_task_add_timeout(server->schedule,
1848 silc_server_connect_to_router_retry,
1850 silc_dlist_del(server->conns, sconn);
1854 if (sconn->callback)
1855 (*sconn->callback)(server, NULL, sconn->callback_context);
1856 silc_server_connection_free(sconn);
1859 silc_ske_set_callbacks(ske, silc_server_verify_key,
1860 silc_server_ke_completed, sconn->sock);
1862 /* Start key exchange protocol */
1863 params.version = silc_version_string;
1864 params.timeout_secs = server->config->key_exchange_timeout;
1865 entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1868 /* Timeout callback that will be called to retry connecting to remote
1869 router. This is used by both normal and router server. This will wait
1870 before retrying the connecting. The timeout is generated by exponential
1871 backoff algorithm. */
1873 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1875 SilcServerConnection sconn = context;
1876 SilcServer server = sconn->server;
1877 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1878 SilcServerConfigConnParams *param =
1879 (conn->param ? conn->param : &server->config->param);
1881 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1882 sconn->remote_port));
1884 /* Calculate next timeout */
1885 if (sconn->retry_count >= 1) {
1886 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1887 if (sconn->retry_timeout > param->reconnect_interval_max)
1888 sconn->retry_timeout = param->reconnect_interval_max;
1890 sconn->retry_timeout = param->reconnect_interval;
1892 sconn->retry_count++;
1893 sconn->retry_timeout = sconn->retry_timeout +
1894 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1896 /* If we've reached max retry count, give up. */
1897 if ((sconn->retry_count > param->reconnect_count) &&
1898 sconn->no_reconnect) {
1899 SILC_LOG_ERROR(("Could not connect, giving up"));
1901 if (sconn->callback)
1902 (*sconn->callback)(server, NULL, sconn->callback_context);
1903 silc_server_connection_free(sconn);
1907 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1909 /* We will lookup a fresh pointer later */
1910 silc_server_config_unref(&sconn->conn);
1912 /* Wait before retrying */
1913 silc_schedule_task_del_by_context(server->schedule, sconn);
1914 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1915 sconn, sconn->retry_timeout, 0);
1918 /* Callback for async connection to remote router */
1920 static void silc_server_connection_established(SilcNetStatus status,
1924 SilcServerConnection sconn = context;
1925 SilcServer server = sconn->server;
1927 silc_schedule_task_del_by_context(server->schedule, sconn);
1932 SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
1933 sconn->remote_host, sconn->remote_port));
1935 /* Continue with key exchange protocol */
1936 sconn->stream = stream;
1937 silc_server_start_key_exchange(sconn);
1940 case SILC_NET_UNKNOWN_IP:
1941 case SILC_NET_UNKNOWN_HOST:
1942 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1943 sconn->remote_host, sconn->remote_port,
1944 silc_net_get_error_string(status)));
1945 if (!sconn->no_reconnect) {
1946 silc_schedule_task_add_timeout(sconn->server->schedule,
1947 silc_server_connect_to_router_retry,
1949 silc_dlist_del(server->conns, sconn);
1951 if (sconn->callback)
1952 (*sconn->callback)(server, NULL, sconn->callback_context);
1953 silc_server_connection_free(sconn);
1958 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1959 sconn->remote_host, sconn->remote_port,
1960 silc_net_get_error_string(status)));
1961 if (!sconn->no_reconnect) {
1962 silc_schedule_task_add_timeout(sconn->server->schedule,
1963 silc_server_connect_to_router_retry,
1965 silc_dlist_del(server->conns, sconn);
1967 if (sconn->callback)
1968 (*sconn->callback)(server, NULL, sconn->callback_context);
1969 silc_server_connection_free(sconn);
1975 /* Generic routine to use connect to a router. */
1977 SILC_TASK_CALLBACK(silc_server_connect_router)
1979 SilcServerConnection sconn = context;
1980 SilcServer server = sconn->server;
1981 SilcServerConfigRouter *rconn;
1983 silc_schedule_task_del_by_context(server->schedule, sconn);
1985 /* Don't connect if we are shutting down. */
1986 if (server->server_shutdown) {
1987 if (sconn->callback)
1988 (*sconn->callback)(server, NULL, sconn->callback_context);
1989 silc_server_connection_free(sconn);
1993 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1994 (sconn->backup ? "backup router" : "router"),
1995 sconn->remote_host, sconn->remote_port));
1997 if (!sconn->no_conf) {
1998 /* Find connection configuration */
1999 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
2000 sconn->remote_port);
2002 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
2003 (sconn->backup ? "backup router" : "router"),
2004 sconn->remote_host, sconn->remote_port));
2005 if (sconn->callback)
2006 (*sconn->callback)(server, NULL, sconn->callback_context);
2007 silc_server_connection_free(sconn);
2010 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
2013 /* Connect to remote host */
2015 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
2016 server->config->server_info->primary->server_ip),
2017 sconn->remote_host, sconn->remote_port,
2018 server->schedule, silc_server_connection_established,
2021 SILC_LOG_ERROR(("Could not connect to router %s:%d",
2022 sconn->remote_host, sconn->remote_port));
2023 if (sconn->callback)
2024 (*sconn->callback)(server, NULL, sconn->callback_context);
2025 silc_server_connection_free(sconn);
2029 /* Add to connection list */
2030 silc_dlist_add(server->conns, sconn);
2033 /* This function connects to our primary router or if we are a router this
2034 establishes all our primary routes. This is called at the start of the
2035 server to do authentication and key exchange with our router - called
2038 SILC_TASK_CALLBACK(silc_server_connect_to_router)
2040 SilcServer server = context;
2041 SilcServerConnection sconn;
2042 SilcServerConfigRouter *ptr;
2043 SilcServerConfigConnParams *param;
2045 /* Don't connect if we are shutting down. */
2046 if (server->server_shutdown)
2049 SILC_LOG_DEBUG(("We are %s",
2050 (server->server_type == SILC_SERVER ?
2051 "normal server" : server->server_type == SILC_ROUTER ?
2052 "router" : "backup router/normal server")));
2054 if (!server->config->routers) {
2055 /* There wasn't a configured router, we will continue but we don't
2056 have a connection to outside world. We will be standalone server. */
2057 SILC_LOG_DEBUG(("No router(s), we are standalone"));
2058 server->standalone = TRUE;
2062 /* Cancel any possible retry timeouts */
2063 silc_schedule_task_del_by_callback(server->schedule,
2064 silc_server_connect_router);
2065 silc_schedule_task_del_by_callback(server->schedule,
2066 silc_server_connect_to_router_retry);
2068 /* Create the connections to all our routes */
2069 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
2071 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
2072 ptr->backup_router ? "Backup router" : "Router",
2073 ptr->initiator ? "Initiator" : "Responder",
2074 ptr->host, ptr->port));
2076 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
2077 ptr->initiator == FALSE && !server->backup_router &&
2078 !silc_server_config_get_backup_router(server))
2079 server->wait_backup = TRUE;
2081 if (!ptr->initiator)
2083 if (ptr->dynamic_connection)
2086 /* Check whether we are connecting or connected to this host already */
2087 if (silc_server_num_sockets_by_remote(server,
2088 silc_net_is_ip(ptr->host) ?
2090 silc_net_is_ip(ptr->host) ?
2091 NULL : ptr->host, ptr->port,
2092 SILC_CONN_ROUTER)) {
2093 SILC_LOG_DEBUG(("We are already connected to %s:%d",
2094 ptr->host, ptr->port));
2096 /* If we don't have primary router and this connection is our
2097 primary router we are in desync. Reconnect to the primary. */
2098 if (server->standalone && !server->router) {
2100 SilcPacketStream sock;
2101 SilcServerConfigRouter *primary =
2102 silc_server_config_get_primary_router(server);
2105 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
2106 ptr->host, ptr->port);
2109 server->backup_noswitch = TRUE;
2110 silc_server_free_sock_user_data(server, sock, NULL);
2111 silc_server_disconnect_remote(server, sock, 0, NULL);
2112 server->backup_noswitch = FALSE;
2113 SILC_LOG_DEBUG(("Reconnecting to primary router"));
2119 param = (ptr->param ? ptr->param : &server->config->param);
2121 /* Allocate connection object for hold connection specific stuff. */
2122 sconn = silc_calloc(1, sizeof(*sconn));
2125 sconn->server = server;
2126 sconn->remote_host = strdup(ptr->host);
2127 sconn->remote_port = ptr->port;
2128 sconn->backup = ptr->backup_router;
2129 if (sconn->backup) {
2130 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
2131 sconn->backup_replace_port = ptr->backup_replace_port;
2133 sconn->no_reconnect = param->reconnect_keep_trying == FALSE;
2135 SILC_LOG_DEBUG(("Created connection %p", sconn));
2137 if (!server->router_conn && !sconn->backup)
2138 server->router_conn = sconn;
2141 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
2147 /************************ Accepting new connection **************************/
2149 /* After this is called, server don't wait for backup router anymore.
2150 This gets called automatically even after we have backup router
2151 connection established. */
2153 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
2155 SilcServer server = context;
2156 server->wait_backup = FALSE;
2159 /* Authentication data callback */
2162 silc_server_accept_get_auth(SilcConnAuth connauth,
2163 SilcConnectionType conn_type,
2164 unsigned char **passphrase,
2165 SilcUInt32 *passphrase_len,
2166 SilcSKR *repository,
2169 SilcPacketStream sock = context;
2170 SilcUnknownEntry entry = silc_packet_get_context(sock);
2171 SilcServer server = entry->server;
2173 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
2175 /* Remote end is client */
2176 if (conn_type == SILC_CONN_CLIENT) {
2177 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
2181 *passphrase = cconfig->passphrase;
2182 *passphrase_len = cconfig->passphrase_len;
2183 if (cconfig->publickeys)
2184 *repository = server->repository;
2186 if (cconfig->publickeys) {
2187 if (server->config->prefer_passphrase_auth) {
2191 *passphrase_len = 0;
2195 entry->conn_type = conn_type;
2199 /* Remote end is server */
2200 if (conn_type == SILC_CONN_SERVER) {
2201 SilcServerConfigServer *sconfig;
2203 /* If we are normal server, don't accept the connection */
2204 if (server->server_type == SILC_SERVER)
2207 sconfig = entry->sconfig.ref_ptr;
2211 *passphrase = sconfig->passphrase;
2212 *passphrase_len = sconfig->passphrase_len;
2213 if (sconfig->publickeys)
2214 *repository = server->repository;
2216 if (sconfig->publickeys) {
2217 if (server->config->prefer_passphrase_auth) {
2221 *passphrase_len = 0;
2225 entry->conn_type = conn_type;
2229 /* Remote end is router */
2230 if (conn_type == SILC_CONN_ROUTER) {
2231 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
2235 *passphrase = rconfig->passphrase;
2236 *passphrase_len = rconfig->passphrase_len;
2237 if (rconfig->publickeys)
2238 *repository = server->repository;
2240 if (rconfig->publickeys) {
2241 if (server->config->prefer_passphrase_auth) {
2245 *passphrase_len = 0;
2249 entry->conn_type = conn_type;
2256 /* Authentication completion callback. */
2259 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
2262 SilcPacketStream sock = context;
2263 SilcUnknownEntry entry = silc_packet_get_context(sock);
2264 SilcIDListData idata = (SilcIDListData)entry;
2265 SilcServer server = entry->server;
2266 SilcServerConfigConnParams *param = &server->config->param;
2267 SilcServerConnection sconn;
2269 const char *hostname, *ip;
2273 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2274 NULL, &hostname, &ip, &port);
2276 if (success == FALSE) {
2277 /* Authentication failed */
2278 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
2279 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2280 server->stat.auth_failures++;
2281 silc_server_disconnect_remote(server, sock,
2282 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2283 silc_server_config_unref(&entry->cconfig);
2284 silc_server_config_unref(&entry->sconfig);
2285 silc_server_config_unref(&entry->rconfig);
2286 silc_server_free_sock_user_data(server, sock, NULL);
2290 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2292 switch (entry->conn_type) {
2293 case SILC_CONN_CLIENT:
2295 SilcClientEntry client;
2296 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2298 /* Verify whether this connection is after all allowed to connect */
2299 if (!silc_server_connection_allowed(server, sock, entry->conn_type,
2300 &server->config->param,
2302 silc_connauth_get_ske(connauth))) {
2303 server->stat.auth_failures++;
2307 /* If we are primary router and we have backup router configured
2308 but it has not connected to use yet, do not accept any other
2310 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2311 !server->backup_router) {
2312 SilcServerConfigRouter *router;
2313 router = silc_server_config_get_backup_router(server);
2314 if (router && strcmp(server->config->server_info->primary->server_ip,
2316 silc_server_find_socket_by_host(server,
2318 router->backup_replace_ip, 0)) {
2319 SILC_LOG_INFO(("Will not accept connections because we do "
2320 "not have backup router connection established"));
2321 silc_server_disconnect_remote(server, sock,
2322 SILC_STATUS_ERR_PERM_DENIED,
2323 "We do not have connection to backup "
2324 "router established, try later");
2325 silc_server_config_unref(&entry->cconfig);
2326 silc_server_config_unref(&entry->sconfig);
2327 silc_server_config_unref(&entry->rconfig);
2328 silc_server_free_sock_user_data(server, sock, NULL);
2329 server->stat.auth_failures++;
2331 /* From here on, wait 20 seconds for the backup router to appear. */
2332 silc_schedule_task_add_timeout(server->schedule,
2333 silc_server_backup_router_wait,
2334 (void *)server, 20, 0);
2339 SILC_LOG_DEBUG(("Remote host is client"));
2340 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2343 /* Add the client to the client ID cache. The nickname and Client ID
2344 and other information is created after we have received NEW_CLIENT
2345 packet from client. */
2346 client = silc_idlist_add_client(server->local_list,
2347 NULL, NULL, NULL, NULL, NULL, sock);
2349 SILC_LOG_ERROR(("Could not add new client to cache"));
2350 server->stat.auth_failures++;
2351 silc_server_disconnect_remote(server, sock,
2352 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2353 silc_server_config_unref(&entry->cconfig);
2354 silc_server_config_unref(&entry->sconfig);
2355 silc_server_config_unref(&entry->rconfig);
2356 silc_server_free_sock_user_data(server, sock, NULL);
2359 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2360 entry->data.conn_type = SILC_CONN_CLIENT;
2363 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
2364 server->stat.clients + 1));
2365 server->stat.my_clients++;
2366 server->stat.clients++;
2367 server->stat.cell_clients++;
2369 /* Get connection parameters */
2371 param = conn->param;
2373 if (!param->keepalive_secs)
2374 param->keepalive_secs = server->config->param.keepalive_secs;
2376 if (!param->qos && server->config->param.qos) {
2377 param->qos = server->config->param.qos;
2378 param->qos_rate_limit = server->config->param.qos_rate_limit;
2379 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2380 param->qos_limit_sec = server->config->param.qos_limit_sec;
2381 param->qos_limit_usec = server->config->param.qos_limit_usec;
2384 /* Check if to be anonymous connection */
2385 if (param->anonymous)
2386 client->mode |= SILC_UMODE_ANONYMOUS;
2389 /* Add public key to repository */
2390 SILC_LOG_DEBUG(("Add client public key to repository"));
2391 if (!silc_server_get_public_key_by_client(server, client, NULL))
2392 silc_skr_add_public_key_simple(server->repository,
2393 entry->data.public_key,
2394 SILC_SKR_USAGE_IDENTIFICATION, client,
2397 id_entry = (void *)client;
2401 case SILC_CONN_SERVER:
2402 case SILC_CONN_ROUTER:
2404 SilcServerEntry new_server;
2405 SilcBool initiator = FALSE;
2406 SilcBool backup_local = FALSE;
2407 SilcBool backup_router = FALSE;
2408 char *backup_replace_ip = NULL;
2409 SilcUInt16 backup_replace_port = 0;
2410 SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
2411 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2413 /* If we are backup router and this is incoming server connection
2414 and we do not have connection to primary router, do not allow
2416 if (server->server_type == SILC_BACKUP_ROUTER &&
2417 entry->conn_type == SILC_CONN_SERVER &&
2418 !SILC_PRIMARY_ROUTE(server)) {
2419 SILC_LOG_INFO(("Will not accept server connection because we do "
2420 "not have primary router connection established"));
2421 silc_server_disconnect_remote(server, sock,
2422 SILC_STATUS_ERR_PERM_DENIED,
2423 "We do not have connection to primary "
2424 "router established, try later");
2425 silc_server_config_unref(&entry->cconfig);
2426 silc_server_config_unref(&entry->sconfig);
2427 silc_server_config_unref(&entry->rconfig);
2428 silc_server_free_sock_user_data(server, sock, NULL);
2429 server->stat.auth_failures++;
2433 if (entry->conn_type == SILC_CONN_ROUTER) {
2434 /* Verify whether this connection is after all allowed to connect */
2435 if (!silc_server_connection_allowed(server, sock,
2437 &server->config->param,
2438 rconn ? rconn->param : NULL,
2439 silc_connauth_get_ske(connauth))) {
2440 silc_server_config_unref(&entry->cconfig);
2441 silc_server_config_unref(&entry->sconfig);
2442 silc_server_config_unref(&entry->rconfig);
2443 server->stat.auth_failures++;
2449 param = rconn->param;
2451 if (!param->keepalive_secs)
2452 param->keepalive_secs = server->config->param.keepalive_secs;
2454 if (!param->qos && server->config->param.qos) {
2455 param->qos = server->config->param.qos;
2456 param->qos_rate_limit = server->config->param.qos_rate_limit;
2457 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2458 param->qos_limit_sec = server->config->param.qos_limit_sec;
2459 param->qos_limit_usec = server->config->param.qos_limit_usec;
2463 initiator = rconn->initiator;
2464 backup_local = rconn->backup_local;
2465 backup_router = rconn->backup_router;
2466 backup_replace_ip = rconn->backup_replace_ip;
2467 backup_replace_port = rconn->backup_replace_port;
2471 if (entry->conn_type == SILC_CONN_SERVER) {
2472 /* Verify whether this connection is after all allowed to connect */
2473 if (!silc_server_connection_allowed(server, sock,
2475 &server->config->param,
2476 srvconn ? srvconn->param : NULL,
2477 silc_connauth_get_ske(connauth))) {
2478 server->stat.auth_failures++;
2482 if (srvconn->param) {
2483 param = srvconn->param;
2485 if (!param->keepalive_secs)
2486 param->keepalive_secs = server->config->param.keepalive_secs;
2488 if (!param->qos && server->config->param.qos) {
2489 param->qos = server->config->param.qos;
2490 param->qos_rate_limit = server->config->param.qos_rate_limit;
2491 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2492 param->qos_limit_sec = server->config->param.qos_limit_sec;
2493 param->qos_limit_usec = server->config->param.qos_limit_usec;
2497 backup_router = srvconn->backup_router;
2501 /* If we are primary router and we have backup router configured
2502 but it has not connected to use yet, do not accept any other
2504 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2505 !server->backup_router && !backup_router) {
2506 SilcServerConfigRouter *router;
2507 router = silc_server_config_get_backup_router(server);
2508 if (router && strcmp(server->config->server_info->primary->server_ip,
2510 silc_server_find_socket_by_host(server,
2512 router->backup_replace_ip, 0)) {
2513 SILC_LOG_INFO(("Will not accept connections because we do "
2514 "not have backup router connection established"));
2515 silc_server_disconnect_remote(server, sock,
2516 SILC_STATUS_ERR_PERM_DENIED,
2517 "We do not have connection to backup "
2518 "router established, try later");
2519 silc_server_config_unref(&entry->cconfig);
2520 silc_server_config_unref(&entry->sconfig);
2521 silc_server_config_unref(&entry->rconfig);
2522 silc_server_free_sock_user_data(server, sock, NULL);
2523 server->stat.auth_failures++;
2525 /* From here on, wait 20 seconds for the backup router to appear. */
2526 silc_schedule_task_add_timeout(server->schedule,
2527 silc_server_backup_router_wait,
2528 (void *)server, 20, 0);
2533 SILC_LOG_DEBUG(("Remote host is %s",
2534 entry->conn_type == SILC_CONN_SERVER ?
2535 "server" : (backup_router ?
2536 "backup router" : "router")));
2537 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2538 entry->ip, entry->conn_type == SILC_CONN_SERVER ?
2539 "server" : (backup_router ?
2540 "backup router" : "router")));
2542 /* Add the server into server cache. The server name and Server ID
2543 is updated after we have received NEW_SERVER packet from the
2544 server. We mark ourselves as router for this server if we really
2547 silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ?
2548 server->local_list : (backup_router ?
2549 server->local_list :
2550 server->global_list)),
2552 (entry->conn_type == SILC_CONN_SERVER ?
2553 SILC_SERVER : SILC_ROUTER),
2555 (entry->conn_type == SILC_CONN_SERVER ?
2556 server->id_entry : (backup_router ?
2557 server->id_entry : NULL)),
2560 SILC_LOG_ERROR(("Could not add new server to cache"));
2561 silc_server_disconnect_remote(server, sock,
2562 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2563 silc_server_config_unref(&entry->cconfig);
2564 silc_server_config_unref(&entry->sconfig);
2565 silc_server_config_unref(&entry->rconfig);
2566 silc_server_free_sock_user_data(server, sock, NULL);
2567 server->stat.auth_failures++;
2570 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2571 entry->data.conn_type = entry->conn_type;
2573 id_entry = (void *)new_server;
2575 /* If the incoming connection is router and marked as backup router
2576 then add it to be one of our backups */
2577 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2578 /* Change it back to SERVER type since that's what it really is. */
2580 entry->data.conn_type = SILC_CONN_SERVER;
2581 new_server->server_type = SILC_BACKUP_ROUTER;
2583 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2584 ("Backup router %s is now online",
2587 /* Remove the backup waiting with timeout */
2588 silc_schedule_task_add_timeout(server->schedule,
2589 silc_server_backup_router_wait,
2590 (void *)server, 10, 0);
2594 if (entry->data.conn_type == SILC_CONN_SERVER) {
2595 server->stat.my_servers++;
2596 server->stat.servers++;
2597 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
2599 server->stat.my_routers++;
2600 server->stat.routers++;
2601 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
2604 /* Check whether this connection is to be our primary router connection
2605 if we do not already have the primary route. */
2606 if (!backup_router &&
2607 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2608 if (silc_server_config_is_primary_route(server) && !initiator)
2611 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2612 server->standalone = FALSE;
2613 if (!server->id_entry->router) {
2614 server->id_entry->router = id_entry;
2615 server->router = id_entry;
2627 /* Add connection to server->conns so that we know we have connection
2629 sconn = silc_calloc(1, sizeof(*sconn));
2632 sconn->server = server;
2634 sconn->remote_host = strdup(hostname);
2635 sconn->remote_port = port;
2636 silc_dlist_add(server->conns, sconn);
2637 idata->sconn = sconn;
2638 idata->sconn->callback = NULL;
2639 idata->last_receive = time(NULL);
2641 /* Add the common data structure to the ID entry. */
2642 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2643 silc_packet_set_context(sock, id_entry);
2645 /* Connection has been fully established now. Everything is ok. */
2646 SILC_LOG_DEBUG(("New connection %p authenticated", sconn));
2648 /* Perform Quality of Service */
2650 silc_socket_stream_set_qos(silc_packet_stream_get_stream(sock),
2651 param->qos_rate_limit, param->qos_bytes_limit,
2652 param->qos_limit_sec, param->qos_limit_usec);
2654 silc_server_config_unref(&entry->cconfig);
2655 silc_server_config_unref(&entry->sconfig);
2656 silc_server_config_unref(&entry->rconfig);
2660 silc_ske_free(silc_connauth_get_ske(connauth));
2661 silc_connauth_free(connauth);
2664 /* SKE completion callback. We set the new keys into use here. */
2667 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2668 SilcSKESecurityProperties prop,
2669 SilcSKEKeyMaterial keymat,
2670 SilcSKERekeyMaterial rekey,
2673 SilcPacketStream sock = context;
2674 SilcUnknownEntry entry = silc_packet_get_context(sock);
2675 SilcIDListData idata = (SilcIDListData)entry;
2676 SilcServer server = entry->server;
2677 SilcConnAuth connauth;
2678 SilcCipher send_key, receive_key;
2679 SilcHmac hmac_send, hmac_receive;
2686 if (status != SILC_SKE_STATUS_OK) {
2688 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2689 silc_ske_map_status(status), entry->hostname, entry->ip));
2691 silc_server_disconnect_remote(server, sock,
2692 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2693 silc_server_config_unref(&entry->cconfig);
2694 silc_server_config_unref(&entry->sconfig);
2695 silc_server_config_unref(&entry->rconfig);
2696 silc_server_free_sock_user_data(server, sock, NULL);
2700 SILC_LOG_DEBUG(("Setting keys into use"));
2702 /* Set the keys into use. The data will be encrypted after this. */
2703 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2704 &hmac_send, &hmac_receive, &hash)) {
2705 /* Error setting keys */
2707 silc_server_disconnect_remote(server, sock,
2708 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2709 silc_server_free_sock_user_data(server, sock, NULL);
2712 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2713 hmac_receive, FALSE);
2715 idata->rekey = rekey;
2716 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2717 pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len);
2719 silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint);
2724 SILC_LOG_DEBUG(("Starting connection authentication"));
2725 server->stat.auth_attempts++;
2727 connauth = silc_connauth_alloc(server->schedule, ske,
2728 server->config->conn_auth_timeout);
2730 /** Error allocating auth protocol */
2732 silc_server_disconnect_remote(server, sock,
2733 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2734 silc_server_config_unref(&entry->cconfig);
2735 silc_server_config_unref(&entry->sconfig);
2736 silc_server_config_unref(&entry->rconfig);
2737 silc_server_free_sock_user_data(server, sock, NULL);
2741 /* Start connection authentication */
2743 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2744 silc_server_accept_auth_compl, sock);
2747 /* Accept new TCP connection */
2749 static void silc_server_accept_new_connection(SilcNetStatus status,
2753 SilcServer server = context;
2754 SilcPacketStream packet_stream;
2755 SilcServerConfigClient *cconfig = NULL;
2756 SilcServerConfigServer *sconfig = NULL;
2757 SilcServerConfigRouter *rconfig = NULL;
2758 SilcServerConfigDeny *deny;
2759 SilcUnknownEntry entry;
2761 SilcSKEParamsStruct params;
2762 char *hostname, *ip;
2765 SILC_LOG_DEBUG(("Accepting new connection"));
2767 /* Check for maximum allowed connections */
2768 server->stat.conn_attempts++;
2769 if (silc_dlist_count(server->conns) >
2770 server->config->param.connections_max) {
2771 SILC_LOG_ERROR(("Refusing connection, server is full"));
2772 server->stat.conn_failures++;
2773 silc_stream_destroy(stream);
2777 /* Get hostname, IP and port */
2778 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2779 (const char **)&ip, &port)) {
2780 /* Bad socket stream */
2781 server->stat.conn_failures++;
2782 silc_stream_destroy(stream);
2786 /* Create packet stream */
2787 packet_stream = silc_packet_stream_create(server->packet_engine,
2788 server->schedule, stream);
2789 if (!packet_stream) {
2790 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2791 server->stat.conn_failures++;
2792 silc_stream_destroy(stream);
2795 server->stat.conn_num++;
2797 SILC_LOG_DEBUG(("Created packet stream %p", packet_stream));
2799 /* Set source ID to packet stream */
2800 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2803 server->stat.conn_failures++;
2804 silc_packet_stream_destroy(packet_stream);
2808 /* Check whether this connection is denied to connect to us. */
2809 deny = silc_server_config_find_denied(server, ip);
2811 deny = silc_server_config_find_denied(server, hostname);
2813 /* The connection is denied */
2814 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2815 silc_server_disconnect_remote(server, packet_stream,
2816 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2818 silc_server_free_sock_user_data(server, packet_stream, NULL);
2822 /* Check whether we have configured this sort of connection at all. We
2823 have to check all configurations since we don't know what type of
2824 connection this is. */
2825 if (!(cconfig = silc_server_config_find_client(server, ip)))
2826 cconfig = silc_server_config_find_client(server, hostname);
2827 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2828 sconfig = silc_server_config_find_server_conn(server, hostname);
2829 if (server->server_type == SILC_ROUTER)
2830 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2831 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2832 if (!cconfig && !sconfig && !rconfig) {
2833 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2834 server->stat.conn_failures++;
2835 silc_server_disconnect_remote(server, packet_stream,
2836 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2837 silc_server_free_sock_user_data(server, packet_stream, NULL);
2841 /* The connection is allowed */
2842 entry = silc_calloc(1, sizeof(*entry));
2844 server->stat.conn_failures++;
2845 silc_server_disconnect_remote(server, packet_stream,
2846 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2847 silc_server_free_sock_user_data(server, packet_stream, NULL);
2850 entry->hostname = hostname;
2853 entry->server = server;
2854 entry->data.conn_type = SILC_CONN_UNKNOWN;
2855 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2856 silc_packet_set_context(packet_stream, entry);
2858 SILC_LOG_DEBUG(("Created unknown connection %p", entry));
2860 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2861 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2862 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2864 /* Take flags for key exchange. Since we do not know what type of connection
2865 this is, we go through all found configurations and use the global ones
2866 as well. This will result always into strictest key exchange flags. */
2867 memset(¶ms, 0, sizeof(params));
2868 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2869 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2870 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2871 if (server->config->param.key_exchange_pfs)
2872 params.flags |= SILC_SKE_SP_FLAG_PFS;
2874 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2875 server->stat.conn_attempts++;
2877 /* Start SILC Key Exchange protocol */
2878 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2879 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2880 server->public_key, server->private_key,
2883 server->stat.conn_failures++;
2884 silc_server_disconnect_remote(server, packet_stream,
2885 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2886 silc_server_free_sock_user_data(server, packet_stream, NULL);
2889 silc_ske_set_callbacks(ske, silc_server_verify_key,
2890 silc_server_accept_completed, packet_stream);
2892 /* Start key exchange protocol */
2893 params.version = silc_version_string;
2894 params.timeout_secs = server->config->key_exchange_timeout;
2895 entry->op = silc_ske_responder(ske, packet_stream, ¶ms);
2899 /********************************** Rekey ***********************************/
2901 /* Initiator rekey completion callback */
2903 static void silc_server_rekey_completion(SilcSKE ske,
2904 SilcSKEStatus status,
2905 const SilcSKESecurityProperties prop,
2906 const SilcSKEKeyMaterial keymat,
2907 SilcSKERekeyMaterial rekey,
2910 SilcPacketStream sock = context;
2911 SilcIDListData idata = silc_packet_get_context(sock);
2912 SilcServer server = idata->sconn->server;
2914 idata->sconn->op = NULL;
2915 if (status != SILC_SKE_STATUS_OK) {
2916 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2917 idata->sconn->remote_host));
2921 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2922 idata->sconn->remote_host, idata->sconn->remote_port,
2923 SILC_CONNTYPE_STRING(idata->conn_type)));
2925 /* Save rekey data for next rekey */
2926 idata->rekey = rekey;
2928 /* Register new rekey timeout */
2929 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2930 sock, idata->sconn->rekey_timeout, 0);
2933 /* Helper to stop future rekeys on a link. */
2934 void silc_server_stop_rekey(SilcServer server, SilcClientEntry client)
2936 if (!client->connection)
2939 SILC_LOG_DEBUG(("Stopping rekey for client %p", client));
2941 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
2942 client->connection);
2945 /* Rekey callback. Start rekey as initiator */
2947 SILC_TASK_CALLBACK(silc_server_do_rekey)
2949 SilcServer server = app_context;
2950 SilcPacketStream sock = context;
2951 SilcIDListData idata = silc_packet_get_context(sock);
2954 SILC_LOG_DEBUG(("Perform rekey, sock %p", sock));
2956 /* Do not execute rekey with disabled connections */
2957 if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey)
2960 /* If another protocol is active do not start rekey */
2961 if (idata->sconn->op) {
2962 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2963 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2968 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2969 idata->sconn->remote_host, idata->sconn->remote_port,
2970 SILC_CONNTYPE_STRING(idata->conn_type)));
2973 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
2974 server->public_key, NULL, sock);
2978 /* Set SKE callbacks */
2979 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2982 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2985 /* Responder rekey completion callback */
2988 silc_server_rekey_resp_completion(SilcSKE ske,
2989 SilcSKEStatus status,
2990 const SilcSKESecurityProperties prop,
2991 const SilcSKEKeyMaterial keymat,
2992 SilcSKERekeyMaterial rekey,
2995 SilcPacketStream sock = context;
2996 SilcIDListData idata = silc_packet_get_context(sock);
2998 idata->sconn->op = NULL;
2999 if (status != SILC_SKE_STATUS_OK) {
3000 SILC_LOG_ERROR(("Error during rekey protocol with %s",
3001 idata->sconn->remote_host));
3005 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
3006 idata->sconn->remote_host, idata->sconn->remote_port,
3007 SILC_CONNTYPE_STRING(idata->conn_type)));
3009 /* Save rekey data for next rekey */
3010 idata->rekey = rekey;
3013 /* Start rekey as responder */
3015 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
3018 SilcIDListData idata = silc_packet_get_context(sock);
3021 if (!idata->rekey) {
3022 silc_packet_free(packet);
3025 if (idata->conn_type == SILC_CONN_UNKNOWN) {
3026 silc_packet_free(packet);
3030 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p",
3031 idata->sconn->remote_host, idata->sconn->remote_port,
3032 SILC_CONNTYPE_STRING(idata->conn_type), sock));
3035 ske = silc_ske_alloc(server->rng, server->schedule, NULL,
3036 server->public_key, NULL, sock);
3038 silc_packet_free(packet);
3042 /* Set SKE callbacks */
3043 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
3046 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
3051 /****************************** Disconnection *******************************/
3053 /* Destroys packet stream. */
3055 SILC_TASK_CALLBACK(silc_server_close_connection_final)
3057 silc_packet_stream_unref(context);
3060 /* Closes connection to socket connection */
3062 void silc_server_close_connection(SilcServer server,
3063 SilcPacketStream sock)
3065 SilcIDListData idata = silc_packet_get_context(sock);
3067 const char *hostname;
3070 if (!silc_packet_stream_is_valid(sock))
3073 memset(tmp, 0, sizeof(tmp));
3074 // silc_socket_get_error(sock, tmp, sizeof(tmp));
3075 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3076 NULL, &hostname, NULL, &port);
3077 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
3078 idata ? SILC_CONNTYPE_STRING(idata->conn_type) : "",
3079 tmp[0] ? tmp : ""));
3081 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
3083 if (idata && idata->sconn) {
3084 silc_server_connection_free(idata->sconn);
3085 idata->sconn = NULL;
3088 /* Take a reference and then destroy the stream. The last reference
3089 is released later in a timeout callback. */
3090 silc_packet_stream_ref(sock);
3091 silc_packet_stream_destroy(sock);
3093 /* Close connection with timeout */
3094 server->stat.conn_num--;
3095 silc_schedule_task_del_by_all(server->schedule, 0,
3096 silc_server_close_connection_final, sock);
3097 silc_schedule_task_add_timeout(server->schedule,
3098 silc_server_close_connection_final,
3102 /* Sends disconnect message to remote connection and disconnects the
3105 void silc_server_disconnect_remote(SilcServer server,
3106 SilcPacketStream sock,
3107 SilcStatus status, ...)
3109 unsigned char buf[512];
3116 SILC_LOG_DEBUG(("Disconnecting remote host, sock %p, status %d", sock,
3119 va_start(ap, status);
3120 cp = va_arg(ap, char *);
3122 silc_vsnprintf(buf, sizeof(buf), cp, ap);
3125 /* Send SILC_PACKET_DISCONNECT */
3126 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
3127 SILC_STR_UI_CHAR(status),
3128 SILC_STR_UI8_STRING(cp ? buf : NULL),
3131 /* Close connection */
3132 silc_server_close_connection(server, sock);
3135 /* Frees client data and notifies about client's signoff. */
3137 void silc_server_free_client_data(SilcServer server,
3138 SilcPacketStream sock,
3139 SilcClientEntry client,
3141 const char *signoff)
3143 SILC_LOG_DEBUG(("Freeing client %p data", client));
3146 /* Check if anyone is watching this nickname */
3147 if (server->server_type == SILC_ROUTER)
3148 silc_server_check_watcher_list(server, client, NULL,
3149 SILC_NOTIFY_TYPE_SIGNOFF);
3151 /* Send SIGNOFF notify to routers. */
3153 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
3154 SILC_BROADCAST(server), client->id,
3158 /* Remove client from all channels */
3160 silc_server_remove_from_channels(server, NULL, client,
3161 TRUE, (char *)signoff, TRUE, FALSE);
3163 silc_server_remove_from_channels(server, NULL, client,
3164 FALSE, NULL, FALSE, FALSE);
3166 /* Remove this client from watcher list if it is */
3167 silc_server_del_from_watcher_list(server, client);
3169 /* Remove client's public key from repository, this will free it too. */
3170 if (client->data.public_key) {
3171 silc_skr_del_public_key(server->repository, client->data.public_key,
3173 client->data.public_key = NULL;
3176 /* Update statistics */
3178 /* Local detached clients aren't counted. */
3179 if (!client->local_detached)
3180 server->stat.my_clients--;
3181 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
3182 server->stat.clients - 1));
3183 SILC_VERIFY(server->stat.clients > 0);
3184 server->stat.clients--;
3185 if (server->stat.cell_clients)
3186 server->stat.cell_clients--;
3187 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
3188 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
3189 silc_schedule_task_del_by_context(server->schedule, client);
3191 if (client->data.sconn) {
3192 silc_server_connection_free(client->data.sconn);
3193 client->data.sconn = NULL;
3196 /* We will not delete the client entry right away. We will take it
3197 into history (for WHOWAS command) for 5 minutes, unless we're
3198 shutting down server. */
3199 if (!server->server_shutdown) {
3200 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
3202 client->router = NULL;
3203 client->connection = NULL;
3204 client->data.created = silc_time();
3205 silc_dlist_del(server->expired_clients, client);
3206 silc_dlist_add(server->expired_clients, client);
3208 /* Delete directly since we're shutting down server */
3209 SILC_LOG_DEBUG(("Delete client directly"));
3210 silc_idlist_del_data(client);
3211 silc_idlist_del_client(server->local_list, client);
3215 /* Frees user_data pointer from socket connection object. This also sends
3216 appropriate notify packets to the network to inform about leaving
3219 void silc_server_free_sock_user_data(SilcServer server,
3220 SilcPacketStream sock,
3221 const char *signoff_message)
3223 SilcIDListData idata;
3230 SILC_LOG_DEBUG(("Start, sock %p", sock));
3232 idata = silc_packet_get_context(sock);
3236 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey,
3239 /* Cancel active protocols */
3241 if (idata->sconn && idata->sconn->op) {
3242 SILC_LOG_DEBUG(("Abort active protocol"));
3243 silc_async_abort(idata->sconn->op, NULL, NULL);
3244 idata->sconn->op = NULL;
3246 if (idata->conn_type == SILC_CONN_UNKNOWN &&
3247 ((SilcUnknownEntry)idata)->op) {
3248 SILC_LOG_DEBUG(("Abort active protocol"));
3249 silc_async_abort(((SilcUnknownEntry)idata)->op, NULL, NULL);
3250 ((SilcUnknownEntry)idata)->op = NULL;
3254 switch (idata->conn_type) {
3255 case SILC_CONN_CLIENT:
3257 SilcClientEntry client_entry = (SilcClientEntry)idata;
3258 silc_server_free_client_data(server, sock, client_entry, TRUE,
3260 silc_packet_set_context(sock, NULL);
3264 case SILC_CONN_SERVER:
3265 case SILC_CONN_ROUTER:
3267 SilcServerEntry user_data = (SilcServerEntry)idata;
3268 SilcServerEntry backup_router = NULL;
3270 SILC_LOG_DEBUG(("Freeing server %p data", user_data));
3273 backup_router = silc_server_backup_get(server, user_data->id);
3275 if (!server->backup_router && server->server_type == SILC_ROUTER &&
3276 backup_router == server->id_entry &&
3277 idata->conn_type != SILC_CONN_ROUTER)
3278 backup_router = NULL;
3280 if (server->server_shutdown || server->backup_noswitch)
3281 backup_router = NULL;
3283 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3284 NULL, NULL, &ip, &port);
3286 /* If this was our primary router connection then we're lost to
3287 the outside world. */
3288 if (server->router == user_data) {
3289 /* Check whether we have a backup router connection */
3290 if (!backup_router || backup_router == user_data) {
3291 if (!server->no_reconnect)
3292 silc_server_create_connections(server);
3293 server->id_entry->router = NULL;
3294 server->router = NULL;
3295 server->standalone = TRUE;
3296 server->backup_primary = FALSE;
3297 backup_router = NULL;
3299 if (server->id_entry != backup_router) {
3300 SILC_LOG_INFO(("New primary router is backup router %s",
3301 backup_router->server_name));
3302 server->id_entry->router = backup_router;
3303 server->router = backup_router;
3304 server->router_connect = time(0);
3305 server->backup_primary = TRUE;
3306 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
3308 /* Send START_USE to backup router to indicate we have switched */
3309 silc_server_backup_send_start_use(server,
3310 backup_router->connection,
3313 SILC_LOG_INFO(("We are now new primary router in this cell"));
3314 server->id_entry->router = NULL;
3315 server->router = NULL;
3316 server->standalone = TRUE;
3319 /* We stop here to take a breath */
3322 if (server->backup_router) {
3323 server->server_type = SILC_ROUTER;
3325 /* We'll need to constantly try to reconnect to the primary
3326 router so that we'll see when it comes back online. */
3327 silc_server_create_connection(server, TRUE, FALSE, ip, port,
3328 silc_server_backup_connected,
3332 /* Mark this connection as replaced */
3333 silc_server_backup_replaced_add(server, user_data->id,
3336 } else if (backup_router) {
3337 SILC_LOG_INFO(("Enabling the use of backup router %s",
3338 backup_router->server_name));
3340 /* Mark this connection as replaced */
3341 silc_server_backup_replaced_add(server, user_data->id,
3343 } else if (server->server_type == SILC_SERVER &&
3344 idata->conn_type == SILC_CONN_ROUTER) {
3345 /* Reconnect to the router (backup) */
3346 if (!server->no_reconnect)
3347 silc_server_create_connections(server);
3350 if (user_data->server_name)
3351 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
3352 ("Server %s signoff", user_data->server_name));
3354 if (!backup_router) {
3355 /* Remove all servers that are originated from this server, and
3356 remove the clients of those servers too. */
3357 silc_server_remove_servers_by_server(server, user_data, TRUE);
3360 /* Remove the clients that this server owns as they will become
3361 invalid now too. For backup router the server is actually
3362 coming from the primary router, so mark that as the owner
3364 if (server->server_type == SILC_BACKUP_ROUTER &&
3365 sock->type == SILC_CONN_SERVER)
3366 silc_server_remove_clients_by_server(server, server->router,
3370 silc_server_remove_clients_by_server(server, user_data,
3373 /* Remove channels owned by this server */
3374 if (server->server_type == SILC_SERVER)
3375 silc_server_remove_channels_by_server(server, user_data);
3377 /* Enable local server connections that may be disabled */
3378 silc_server_local_servers_toggle_enabled(server, TRUE);
3380 /* Update the client entries of this server to the new backup
3381 router. If we are the backup router we also resolve the real
3382 servers for the clients. After updating is over this also
3383 removes the clients that this server explicitly owns. */
3384 silc_server_update_clients_by_server(server, user_data,
3385 backup_router, TRUE);
3387 /* If we are router and just lost our primary router (now standlaone)
3388 we remove everything that was behind it, since we don't know
3390 if (server->server_type == SILC_ROUTER && server->standalone)
3391 /* Remove all servers that are originated from this server, and
3392 remove the clients of those servers too. */
3393 silc_server_remove_servers_by_server(server, user_data, TRUE);
3395 /* Finally remove the clients that are explicitly owned by this
3396 server. They go down with the server. */
3397 silc_server_remove_clients_by_server(server, user_data,
3400 /* Update our server cache to use the new backup router too. */
3401 silc_server_update_servers_by_server(server, user_data, backup_router);
3402 if (server->server_type == SILC_SERVER)
3403 silc_server_update_channels_by_server(server, user_data,
3406 /* Send notify about primary router going down to local operators */
3407 if (server->backup_router)
3408 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3409 SILC_NOTIFY_TYPE_NONE,
3410 ("%s switched to backup router %s "
3411 "(we are primary router now)",
3412 server->server_name, server->server_name));
3413 else if (server->router)
3414 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3415 SILC_NOTIFY_TYPE_NONE,
3416 ("%s switched to backup router %s",
3417 server->server_name,
3418 server->router->server_name));
3420 server->backup_noswitch = FALSE;
3423 silc_server_connection_free(idata->sconn);
3424 idata->sconn = NULL;
3428 if (idata->conn_type == SILC_CONN_SERVER) {
3429 server->stat.my_servers--;
3430 server->stat.servers--;
3431 SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers));
3432 } else if (idata->conn_type == SILC_CONN_ROUTER) {
3433 server->stat.my_routers--;
3434 server->stat.routers--;
3435 SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers));
3437 if (server->server_type == SILC_ROUTER)
3438 server->stat.cell_servers--;
3440 /* Free the server entry */
3441 silc_server_backup_del(server, user_data);
3442 silc_server_backup_replaced_del(server, user_data);
3443 silc_idlist_del_data(user_data);
3444 if (!silc_idlist_del_server(server->local_list, user_data))
3445 silc_idlist_del_server(server->global_list, user_data);
3447 if (backup_router && backup_router != server->id_entry) {
3448 /* Announce all of our stuff that was created about 5 minutes ago.
3449 The backup router knows all the other stuff already. */
3450 if (server->server_type == SILC_ROUTER)
3451 silc_server_announce_servers(server, FALSE, time(0) - 300,
3452 backup_router->connection);
3454 /* Announce our clients and channels to the router */
3455 silc_server_announce_clients(server, time(0) - 300,
3456 backup_router->connection);
3457 silc_server_announce_channels(server, time(0) - 300,
3458 backup_router->connection);
3461 silc_packet_set_context(sock, NULL);
3467 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3469 SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry));
3472 if (server->router_conn == idata->sconn) {
3473 if (!server->no_reconnect)
3474 silc_server_create_connections(server);
3475 server->router_conn = NULL;
3478 silc_server_connection_free(idata->sconn);
3479 idata->sconn = NULL;
3481 silc_idlist_del_data(idata);
3483 silc_packet_set_context(sock, NULL);
3489 /* Removes client from all channels it has joined. This is used when client
3490 connection is disconnected. If the client on a channel is last, the
3491 channel is removed as well. This sends the SIGNOFF notify types. */
3493 void silc_server_remove_from_channels(SilcServer server,
3494 SilcPacketStream sock,
3495 SilcClientEntry client,
3497 const char *signoff_message,
3501 SilcChannelEntry channel;
3502 SilcChannelClientEntry chl;
3503 SilcHashTableList htl;
3504 SilcBuffer clidp = NULL;
3509 if (notify && !client->id)
3512 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3513 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3516 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3521 /* Remove the client from all channels. The client is removed from
3522 the channels' user list. */
3523 silc_hash_table_list(client->channels, &htl);
3524 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3525 channel = chl->channel;
3527 /* Remove channel if this is last client leaving the channel, unless
3528 the channel is permanent. */
3529 if (server->server_type != SILC_SERVER &&
3530 silc_hash_table_count(channel->user_list) < 2) {
3531 silc_server_channel_delete(server, channel);
3535 silc_hash_table_del(client->channels, channel);
3536 silc_hash_table_del(channel->user_list, client);
3537 channel->user_count--;
3539 /* If there is no global users on the channel anymore mark the channel
3540 as local channel. Do not check if the removed client is local client. */
3541 if (server->server_type == SILC_SERVER && channel->global_users &&
3542 chl->client->router && !silc_server_channel_has_global(channel))
3543 channel->global_users = FALSE;
3545 memset(chl, 'A', sizeof(*chl));
3548 /* Update statistics */
3549 if (SILC_IS_LOCAL(client))
3550 server->stat.my_chanclients--;
3551 if (server->server_type == SILC_ROUTER) {
3552 server->stat.cell_chanclients--;
3553 server->stat.chanclients--;
3556 /* If there is not at least one local user on the channel then we don't
3557 need the channel entry anymore, we can remove it safely, unless the
3558 channel is permanent channel */
3559 if (server->server_type == SILC_SERVER &&
3560 !silc_server_channel_has_local(channel)) {
3561 /* Notify about leaving client if this channel has global users. */
3562 if (notify && channel->global_users)
3563 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3564 SILC_NOTIFY_TYPE_SIGNOFF,
3565 signoff_message ? 2 : 1,
3566 clidp->data, silc_buffer_len(clidp),
3567 signoff_message, signoff_message ?
3568 strlen(signoff_message) : 0);
3570 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3571 silc_server_channel_delete(server, channel);
3575 /* Send notify to channel about client leaving SILC and channel too */
3577 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3578 SILC_NOTIFY_TYPE_SIGNOFF,
3579 signoff_message ? 2 : 1,
3580 clidp->data, silc_buffer_len(clidp),
3581 signoff_message, signoff_message ?
3582 strlen(signoff_message) : 0);
3584 if (killed && clidp) {
3585 /* Remove the client from channel's invite list */
3586 if (channel->invite_list &&
3587 silc_hash_table_count(channel->invite_list)) {
3589 SilcArgumentPayload iargs;
3590 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3591 silc_buffer_len(clidp), 3);
3592 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3593 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3594 silc_buffer_free(ab);
3595 silc_argument_payload_free(iargs);
3599 /* Don't create keys if we are shutting down */
3600 if (server->server_shutdown)
3603 /* Re-generate channel key if needed */
3604 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3605 if (!silc_server_create_channel_key(server, channel, 0))
3608 /* Send the channel key to the channel. The key of course is not sent
3609 to the client who was removed from the channel. */
3610 silc_server_send_channel_key(server, client->connection, channel,
3611 server->server_type == SILC_ROUTER ?
3612 FALSE : !server->standalone);
3616 silc_hash_table_list_reset(&htl);
3618 silc_buffer_free(clidp);
3621 /* Removes client from one channel. This is used for example when client
3622 calls LEAVE command to remove itself from the channel. Returns TRUE
3623 if channel still exists and FALSE if the channel is removed when
3624 last client leaves the channel. If `notify' is FALSE notify messages
3627 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3628 SilcPacketStream sock,
3629 SilcChannelEntry channel,
3630 SilcClientEntry client,
3633 SilcChannelClientEntry chl;
3636 SILC_LOG_DEBUG(("Removing %s from channel %s",
3637 silc_id_render(client->id, SILC_ID_CLIENT),
3638 channel->channel_name));
3640 /* Get the entry to the channel, if this client is not on the channel
3642 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3645 /* Remove channel if this is last client leaving the channel, unless
3646 the channel is permanent. */
3647 if (server->server_type != SILC_SERVER &&
3648 silc_hash_table_count(channel->user_list) < 2) {
3649 silc_server_channel_delete(server, channel);
3653 silc_hash_table_del(client->channels, channel);
3654 silc_hash_table_del(channel->user_list, client);
3655 channel->user_count--;
3657 /* If there is no global users on the channel anymore mark the channel
3658 as local channel. Do not check if the client is local client. */
3659 if (server->server_type == SILC_SERVER && channel->global_users &&
3660 chl->client->router && !silc_server_channel_has_global(channel))
3661 channel->global_users = FALSE;
3663 memset(chl, 'O', sizeof(*chl));
3666 /* Update statistics */
3667 if (SILC_IS_LOCAL(client))
3668 server->stat.my_chanclients--;
3669 if (server->server_type == SILC_ROUTER) {
3670 server->stat.cell_chanclients--;
3671 server->stat.chanclients--;
3674 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3678 /* If there is not at least one local user on the channel then we don't
3679 need the channel entry anymore, we can remove it safely, unless the
3680 channel is permanent channel */
3681 if (server->server_type == SILC_SERVER &&
3682 !silc_server_channel_has_local(channel)) {
3683 /* Notify about leaving client if this channel has global users. */
3684 if (notify && channel->global_users)
3685 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3686 SILC_NOTIFY_TYPE_LEAVE, 1,
3687 clidp->data, silc_buffer_len(clidp));
3689 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3690 silc_server_channel_delete(server, channel);
3691 silc_buffer_free(clidp);
3695 /* Send notify to channel about client leaving the channel */
3697 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3698 SILC_NOTIFY_TYPE_LEAVE, 1,
3699 clidp->data, silc_buffer_len(clidp));
3701 silc_buffer_free(clidp);
3705 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3706 function may be used only by router. In real SILC network all channels
3707 are created by routers thus this function is never used by normal
3710 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3711 SilcServerID *router_id,
3717 SilcChannelID *channel_id;
3718 SilcChannelEntry entry;
3719 SilcCipher send_key, receive_key;
3722 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3725 cipher = SILC_DEFAULT_CIPHER;
3727 hmac = SILC_DEFAULT_HMAC;
3729 /* Allocate cipher */
3730 if (!silc_cipher_alloc(cipher, &send_key))
3732 if (!silc_cipher_alloc(cipher, &receive_key)) {
3733 silc_cipher_free(send_key);
3738 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3739 silc_cipher_free(send_key);
3740 silc_cipher_free(receive_key);
3744 channel_name = strdup(channel_name);
3746 /* Create the channel ID */
3747 if (!silc_id_create_channel_id(server, router_id, server->rng,
3749 silc_free(channel_name);
3750 silc_cipher_free(send_key);
3751 silc_cipher_free(receive_key);
3752 silc_hmac_free(newhmac);
3756 /* Create the channel */
3757 entry = silc_idlist_add_channel(server->local_list, channel_name,
3758 SILC_CHANNEL_MODE_NONE, channel_id,
3759 NULL, send_key, receive_key, newhmac);
3761 silc_free(channel_name);
3762 silc_cipher_free(send_key);
3763 silc_cipher_free(receive_key);
3764 silc_hmac_free(newhmac);
3765 silc_free(channel_id);
3769 entry->cipher = strdup(cipher);
3770 entry->hmac_name = strdup(hmac);
3772 /* Now create the actual key material */
3773 if (!silc_server_create_channel_key(server, entry,
3774 silc_cipher_get_key_len(send_key) / 8)) {
3775 silc_idlist_del_channel(server->local_list, entry);
3779 /* Notify other routers about the new channel. We send the packet
3780 to our primary route. */
3782 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3783 channel_name, entry->id,
3784 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3787 /* Distribute to backup routers */
3788 if (broadcast && server->server_type == SILC_ROUTER) {
3790 unsigned char cid[32];
3791 SilcUInt32 name_len = strlen(channel_name);
3794 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3795 packet = silc_channel_payload_encode(channel_name, name_len,
3796 cid, id_len, entry->mode);
3797 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3798 packet->data, silc_buffer_len(packet), FALSE,
3800 silc_buffer_free(packet);
3803 server->stat.my_channels++;
3804 if (server->server_type == SILC_ROUTER) {
3805 server->stat.channels++;
3806 server->stat.cell_channels++;
3807 entry->users_resolved = TRUE;
3813 /* Same as above but creates the channel with Channel ID `channel_id. */
3816 silc_server_create_new_channel_with_id(SilcServer server,
3820 SilcChannelID *channel_id,
3823 SilcChannelEntry entry;
3824 SilcCipher send_key, receive_key;
3827 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3830 cipher = SILC_DEFAULT_CIPHER;
3832 hmac = SILC_DEFAULT_HMAC;
3834 /* Allocate cipher */
3835 if (!silc_cipher_alloc(cipher, &send_key))
3837 if (!silc_cipher_alloc(cipher, &receive_key)) {
3838 silc_cipher_free(send_key);
3843 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3844 silc_cipher_free(send_key);
3845 silc_cipher_free(receive_key);
3849 channel_name = strdup(channel_name);
3851 /* Create the channel */
3852 entry = silc_idlist_add_channel(server->local_list, channel_name,
3853 SILC_CHANNEL_MODE_NONE, channel_id,
3854 NULL, send_key, receive_key, newhmac);
3856 silc_cipher_free(send_key);
3857 silc_cipher_free(receive_key);
3858 silc_hmac_free(newhmac);
3859 silc_free(channel_name);
3863 /* Now create the actual key material */
3864 if (!silc_server_create_channel_key(server, entry,
3865 silc_cipher_get_key_len(send_key) / 8)) {
3866 silc_idlist_del_channel(server->local_list, entry);
3870 /* Notify other routers about the new channel. We send the packet
3871 to our primary route. */
3873 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3874 channel_name, entry->id,
3875 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3878 /* Distribute to backup routers */
3879 if (broadcast && server->server_type == SILC_ROUTER) {
3881 unsigned char cid[32];
3882 SilcUInt32 name_len = strlen(channel_name);
3885 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3886 packet = silc_channel_payload_encode(channel_name, name_len,
3887 cid, id_len, entry->mode);
3888 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3889 packet->data, silc_buffer_len(packet), FALSE,
3891 silc_buffer_free(packet);
3894 server->stat.my_channels++;
3895 if (server->server_type == SILC_ROUTER) {
3896 server->stat.channels++;
3897 server->stat.cell_channels++;
3898 entry->users_resolved = TRUE;
3904 /* Channel's key re-key timeout callback. */
3906 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3908 SilcServer server = app_context;
3909 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3913 /* Return now if we are shutting down */
3914 if (server->server_shutdown)
3917 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3920 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3923 /* Generates new channel key. This is used to create the initial channel key
3924 but also to re-generate new key for channel. If `key_len' is provided
3925 it is the bytes of the key length. */
3927 SilcBool silc_server_create_channel_key(SilcServer server,
3928 SilcChannelEntry channel,
3932 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3935 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3936 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3940 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3942 if (!channel->send_key)
3943 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3944 channel->send_key = NULL;
3947 if (!channel->receive_key)
3948 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3949 silc_cipher_free(channel->send_key);
3950 channel->send_key = channel->receive_key = NULL;
3956 else if (channel->key_len)
3957 len = channel->key_len / 8;
3959 len = silc_cipher_get_key_len(channel->send_key) / 8;
3961 /* Create channel key */
3962 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3965 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3966 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3968 /* Remove old key if exists */
3970 memset(channel->key, 0, channel->key_len / 8);
3971 silc_free(channel->key);
3975 channel->key_len = len * 8;
3976 channel->key = silc_memdup(channel_key, len);
3977 memset(channel_key, 0, sizeof(channel_key));
3979 /* Generate HMAC key from the channel key data and set it */
3981 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3982 memset(channel->key, 0, channel->key_len / 8);
3983 silc_free(channel->key);
3984 silc_cipher_free(channel->send_key);
3985 silc_cipher_free(channel->receive_key);
3986 channel->send_key = channel->receive_key = NULL;
3989 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3990 silc_hmac_set_key(channel->hmac, hash,
3991 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3992 memset(hash, 0, sizeof(hash));
3994 if (server->server_type == SILC_ROUTER) {
3995 if (!channel->rekey)
3996 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3997 channel->rekey->channel = channel;
3998 channel->rekey->key_len = key_len;
3999 if (channel->rekey->task)
4000 silc_schedule_task_del(server->schedule, channel->rekey->task);
4002 channel->rekey->task =
4003 silc_schedule_task_add_timeout(server->schedule,
4004 silc_server_channel_key_rekey,
4005 (void *)channel->rekey,
4006 server->config->channel_rekey_secs, 0);
4012 /* Saves the channel key found in the encoded `key_payload' buffer. This
4013 function is used when we receive Channel Key Payload and also when we're
4014 processing JOIN command reply. Returns entry to the channel. */
4016 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
4017 SilcBuffer key_payload,
4018 SilcChannelEntry channel)
4020 SilcChannelKeyPayload payload = NULL;
4022 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
4026 /* Decode channel key payload */
4027 payload = silc_channel_key_payload_parse(key_payload->data,
4028 silc_buffer_len(key_payload));
4030 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
4035 /* Get the channel entry */
4038 /* Get channel ID */
4039 tmp = silc_channel_key_get_id(payload, &tmp_len);
4040 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
4045 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
4047 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
4049 if (server->server_type == SILC_ROUTER)
4050 SILC_LOG_ERROR(("Received key for non-existent channel %s",
4051 silc_id_render(&id, SILC_ID_CHANNEL)));
4057 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
4059 tmp = silc_channel_key_get_key(payload, &tmp_len);
4065 cipher = silc_channel_key_get_cipher(payload, NULL);
4071 /* Remove old key if exists */
4073 memset(channel->key, 0, channel->key_len / 8);
4074 silc_free(channel->key);
4075 silc_cipher_free(channel->send_key);
4076 silc_cipher_free(channel->receive_key);
4079 /* Create new cipher */
4080 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
4081 channel->send_key = NULL;
4085 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
4086 silc_cipher_free(channel->send_key);
4087 channel->send_key = channel->receive_key = NULL;
4092 if (channel->cipher)
4093 silc_free(channel->cipher);
4094 channel->cipher = strdup(cipher);
4097 channel->key_len = tmp_len * 8;
4098 channel->key = silc_memdup(tmp, tmp_len);
4099 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
4100 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
4102 /* Generate HMAC key from the channel key data and set it */
4104 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
4105 memset(channel->key, 0, channel->key_len / 8);
4106 silc_free(channel->key);
4107 silc_cipher_free(channel->send_key);
4108 silc_cipher_free(channel->receive_key);
4109 channel->send_key = channel->receive_key = NULL;
4112 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
4113 silc_hmac_set_key(channel->hmac, hash,
4114 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4116 memset(hash, 0, sizeof(hash));
4117 memset(tmp, 0, tmp_len);
4119 if (server->server_type == SILC_ROUTER) {
4120 if (!channel->rekey)
4121 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
4122 channel->rekey->channel = channel;
4123 if (channel->rekey->task)
4124 silc_schedule_task_del(server->schedule, channel->rekey->task);
4126 channel->rekey->task =
4127 silc_schedule_task_add_timeout(server->schedule,
4128 silc_server_channel_key_rekey,
4129 (void *)channel->rekey,
4130 server->config->channel_rekey_secs, 0);
4135 silc_channel_key_payload_free(payload);
4140 /* Returns assembled of all servers in the given ID list. The packet's
4141 form is dictated by the New ID payload. */
4143 static void silc_server_announce_get_servers(SilcServer server,
4144 SilcServerEntry remote,
4146 SilcBuffer *servers,
4147 unsigned long creation_time)
4150 SilcIDCacheEntry id_cache;
4151 SilcServerEntry entry;
4155 /* Go through all clients in the list */
4156 if (silc_idcache_get_all(id_list->servers, &list)) {
4157 silc_list_start(list);
4158 while ((id_cache = silc_list_get(list))) {
4159 entry = (SilcServerEntry)id_cache->context;
4161 /* Do not announce the one we've sending our announcements and
4162 do not announce ourself. Also check the creation time if it's
4164 if ((entry == remote) || (entry == server->id_entry) ||
4165 (creation_time && entry->data.created < creation_time))
4168 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
4170 tmp = silc_buffer_realloc(*servers,
4172 silc_buffer_truelen((*servers)) +
4173 silc_buffer_len(idp) :
4174 silc_buffer_len(idp)));
4178 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
4179 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
4180 silc_buffer_pull(*servers, silc_buffer_len(idp));
4181 silc_buffer_free(idp);
4187 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
4193 p = silc_notify_payload_encode(notify, argc, ap);
4199 /* This function is used by router to announce existing servers to our
4200 primary router when we've connected to it. If `creation_time' is non-zero
4201 then only the servers that has been created after the `creation_time'
4202 will be announced. */
4204 void silc_server_announce_servers(SilcServer server, SilcBool global,
4205 unsigned long creation_time,
4206 SilcPacketStream remote)
4208 SilcBuffer servers = NULL;
4210 SILC_LOG_DEBUG(("Announcing servers"));
4212 /* Get servers in local list */
4213 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4214 server->local_list, &servers,
4218 /* Get servers in global list */
4219 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
4220 server->global_list, &servers,
4224 silc_buffer_push(servers, servers->data - servers->head);
4225 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
4227 /* Send the packet */
4228 silc_server_packet_send(server, remote,
4229 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4230 servers->data, silc_buffer_len(servers));
4232 silc_buffer_free(servers);
4236 /* Returns assembled packet of all clients in the given ID list. The
4237 packet's form is dictated by the New ID Payload. */
4239 static void silc_server_announce_get_clients(SilcServer server,
4241 SilcBuffer *clients,
4243 unsigned long creation_time)
4246 SilcIDCacheEntry id_cache;
4247 SilcClientEntry client;
4250 unsigned char mode[4];
4253 /* Go through all clients in the list */
4254 if (silc_idcache_get_all(id_list->clients, &list)) {
4255 silc_list_start(list);
4256 while ((id_cache = silc_list_get(list))) {
4257 client = (SilcClientEntry)id_cache->context;
4259 if (creation_time && client->data.created < creation_time)
4261 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4263 if (!client->connection && !client->router)
4266 SILC_LOG_DEBUG(("Announce Client ID %s",
4267 silc_id_render(client->id, SILC_ID_CLIENT)));
4269 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4273 tmp2 = silc_buffer_realloc(*clients,
4275 silc_buffer_truelen((*clients)) +
4276 silc_buffer_len(idp) :
4277 silc_buffer_len(idp)));
4281 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
4282 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
4283 silc_buffer_pull(*clients, silc_buffer_len(idp));
4285 SILC_PUT32_MSB(client->mode, mode);
4287 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
4288 2, idp->data, silc_buffer_len(idp),
4290 tmp2 = silc_buffer_realloc(*umodes,
4292 silc_buffer_truelen((*umodes)) +
4293 silc_buffer_len(tmp) :
4294 silc_buffer_len(tmp)));
4298 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
4299 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
4300 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
4301 silc_buffer_free(tmp);
4303 silc_buffer_free(idp);
4308 /* This function is used to announce our existing clients to our router
4309 when we've connected to it. If `creation_time' is non-zero then only
4310 the clients that has been created after the `creation_time' will be
4313 void silc_server_announce_clients(SilcServer server,
4314 unsigned long creation_time,
4315 SilcPacketStream remote)
4317 SilcBuffer clients = NULL;
4318 SilcBuffer umodes = NULL;
4320 SILC_LOG_DEBUG(("Announcing clients"));
4322 /* Get clients in local list */
4323 silc_server_announce_get_clients(server, server->local_list,
4324 &clients, &umodes, creation_time);
4326 /* As router we announce our global list as well */
4327 if (server->server_type == SILC_ROUTER)
4328 silc_server_announce_get_clients(server, server->global_list,
4329 &clients, &umodes, creation_time);
4332 silc_buffer_push(clients, clients->data - clients->head);
4333 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
4335 /* Send the packet */
4336 silc_server_packet_send(server, remote,
4337 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
4338 clients->data, silc_buffer_len(clients));
4340 silc_buffer_free(clients);
4344 silc_buffer_push(umodes, umodes->data - umodes->head);
4345 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
4347 /* Send the packet */
4348 silc_server_packet_send(server, remote,
4349 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4350 umodes->data, silc_buffer_len(umodes));
4352 silc_buffer_free(umodes);
4356 /* Returns channel's topic for announcing it */
4358 void silc_server_announce_get_channel_topic(SilcServer server,
4359 SilcChannelEntry channel,
4364 if (channel->topic) {
4365 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4366 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
4368 silc_buffer_len(chidp),
4370 strlen(channel->topic));
4371 silc_buffer_free(chidp);
4375 /* Returns channel's invite and ban lists */
4377 void silc_server_announce_get_inviteban(SilcServer server,
4378 SilcChannelEntry channel,
4382 SilcBuffer list, idp, idp2, tmp2;
4385 SilcHashTableList htl;
4386 const unsigned char a[1] = { 0x03 };
4388 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
4390 /* Encode invite list */
4391 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
4392 list = silc_buffer_alloc_size(2);
4393 type = silc_hash_table_count(channel->invite_list);
4394 SILC_PUT16_MSB(type, list->data);
4395 silc_hash_table_list(channel->invite_list, &htl);
4396 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4397 list = silc_argument_payload_encode_one(list, tmp2->data,
4398 silc_buffer_len(tmp2),
4399 SILC_PTR_TO_32(ptype));
4400 silc_hash_table_list_reset(&htl);
4402 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4404 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4405 idp->data, silc_buffer_len(idp),
4406 channel->channel_name,
4407 strlen(channel->channel_name),
4408 idp2->data, silc_buffer_len(idp2),
4410 list->data, silc_buffer_len(list));
4411 silc_buffer_free(idp2);
4412 silc_buffer_free(list);
4415 /* Encode ban list */
4416 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4417 list = silc_buffer_alloc_size(2);
4418 type = silc_hash_table_count(channel->ban_list);
4419 SILC_PUT16_MSB(type, list->data);
4420 silc_hash_table_list(channel->ban_list, &htl);
4421 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
4422 list = silc_argument_payload_encode_one(list, tmp2->data,
4423 silc_buffer_len(tmp2),
4424 SILC_PTR_TO_32(ptype));
4425 silc_hash_table_list_reset(&htl);
4428 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4429 idp->data, silc_buffer_len(idp),
4431 list->data, silc_buffer_len(list));
4432 silc_buffer_free(list);
4435 silc_buffer_free(idp);
4438 /* Returns assembled packets for channel users of the `channel'. */
4440 void silc_server_announce_get_channel_users(SilcServer server,
4441 SilcChannelEntry channel,
4442 SilcBuffer *channel_modes,
4443 SilcBuffer *channel_users,
4444 SilcBuffer *channel_users_modes)
4446 SilcChannelClientEntry chl;
4447 SilcHashTableList htl;
4448 SilcBuffer chidp, clidp, csidp;
4449 SilcBuffer tmp, fkey = NULL, chpklist;
4451 unsigned char mode[4], ulimit[4];
4455 SILC_LOG_DEBUG(("Start"));
4457 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4458 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4459 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4462 SILC_PUT32_MSB(channel->mode, mode);
4463 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4464 SILC_PUT32_MSB(channel->user_limit, ulimit);
4465 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4466 if (channel->founder_key)
4467 fkey = silc_public_key_payload_encode(channel->founder_key);
4469 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4471 silc_buffer_len(csidp),
4474 hmac, hmac ? strlen(hmac) : 0,
4475 channel->passphrase,
4476 channel->passphrase ?
4477 strlen(channel->passphrase) : 0,
4478 fkey ? fkey->data : NULL,
4479 fkey ? silc_buffer_len(fkey) : 0,
4480 chpklist ? chpklist->data : NULL,
4482 silc_buffer_len(chpklist) : 0,
4484 SILC_CHANNEL_MODE_ULIMIT ?
4487 SILC_CHANNEL_MODE_ULIMIT ?
4488 sizeof(ulimit) : 0));
4489 len = silc_buffer_len(tmp);
4491 silc_buffer_realloc(*channel_modes,
4493 silc_buffer_truelen((*channel_modes)) + len : len));
4496 *channel_modes = tmp2;
4497 silc_buffer_pull_tail(*channel_modes,
4498 ((*channel_modes)->end -
4499 (*channel_modes)->data));
4500 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4501 silc_buffer_pull(*channel_modes, len);
4502 silc_buffer_free(tmp);
4503 silc_buffer_free(fkey);
4506 /* Now find all users on the channel */
4507 silc_hash_table_list(channel->user_list, &htl);
4508 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4509 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4511 SILC_LOG_DEBUG(("JOIN Client %s", silc_id_render(chl->client->id,
4515 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4517 silc_buffer_len(clidp),
4519 silc_buffer_len(chidp));
4520 len = silc_buffer_len(tmp);
4522 silc_buffer_realloc(*channel_users,
4524 silc_buffer_truelen((*channel_users)) + len : len));
4527 *channel_users = tmp2;
4528 silc_buffer_pull_tail(*channel_users,
4529 ((*channel_users)->end -
4530 (*channel_users)->data));
4532 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4533 silc_buffer_pull(*channel_users, len);
4534 silc_buffer_free(tmp);
4536 /* CUMODE notify for mode change on the channel */
4537 SILC_PUT32_MSB(chl->mode, mode);
4538 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4539 fkey = silc_public_key_payload_encode(channel->founder_key);
4540 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4542 silc_buffer_len(csidp),
4545 silc_buffer_len(clidp),
4546 fkey ? fkey->data : NULL,
4547 fkey ? silc_buffer_len(fkey) : 0);
4548 len = silc_buffer_len(tmp);
4550 silc_buffer_realloc(*channel_users_modes,
4551 (*channel_users_modes ?
4552 silc_buffer_truelen((*channel_users_modes)) +
4556 *channel_users_modes = tmp2;
4557 silc_buffer_pull_tail(*channel_users_modes,
4558 ((*channel_users_modes)->end -
4559 (*channel_users_modes)->data));
4561 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4562 silc_buffer_pull(*channel_users_modes, len);
4563 silc_buffer_free(tmp);
4564 silc_buffer_free(fkey);
4566 silc_buffer_free(clidp);
4568 silc_hash_table_list_reset(&htl);
4569 silc_buffer_free(chidp);
4570 silc_buffer_free(csidp);
4573 /* Returns assembled packets for all channels and users on those channels
4574 from the given ID List. The packets are in the form dictated by the
4575 New Channel and New Channel User payloads. */
4577 void silc_server_announce_get_channels(SilcServer server,
4579 SilcBuffer *channels,
4580 SilcBuffer **channel_modes,
4581 SilcBuffer *channel_users,
4582 SilcBuffer **channel_users_modes,
4583 SilcUInt32 *channel_users_modes_c,
4584 SilcBuffer **channel_topics,
4585 SilcBuffer **channel_invites,
4586 SilcBuffer **channel_bans,
4587 SilcChannelID ***channel_ids,
4588 unsigned long creation_time)
4591 SilcIDCacheEntry id_cache;
4592 SilcChannelEntry channel;
4593 unsigned char cid[32];
4595 SilcUInt16 name_len;
4597 int i = *channel_users_modes_c;
4601 SILC_LOG_DEBUG(("Start"));
4603 /* Go through all channels in the list */
4604 if (silc_idcache_get_all(id_list->channels, &list)) {
4605 silc_list_start(list);
4606 while ((id_cache = silc_list_get(list))) {
4607 channel = (SilcChannelEntry)id_cache->context;
4609 if (creation_time && channel->created < creation_time)
4614 SILC_LOG_DEBUG(("Announce Channel ID %s",
4615 silc_id_render(channel->id, SILC_ID_CHANNEL)));
4617 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4618 name_len = strlen(channel->channel_name);
4621 len = 4 + name_len + id_len + 4;
4623 silc_buffer_realloc(*channels,
4625 silc_buffer_truelen((*channels)) +
4631 silc_buffer_pull_tail(*channels,
4632 ((*channels)->end - (*channels)->data));
4633 silc_buffer_format(*channels,
4634 SILC_STR_UI_SHORT(name_len),
4635 SILC_STR_UI_XNSTRING(channel->channel_name,
4637 SILC_STR_UI_SHORT(id_len),
4638 SILC_STR_UI_XNSTRING(cid, id_len),
4639 SILC_STR_UI_INT(channel->mode),
4641 silc_buffer_pull(*channels, len);
4644 if (creation_time && channel->updated < creation_time)
4650 /* Channel user modes */
4651 tmp = silc_realloc(*channel_users_modes,
4652 sizeof(**channel_users_modes) * (i + 1));
4655 *channel_users_modes = tmp;
4656 (*channel_users_modes)[i] = NULL;
4657 tmp = silc_realloc(*channel_modes,
4658 sizeof(**channel_modes) * (i + 1));
4661 *channel_modes = tmp;
4662 (*channel_modes)[i] = NULL;
4663 tmp = silc_realloc(*channel_ids,
4664 sizeof(**channel_ids) * (i + 1));
4668 (*channel_ids)[i] = NULL;
4669 silc_server_announce_get_channel_users(server, channel,
4670 &(*channel_modes)[i],
4672 &(*channel_users_modes)[i]);
4673 (*channel_ids)[i] = channel->id;
4675 /* Channel's topic */
4676 tmp = silc_realloc(*channel_topics,
4677 sizeof(**channel_topics) * (i + 1));
4680 *channel_topics = tmp;
4681 (*channel_topics)[i] = NULL;
4682 silc_server_announce_get_channel_topic(server, channel,
4683 &(*channel_topics)[i]);
4685 /* Channel's invite and ban list */
4686 tmp = silc_realloc(*channel_invites,
4687 sizeof(**channel_invites) * (i + 1));
4690 *channel_invites = tmp;
4691 (*channel_invites)[i] = NULL;
4692 tmp = silc_realloc(*channel_bans,
4693 sizeof(**channel_bans) * (i + 1));
4696 *channel_bans = tmp;
4697 (*channel_bans)[i] = NULL;
4698 silc_server_announce_get_inviteban(server, channel,
4699 &(*channel_invites)[i],
4700 &(*channel_bans)[i]);
4702 (*channel_users_modes_c)++;
4710 /* This function is used to announce our existing channels to our router
4711 when we've connected to it. This also announces the users on the
4712 channels to the router. If the `creation_time' is non-zero only the
4713 channels that was created after the `creation_time' are announced.
4714 Note that the channel users are still announced even if the `creation_time'
4717 void silc_server_announce_channels(SilcServer server,
4718 unsigned long creation_time,
4719 SilcPacketStream remote)
4721 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4722 SilcBuffer *channel_users_modes = NULL;
4723 SilcBuffer *channel_topics = NULL;
4724 SilcBuffer *channel_invites = NULL;
4725 SilcBuffer *channel_bans = NULL;
4726 SilcUInt32 channel_users_modes_c = 0;
4727 SilcChannelID **channel_ids = NULL;
4729 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4731 /* Get channels and channel users in local list */
4732 silc_server_announce_get_channels(server, server->local_list,
4733 &channels, &channel_modes,
4735 &channel_users_modes,
4736 &channel_users_modes_c,
4740 &channel_ids, creation_time);
4742 /* Get channels and channel users in global list */
4743 if (server->server_type != SILC_SERVER)
4744 silc_server_announce_get_channels(server, server->global_list,
4745 &channels, &channel_modes,
4747 &channel_users_modes,
4748 &channel_users_modes_c,
4752 &channel_ids, creation_time);
4755 silc_buffer_push(channels, channels->data - channels->head);
4756 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4758 /* Send the packet */
4759 silc_server_packet_send(server, remote,
4760 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4761 channels->data, silc_buffer_len(channels));
4763 silc_buffer_free(channels);
4766 if (channel_users) {
4767 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4768 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4769 silc_buffer_len(channel_users));
4771 /* Send the packet */
4772 silc_server_packet_send(server, remote,
4773 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4774 channel_users->data, silc_buffer_len(channel_users));
4776 silc_buffer_free(channel_users);
4779 if (channel_modes) {
4782 for (i = 0; i < channel_users_modes_c; i++) {
4783 if (!channel_modes[i])
4785 silc_buffer_push(channel_modes[i],
4786 channel_modes[i]->data -
4787 channel_modes[i]->head);
4788 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4789 silc_buffer_len(channel_modes[i]));
4790 silc_server_packet_send_dest(server, remote,
4791 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4792 channel_ids[i], SILC_ID_CHANNEL,
4793 channel_modes[i]->data,
4794 silc_buffer_len(channel_modes[i]));
4795 silc_buffer_free(channel_modes[i]);
4797 silc_free(channel_modes);
4800 if (channel_users_modes) {
4803 for (i = 0; i < channel_users_modes_c; i++) {
4804 if (!channel_users_modes[i])
4806 silc_buffer_push(channel_users_modes[i],
4807 channel_users_modes[i]->data -
4808 channel_users_modes[i]->head);
4809 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4810 silc_buffer_len(channel_users_modes[i]));
4811 silc_server_packet_send_dest(server, remote,
4812 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4813 channel_ids[i], SILC_ID_CHANNEL,
4814 channel_users_modes[i]->data,
4815 silc_buffer_len(channel_users_modes[i]));
4816 silc_buffer_free(channel_users_modes[i]);
4818 silc_free(channel_users_modes);
4821 if (channel_topics) {
4824 for (i = 0; i < channel_users_modes_c; i++) {
4825 if (!channel_topics[i])
4828 silc_buffer_push(channel_topics[i],
4829 channel_topics[i]->data -
4830 channel_topics[i]->head);
4831 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4832 silc_buffer_len(channel_topics[i]));
4833 silc_server_packet_send_dest(server, remote,
4834 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4835 channel_ids[i], SILC_ID_CHANNEL,
4836 channel_topics[i]->data,
4837 silc_buffer_len(channel_topics[i]));
4838 silc_buffer_free(channel_topics[i]);
4840 silc_free(channel_topics);
4843 if (channel_invites) {
4846 for (i = 0; i < channel_users_modes_c; i++) {
4847 if (!channel_invites[i])
4850 silc_buffer_push(channel_invites[i],
4851 channel_invites[i]->data -
4852 channel_invites[i]->head);
4853 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4854 silc_buffer_len(channel_invites[i]));
4855 silc_server_packet_send_dest(server, remote,
4856 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4857 channel_ids[i], SILC_ID_CHANNEL,
4858 channel_invites[i]->data,
4859 silc_buffer_len(channel_invites[i]));
4860 silc_buffer_free(channel_invites[i]);
4862 silc_free(channel_invites);
4868 for (i = 0; i < channel_users_modes_c; i++) {
4869 if (!channel_bans[i])
4872 silc_buffer_push(channel_bans[i],
4873 channel_bans[i]->data -
4874 channel_bans[i]->head);
4875 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4876 silc_buffer_len(channel_bans[i]));
4877 silc_server_packet_send_dest(server, remote,
4878 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4879 channel_ids[i], SILC_ID_CHANNEL,
4880 channel_bans[i]->data,
4881 silc_buffer_len(channel_bans[i]));
4882 silc_buffer_free(channel_bans[i]);
4884 silc_free(channel_bans);
4887 silc_free(channel_ids);
4890 /* Announces WATCH list. */
4892 void silc_server_announce_watches(SilcServer server,
4893 SilcPacketStream remote)
4895 SilcHashTableList htl;
4896 SilcBuffer buffer, idp, args, pkp;
4897 SilcClientEntry client;
4900 SILC_LOG_DEBUG(("Announcing watch list"));
4902 /* XXX because way we save the nicks (hash) we cannot announce them. */
4904 /* XXX we should send all public keys in one command if client is
4905 watching more than one key */
4906 silc_hash_table_list(server->watcher_list_pk, &htl);
4907 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4908 if (!client || !client->id)
4911 server->stat.commands_sent++;
4913 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4914 args = silc_buffer_alloc_size(2);
4915 silc_buffer_format(args,
4916 SILC_STR_UI_SHORT(1),
4918 pkp = silc_public_key_payload_encode(key);
4919 args = silc_argument_payload_encode_one(args, pkp->data,
4920 silc_buffer_len(pkp), 0x00);
4921 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4922 ++server->cmd_ident, 2,
4923 1, idp->data, silc_buffer_len(idp),
4925 silc_buffer_len(args));
4928 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4929 buffer->data, silc_buffer_len(buffer));
4931 silc_buffer_free(pkp);
4932 silc_buffer_free(args);
4933 silc_buffer_free(idp);
4934 silc_buffer_free(buffer);
4936 silc_hash_table_list_reset(&htl);
4939 /* Assembles user list and users mode list from the `channel'. */
4941 SilcBool silc_server_get_users_on_channel(SilcServer server,
4942 SilcChannelEntry channel,
4943 SilcBuffer *user_list,
4944 SilcBuffer *mode_list,
4945 SilcUInt32 *user_count)
4947 SilcChannelClientEntry chl;
4948 SilcHashTableList htl;
4949 SilcBuffer client_id_list;
4950 SilcBuffer client_mode_list;
4952 SilcUInt32 list_count = 0, len = 0;
4954 if (!silc_hash_table_count(channel->user_list))
4957 silc_hash_table_list(channel->user_list, &htl);
4958 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4959 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4960 silc_hash_table_list_reset(&htl);
4962 client_id_list = silc_buffer_alloc(len);
4964 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4965 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4966 silc_buffer_pull_tail(client_mode_list,
4967 silc_buffer_truelen(client_mode_list));
4969 silc_hash_table_list(channel->user_list, &htl);
4970 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4972 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4973 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4974 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4975 silc_buffer_free(idp);
4977 /* Client's mode on channel */
4978 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4979 silc_buffer_pull(client_mode_list, 4);
4983 silc_hash_table_list_reset(&htl);
4984 silc_buffer_push(client_id_list,
4985 client_id_list->data - client_id_list->head);
4986 silc_buffer_push(client_mode_list,
4987 client_mode_list->data - client_mode_list->head);
4989 *user_list = client_id_list;
4990 *mode_list = client_mode_list;
4991 *user_count = list_count;
4995 /* Saves users and their modes to the `channel'. */
4997 void silc_server_save_users_on_channel(SilcServer server,
4998 SilcPacketStream sock,
4999 SilcChannelEntry channel,
5000 SilcClientID *noadd,
5001 SilcBuffer user_list,
5002 SilcBuffer mode_list,
5003 SilcUInt32 user_count)
5009 SilcClientEntry client;
5010 SilcIDCacheEntry cache;
5011 SilcChannelClientEntry chl;
5013 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
5014 channel->channel_name));
5016 for (i = 0; i < user_count; i++) {
5018 SILC_GET16_MSB(idp_len, user_list->data + 2);
5020 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
5022 silc_buffer_pull(user_list, idp_len);
5025 SILC_GET32_MSB(mode, mode_list->data);
5026 silc_buffer_pull(mode_list, 4);
5028 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
5033 /* Check if we have this client cached already. */
5034 client = silc_idlist_find_client_by_id(server->local_list,
5036 server->server_type, &cache);
5038 client = silc_idlist_find_client_by_id(server->global_list,
5040 server->server_type, &cache);
5042 /* If router did not find such Client ID in its lists then this must
5043 be bogus client or some router in the net is buggy. */
5044 if (server->server_type != SILC_SERVER)
5047 /* We don't have that client anywhere, add it. The client is added
5048 to global list since server didn't have it in the lists so it must be
5050 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
5051 silc_id_dup(&id.u.client_id,
5053 silc_packet_get_context(sock),
5056 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
5060 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
5062 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
5063 server->stat.clients + 1));
5064 server->stat.clients++;
5067 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
5068 SILC_LOG_ERROR(("Attempting to add unregistered client to channel "
5069 "%s", channel->channel_name));
5073 if (!silc_server_client_on_channel(client, channel, &chl)) {
5074 /* Client was not on the channel, add it. */
5075 chl = silc_calloc(1, sizeof(*chl));
5076 chl->client = client;
5078 chl->channel = channel;
5079 silc_hash_table_add(channel->user_list, chl->client, chl);
5080 silc_hash_table_add(client->channels, chl->channel, chl);
5081 channel->user_count++;
5089 /* Saves channels and channels user modes to the `client'. Removes
5090 the client from those channels that are not sent in the list but
5093 void silc_server_save_user_channels(SilcServer server,
5094 SilcPacketStream sock,
5095 SilcClientEntry client,
5096 SilcBuffer channels,
5097 SilcBuffer channels_user_modes)
5100 SilcUInt32 *chumodes;
5101 SilcChannelPayload entry;
5102 SilcChannelEntry channel;
5103 SilcChannelID channel_id;
5104 SilcChannelClientEntry chl;
5105 SilcHashTable ht = NULL;
5106 SilcHashTableList htl;
5110 if (!channels || !channels_user_modes ||
5111 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
5114 ch = silc_channel_payload_parse_list(channels->data,
5115 silc_buffer_len(channels));
5116 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
5118 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
5119 NULL, NULL, NULL, TRUE);
5120 silc_dlist_start(ch);
5121 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
5122 /* Check if we have this channel, and add it if we don't have it.
5123 Also add the client on the channel unless it is there already. */
5124 if (!silc_channel_get_id_parse(entry, &channel_id))
5126 channel = silc_idlist_find_channel_by_id(server->local_list,
5129 channel = silc_idlist_find_channel_by_id(server->global_list,
5132 if (server->server_type != SILC_SERVER) {
5137 /* We don't have that channel anywhere, add it. */
5138 name = silc_channel_get_name(entry, NULL);
5139 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
5140 silc_id_dup(&channel_id,
5142 server->router, NULL, NULL, 0);
5149 channel->mode = silc_channel_get_mode(entry);
5151 /* Add the client on the channel */
5152 if (!silc_server_client_on_channel(client, channel, &chl)) {
5153 chl = silc_calloc(1, sizeof(*chl));
5154 chl->client = client;
5155 chl->mode = chumodes[i++];
5156 chl->channel = channel;
5157 silc_hash_table_add(channel->user_list, chl->client, chl);
5158 silc_hash_table_add(client->channels, chl->channel, chl);
5159 channel->user_count++;
5162 chl->mode = chumodes[i++];
5165 silc_hash_table_add(ht, channel, channel);
5167 silc_channel_payload_list_free(ch);
5168 silc_free(chumodes);
5172 /* Go through the list again and remove client from channels that
5173 are no part of the list. */
5175 silc_hash_table_list(client->channels, &htl);
5176 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5177 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
5178 silc_hash_table_del(chl->channel->user_list, chl->client);
5179 silc_hash_table_del(chl->client->channels, chl->channel);
5183 silc_hash_table_list_reset(&htl);
5184 silc_hash_table_free(ht);
5186 silc_hash_table_list(client->channels, &htl);
5187 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5188 silc_hash_table_del(chl->channel->user_list, chl->client);
5189 silc_hash_table_del(chl->client->channels, chl->channel);
5192 silc_hash_table_list_reset(&htl);
5196 /* Lookups route to the client indicated by the `id_data'. The connection
5197 object and internal data object is returned. Returns NULL if route
5198 could not be found to the client. If the `client_id' is specified then
5199 it is used and the `id_data' is ignored. */
5202 silc_server_get_client_route(SilcServer server,
5203 unsigned char *id_data,
5205 SilcClientID *client_id,
5206 SilcIDListData *idata,
5207 SilcClientEntry *client_entry)
5209 SilcClientID *id, clid;
5210 SilcClientEntry client;
5212 SILC_LOG_DEBUG(("Start"));
5215 *client_entry = NULL;
5217 /* Decode destination Client ID */
5219 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
5221 id = silc_id_dup(&clid, SILC_ID_CLIENT);
5223 id = silc_id_dup(client_id, SILC_ID_CLIENT);
5226 /* If the destination belongs to our server we don't have to route
5227 the packet anywhere but to send it to the local destination. */
5228 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
5232 /* If we are router and the client has router then the client is in
5233 our cell but not directly connected to us. */
5234 if (server->server_type == SILC_ROUTER && client->router) {
5235 /* We are of course in this case the client's router thus the route
5236 to the client is the server who owns the client. So, we will send
5237 the packet to that server. */
5239 *idata = (SilcIDListData)client->router;
5240 return client->router->connection;
5243 /* Seems that client really is directly connected to us */
5245 *idata = (SilcIDListData)client;
5247 *client_entry = client;
5248 return client->connection;
5251 /* Destination belongs to someone not in this server. If we are normal
5252 server our action is to send the packet to our router. */
5253 if (server->server_type != SILC_ROUTER && !server->standalone) {
5256 *idata = (SilcIDListData)server->router;
5257 return SILC_PRIMARY_ROUTE(server);
5260 /* We are router and we will perform route lookup for the destination
5261 and send the packet to fastest route. */
5262 if (server->server_type == SILC_ROUTER && !server->standalone) {
5263 /* Check first that the ID is valid */
5264 client = silc_idlist_find_client_by_id(server->global_list, id,
5267 SilcPacketStream dst_sock;
5269 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
5272 if (idata && dst_sock)
5273 *idata = silc_packet_get_context(dst_sock);
5282 /* Encodes and returns channel list of channels the `client' has joined.
5283 Secret channels are not put to the list. */
5285 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
5286 SilcClientEntry client,
5287 SilcBool get_private,
5288 SilcBool get_secret,
5289 SilcBuffer *user_mode_list)
5291 SilcBuffer buffer = NULL;
5292 SilcChannelEntry channel;
5293 SilcChannelClientEntry chl;
5294 SilcHashTableList htl;
5295 unsigned char cid[32];
5297 SilcUInt16 name_len;
5301 *user_mode_list = NULL;
5303 silc_hash_table_list(client->channels, &htl);
5304 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
5305 channel = chl->channel;
5307 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
5309 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
5312 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
5313 name_len = strlen(channel->channel_name);
5315 len = 4 + name_len + id_len + 4;
5316 buffer = silc_buffer_realloc(buffer,
5318 silc_buffer_truelen(buffer) + len : len));
5319 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
5320 silc_buffer_format(buffer,
5321 SILC_STR_UI_SHORT(name_len),
5322 SILC_STR_DATA(channel->channel_name, name_len),
5323 SILC_STR_UI_SHORT(id_len),
5324 SILC_STR_DATA(cid, id_len),
5325 SILC_STR_UI_INT(chl->channel->mode),
5327 silc_buffer_pull(buffer, len);
5329 if (user_mode_list) {
5331 silc_buffer_realloc(*user_mode_list,
5333 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
5334 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
5335 (*user_mode_list)->data));
5336 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
5337 silc_buffer_pull(*user_mode_list, 4);
5340 silc_hash_table_list_reset(&htl);
5343 silc_buffer_push(buffer, buffer->data - buffer->head);
5344 if (user_mode_list && *user_mode_list)
5345 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
5346 (*user_mode_list)->head));
5351 /* Task callback used to retrieve network statistical information from
5352 router server once in a while. */
5354 SILC_TASK_CALLBACK(silc_server_get_stats)
5356 SilcServer server = (SilcServer)context;
5357 SilcBuffer idp, packet;
5359 if (!server->standalone) {
5360 SILC_LOG_DEBUG(("Retrieving stats from router"));
5361 server->stat.commands_sent++;
5362 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
5364 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
5365 ++server->cmd_ident, 1,
5367 silc_buffer_len(idp));
5368 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5369 SILC_PACKET_COMMAND, 0, packet->data,
5370 silc_buffer_len(packet));
5371 silc_buffer_free(packet);
5372 silc_buffer_free(idp);
5376 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,