5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2005, 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /************************* Types and definitions ***************************/
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_do_rekey);
28 static void silc_server_accept_new_connection(SilcNetStatus status,
31 static void silc_server_packet_parse_type(SilcServer server,
32 SilcPacketStream sock,
34 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
38 /************************ Static utility functions **************************/
40 /* SKE public key verification callback */
43 silc_server_verify_key(SilcSKE ske,
44 SilcPublicKey public_key,
46 SilcSKEVerifyCbCompletion completion,
47 void *completion_context)
49 SilcPacketStream sock = context;
50 SilcUnknownEntry entry = silc_packet_get_context(sock);
52 SILC_LOG_DEBUG(("Verifying public key"));
54 if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
55 SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
56 entry->hostname, entry->ip, entry->port,
57 silc_pkcs_get_type(public_key)));
58 completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
63 /* We accept all keys without explicit verification */
64 completion(ske, SILC_SKE_STATUS_OK, completion_context);
68 /************************ Packet engine callbacks ***************************/
70 /* Packet engine callback to receive a packet */
72 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
73 SilcPacketStream stream,
75 void *callback_context,
78 SilcServer server = callback_context;
79 SilcIDListData idata = stream_context;
81 /* Packets we do not handle */
82 switch (packet->type) {
83 case SILC_PACKET_HEARTBEAT:
84 case SILC_PACKET_SUCCESS:
85 case SILC_PACKET_FAILURE:
86 case SILC_PACKET_REJECT:
87 case SILC_PACKET_KEY_EXCHANGE:
88 case SILC_PACKET_KEY_EXCHANGE_1:
89 case SILC_PACKET_KEY_EXCHANGE_2:
90 case SILC_PACKET_REKEY_DONE:
91 case SILC_PACKET_CONNECTION_AUTH:
96 /* Only specific packets can come without source ID present. */
97 if ((!packet->src_id ||
98 !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
99 packet->type != SILC_PACKET_NEW_CLIENT &&
100 packet->type != SILC_PACKET_NEW_SERVER &&
101 packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST &&
102 packet->type != SILC_PACKET_DISCONNECT)
105 /* NEW_CLIENT and NEW_SERVER are accepted only without source ID
106 and for unregistered connection. */
107 if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
108 packet->type == SILC_PACKET_NEW_SERVER) &&
109 (idata->status & SILC_IDLIST_STATUS_REGISTERED))
113 silc_server_packet_parse_type(server, stream, packet);
118 /* Packet engine callback to indicate end of stream */
120 static void silc_server_packet_eos(SilcPacketEngine engine,
121 SilcPacketStream stream,
122 void *callback_context,
123 void *stream_context)
125 SILC_LOG_DEBUG(("End of stream received"));
128 /* Packet engine callback to indicate error */
130 static void silc_server_packet_error(SilcPacketEngine engine,
131 SilcPacketStream stream,
132 SilcPacketError error,
133 void *callback_context,
134 void *stream_context)
139 /* Packet stream callbacks */
140 static SilcPacketCallbacks silc_server_stream_cbs =
142 silc_server_packet_receive,
143 silc_server_packet_eos,
144 silc_server_packet_error
147 /* Parses the packet type and calls what ever routines the packet type
148 requires. This is done for all incoming packets. */
150 static void silc_server_packet_parse_type(SilcServer server,
151 SilcPacketStream sock,
154 SilcPacketType type = packet->type;
155 SilcIDListData idata = silc_packet_get_context(sock);
157 SILC_LOG_DEBUG(("Received %s packet [flags %d]",
158 silc_get_packet_name(type), packet->flags));
160 /* Parse the packet type */
162 case SILC_PACKET_NOTIFY:
164 * Received notify packet. Server can receive notify packets from
165 * router. Server then relays the notify messages to clients if needed.
167 if (packet->flags & SILC_PACKET_FLAG_LIST)
168 silc_server_notify_list(server, sock, packet);
170 silc_server_notify(server, sock, packet);
174 * Private Message packets
176 case SILC_PACKET_PRIVATE_MESSAGE:
178 * Received private message packet. The packet is coming from either
181 if (packet->flags & SILC_PACKET_FLAG_LIST)
183 idata->last_receive = time(NULL);
184 silc_server_private_message(server, sock, packet);
190 case SILC_PACKET_CHANNEL_MESSAGE:
192 * Received channel message. Channel messages are special packets
193 * (although probably most common ones) thus they are handled
196 if (packet->flags & SILC_PACKET_FLAG_LIST)
198 idata->last_receive = time(NULL);
199 silc_server_channel_message(server, sock, packet);
205 case SILC_PACKET_COMMAND:
207 * Recived command. Processes the command request and allocates the
208 * command context and calls the command.
210 if (packet->flags & SILC_PACKET_FLAG_LIST)
212 server->stat.commands_received++;
213 silc_server_command_process(server, sock, packet);
216 case SILC_PACKET_COMMAND_REPLY:
218 * Received command reply packet. Received command reply to command. It
219 * may be reply to command sent by us or reply to command sent by client
220 * that we've routed further.
222 if (packet->flags & SILC_PACKET_FLAG_LIST)
224 server->stat.commands_received++;
225 silc_server_command_reply(server, sock, packet);
228 case SILC_PACKET_DISCONNECT:
231 char *message = NULL;
233 if (packet->flags & SILC_PACKET_FLAG_LIST)
235 if (silc_buffer_len(&packet->buffer) < 1)
238 status = (SilcStatus)packet->buffer.data[0];
239 if (silc_buffer_len(&packet->buffer) > 1 &&
240 silc_utf8_valid(packet->buffer.data + 1, silc_buffer_len(&packet->buffer) - 1))
241 message = silc_memdup(packet->buffer.data + 1,
242 silc_buffer_len(&packet->buffer) - 1);
245 SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s",
246 sock->ip, sock->hostname,
247 silc_get_status_message(status), status,
248 message ? message : ""));
252 /* Do not switch to backup in case of error */
253 server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
255 /* If backup disconnected then mark that resuming will not be allowed */
257 if (server->server_type == SILC_ROUTER && !server->backup_router &&
258 sock->type == SILC_CONN_SERVER && sock->user_data) {
259 SilcServerEntry server_entry = sock->user_data;
260 if (server_entry->server_type == SILC_BACKUP_ROUTER)
261 server->backup_closed = TRUE;
264 /* Handle the disconnection from our end too */
265 if (sock->user_data && SILC_IS_LOCAL(sock->user_data))
266 silc_server_free_sock_user_data(server, sock, NULL);
267 SILC_SET_DISCONNECTING(sock);
268 silc_server_close_connection(server, sock);
269 server->backup_noswitch = FALSE;
274 case SILC_PACKET_CHANNEL_KEY:
276 * Received key for channel. As channels are created by the router
277 * the keys are as well. We will distribute the key to all of our
278 * locally connected clients on the particular channel. Router
279 * never receives this channel and thus is ignored.
281 if (packet->flags & SILC_PACKET_FLAG_LIST)
283 silc_server_channel_key(server, sock, packet);
286 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
288 * Private message key packet.
290 if (packet->flags & SILC_PACKET_FLAG_LIST)
292 silc_server_private_message_key(server, sock, packet);
295 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
297 * Connection authentication request packet. When we receive this packet
298 * we will send to the other end information about our mandatory
299 * authentication method for the connection. This packet maybe received
302 if (packet->flags & SILC_PACKET_FLAG_LIST)
304 silc_server_connection_auth_request(server, sock, packet);
307 case SILC_PACKET_NEW_ID:
309 * Received New ID packet. This includes some new ID that has been
310 * created. It may be for client, server or channel. This is the way
311 * to distribute information about new registered entities in the
314 if (packet->flags & SILC_PACKET_FLAG_LIST)
315 silc_server_new_id_list(server, sock, packet);
317 silc_server_new_id(server, sock, packet);
320 case SILC_PACKET_NEW_CLIENT:
322 * Received new client packet. This includes client information that
323 * we will use to create initial client ID. After creating new
324 * ID we will send it to the client.
326 if (packet->flags & SILC_PACKET_FLAG_LIST)
328 silc_server_new_client(server, sock, packet);
331 case SILC_PACKET_NEW_SERVER:
333 * Received new server packet. This includes Server ID and some other
334 * information that we may save. This is received after server has
337 if (packet->flags & SILC_PACKET_FLAG_LIST)
339 silc_server_new_server(server, sock, packet);
342 case SILC_PACKET_NEW_CHANNEL:
344 * Received new channel packet. Information about new channel in the
345 * network are distributed using this packet.
347 if (packet->flags & SILC_PACKET_FLAG_LIST)
348 silc_server_new_channel_list(server, sock, packet);
350 silc_server_new_channel(server, sock, packet);
353 case SILC_PACKET_HEARTBEAT:
355 * Received heartbeat.
357 if (packet->flags & SILC_PACKET_FLAG_LIST)
361 case SILC_PACKET_KEY_AGREEMENT:
363 * Received heartbeat.
365 if (packet->flags & SILC_PACKET_FLAG_LIST)
367 silc_server_key_agreement(server, sock, packet);
370 case SILC_PACKET_REKEY:
372 * Received re-key packet. The sender wants to regenerate the session
375 if (packet->flags & SILC_PACKET_FLAG_LIST)
377 silc_server_rekey(server, sock, packet);
380 case SILC_PACKET_FTP:
382 if (packet->flags & SILC_PACKET_FLAG_LIST)
384 silc_server_ftp(server, sock, packet);
387 case SILC_PACKET_RESUME_CLIENT:
389 if (packet->flags & SILC_PACKET_FLAG_LIST)
391 silc_server_resume_client(server, sock, packet);
394 case SILC_PACKET_RESUME_ROUTER:
395 /* Resume router packet received. This packet is received for backup
396 router resuming protocol. */
397 if (packet->flags & SILC_PACKET_FLAG_LIST)
400 silc_server_backup_resume_router(server, sock, packet);
405 SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
410 /****************************** Server API **********************************/
412 /* Allocates a new SILC server object. This has to be done before the server
413 can be used. After allocation one must call silc_server_init to initialize
414 the server. The new allocated server object is returned to the new_server
417 SilcBool silc_server_alloc(SilcServer *new_server)
421 SILC_LOG_DEBUG(("Allocating new server object"));
423 server = silc_calloc(1, sizeof(*server));
426 server->server_type = SILC_SERVER;
427 server->standalone = TRUE;
428 server->local_list = silc_calloc(1, sizeof(*server->local_list));
429 if (!server->local_list)
431 server->global_list = silc_calloc(1, sizeof(*server->global_list));
432 if (!server->global_list)
434 server->pending_commands = silc_dlist_init();
435 if (!server->pending_commands)
437 server->listeners = silc_dlist_init();
438 if (!server->listeners)
440 server->repository = silc_skr_alloc();
441 if (!server->repository)
443 server->conns = silc_dlist_init();
447 *new_server = server;
452 /* Free's the SILC server object. This is called at the very end before
455 void silc_server_free(SilcServer server)
458 SilcIDCacheEntry cache;
463 silc_server_backup_free(server);
464 silc_server_config_unref(&server->config_ref);
466 silc_hash_table_free(server->pk_hash);
468 silc_rng_free(server->rng);
469 if (server->public_key)
470 silc_pkcs_public_key_free(server->public_key);
471 if (server->private_key)
472 silc_pkcs_private_key_free(server->private_key);
473 if (server->pending_commands)
474 silc_dlist_uninit(server->pending_commands);
475 if (server->id_entry)
476 silc_idlist_del_server(server->local_list, server->id_entry);
478 /* Delete all channels */
479 if (silc_idcache_get_all(server->local_list->channels, &list)) {
480 silc_list_start(list);
481 while ((cache = silc_list_get(list)))
482 silc_idlist_del_channel(server->local_list, cache->context);
484 if (silc_idcache_get_all(server->global_list->channels, &list)) {
485 silc_list_start(list);
486 while ((cache = silc_list_get(list)))
487 silc_idlist_del_channel(server->global_list, cache->context);
490 /* Delete all clients */
491 if (silc_idcache_get_all(server->local_list->clients, &list)) {
492 silc_list_start(list);
493 while ((cache = silc_list_get(list)))
494 silc_idlist_del_client(server->local_list, cache->context);
496 if (silc_idcache_get_all(server->global_list->clients, &list)) {
497 silc_list_start(list);
498 while ((cache = silc_list_get(list)))
499 silc_idlist_del_client(server->global_list, cache->context);
502 /* Delete all servers */
503 if (silc_idcache_get_all(server->local_list->servers, &list)) {
504 silc_list_start(list);
505 while ((cache = silc_list_get(list)))
506 silc_idlist_del_server(server->local_list, cache->context);
508 if (silc_idcache_get_all(server->global_list->servers, &list)) {
509 while ((cache = silc_list_get(list)))
510 silc_idlist_del_server(server->global_list, cache->context);
513 silc_idcache_free(server->local_list->clients);
514 silc_idcache_free(server->local_list->servers);
515 silc_idcache_free(server->local_list->channels);
516 silc_idcache_free(server->global_list->clients);
517 silc_idcache_free(server->global_list->servers);
518 silc_idcache_free(server->global_list->channels);
519 silc_hash_table_free(server->watcher_list);
520 silc_hash_table_free(server->watcher_list_pk);
522 silc_hash_free(server->md5hash);
523 silc_hash_free(server->sha1hash);
524 silc_hmac_unregister_all();
525 silc_hash_unregister_all();
526 silc_cipher_unregister_all();
527 silc_pkcs_unregister_all();
529 silc_free(server->local_list);
530 silc_free(server->global_list);
531 silc_free(server->server_name);
532 silc_free(server->id_string);
533 silc_free(server->purge_i);
534 silc_free(server->purge_g);
538 /* Creates a new server listener. */
540 static SilcNetListener
541 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
543 SilcNetListener listener;
546 silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
547 server->config->require_reverse_lookup,
549 silc_server_accept_new_connection, server);
551 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
559 /* Adds a secondary listener. */
561 SilcBool silc_server_init_secondary(SilcServer server)
566 SilcPacketStream newsocket = NULL;
567 SilcServerConfigServerInfoInterface *interface;
569 for (interface = server->config->server_info->secondary; interface;
570 interface = interface->next, sock++) {
572 if (!silc_server_listen(server,
573 interface->server_ip, interface->port, &sock_list[sock]))
576 /* Set socket to non-blocking mode */
577 silc_net_set_socket_nonblock(sock_list[sock]);
579 /* Add ourselves also to the socket table. The entry allocated above
580 is sent as argument for fast referencing in the future. */
581 silc_socket_alloc(sock_list[sock],
582 SILC_CONN_SERVER, NULL, &newsocket);
583 server->sockets[sock_list[sock]] = newsocket;
584 SILC_SET_LISTENER(newsocket);
586 /* Perform name and address lookups to resolve the listenning address
588 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
590 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
592 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
593 newsocket->hostname ? newsocket->hostname :
594 newsocket->ip ? newsocket->ip : ""));
595 server->stat.conn_failures++;
598 if (!newsocket->hostname)
599 newsocket->hostname = strdup(newsocket->ip);
601 newsocket->port = silc_net_get_local_port(sock);
603 newsocket->user_data = (void *)server->id_entry;
604 silc_schedule_task_add(server->schedule, sock_list[sock],
605 silc_server_accept_new_connection,
606 (void *)server, 0, 0,
608 SILC_TASK_PRI_NORMAL);
614 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
619 /* Initializes the entire SILC server. This is called always before running
620 the server. This is called only once at the initialization of the program.
621 This binds the server to its listenning port. After this function returns
622 one should call silc_server_run to start the server. This returns TRUE
623 when everything is ok to run the server. Configuration file must be
624 read and parsed before calling this. */
626 SilcBool silc_server_init(SilcServer server)
629 SilcServerEntry id_entry;
630 SilcIDListPurge purge;
631 SilcNetListener listener;
635 SILC_LOG_DEBUG(("Initializing server"));
637 server->starttime = time(NULL);
639 /* Take config object for us */
640 silc_server_config_ref(&server->config_ref, server->config,
644 /* Set debugging on if configured */
645 if (server->config->debug_string) {
646 silc_log_debug(TRUE);
647 silc_log_set_debug_string(server->config->debug_string);
649 #endif /* SILC_DEBUG */
651 /* Steal public and private key from the config object */
652 server->public_key = server->config->server_info->public_key;
653 server->private_key = server->config->server_info->private_key;
654 server->config->server_info->public_key = NULL;
655 server->config->server_info->private_key = NULL;
657 /* Register all configured ciphers, PKCS and hash functions. */
658 if (!silc_server_config_register_ciphers(server))
659 silc_cipher_register_default();
660 if (!silc_server_config_register_pkcs(server))
661 silc_pkcs_register_default();
662 if (!silc_server_config_register_hashfuncs(server))
663 silc_hash_register_default();
664 if (!silc_server_config_register_hmacs(server))
665 silc_hmac_register_default();
667 /* Initialize random number generator for the server. */
668 server->rng = silc_rng_alloc();
669 silc_rng_init(server->rng);
670 silc_rng_global_init(server->rng);
672 /* Initialize hash functions for server to use */
673 silc_hash_alloc("md5", &server->md5hash);
674 silc_hash_alloc("sha1", &server->sha1hash);
676 /* Initialize the scheduler */
677 server->schedule = silc_schedule_init(server->config->param.connections_max,
679 if (!server->schedule)
682 /* First, register log files configuration for error output */
683 silc_server_config_setlogfiles(server);
685 /* Initialize ID caches */
686 server->local_list->clients =
687 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
689 server->local_list->servers =
690 silc_idcache_alloc(0, SILC_ID_SERVER, NULL, NULL);
691 server->local_list->channels =
692 silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, NULL);
694 /* These are allocated for normal server as well as these hold some
695 global information that the server has fetched from its router. For
696 router these are used as they are supposed to be used on router. */
697 server->global_list->clients =
698 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
700 server->global_list->servers =
701 silc_idcache_alloc(0, SILC_ID_SERVER, NULL, NULL);
702 server->global_list->channels =
703 silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, NULL);
705 /* Init watcher lists */
706 server->watcher_list =
707 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
708 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
710 if (!server->watcher_list)
712 server->watcher_list_pk =
713 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
714 silc_hash_public_key_compare, NULL,
716 if (!server->watcher_list_pk)
719 /* Init public key list */
721 silc_hash_table_alloc(0, silc_hash_public_key, NULL,
722 silc_hash_public_key_compare, NULL,
725 if (!server->pk_hash)
728 /* Create TCP listener */
729 listener = silc_server_listen(
731 server->config->server_info->primary == NULL ? NULL :
732 server->config->server_info->primary->server_ip,
733 server->config->server_info->primary == NULL ? 0 :
734 server->config->server_info->primary->port);
738 silc_dlist_add(server->listeners, listener);
740 /* Create a Server ID for the server. */
741 port = silc_net_listener_get_port(listener, NULL);
742 ip = silc_net_listener_get_ip(listener, NULL);
743 silc_id_create_server_id(ip[0], port[0], server->rng, &id);
752 server->server_name = server->config->server_info->server_name;
753 server->config->server_info->server_name = NULL;
755 /* Add ourselves to the server list. We don't have a router yet
756 beacuse we haven't established a route yet. It will be done later.
757 For now, NULL is sent as router. This allocates new entry to
760 silc_idlist_add_server(server->local_list, strdup(server->server_name),
761 server->server_type, server->id, NULL, NULL);
763 SILC_LOG_ERROR(("Could not add local server to cache"));
766 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
767 server->id_entry = id_entry;
769 /* Create secondary TCP listeners */
770 if (silc_server_init_secondary(server) == FALSE)
773 /* Create connections to configured routers. */
774 silc_server_create_connections(server);
776 server->listenning = TRUE;
778 /* Allocate the entire socket list that is used in server. Eventually
779 all connections will have entry in this table (it is a table of
780 pointers to the actual object that is allocated individually
782 server->sockets = silc_calloc(server->config->param.connections_max,
783 sizeof(*server->sockets));
784 if (!server->sockets)
787 /* If server connections has been configured then we must be router as
788 normal server cannot have server connections, only router connections. */
789 if (server->config->servers) {
790 SilcServerConfigServer *ptr = server->config->servers;
792 server->server_type = SILC_ROUTER;
794 if (ptr->backup_router) {
795 server->server_type = SILC_BACKUP_ROUTER;
796 server->backup_router = TRUE;
797 server->id_entry->server_type = SILC_BACKUP_ROUTER;
804 /* Register the ID Cache purge task. This periodically purges the ID cache
805 and removes the expired cache entries. */
807 /* Clients local list */
808 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
809 purge->cache = server->local_list->clients;
810 purge->timeout = 600;
811 silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
812 (void *)purge, purge->timeout, 0);
814 /* Clients global list */
815 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
816 purge->cache = server->global_list->clients;
817 purge->timeout = 300;
818 silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
819 (void *)purge, purge->timeout, 0);
821 /* If we are normal server we'll retrieve network statisticial information
822 once in a while from the router. */
823 if (server->server_type != SILC_ROUTER)
824 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
827 if (server->server_type == SILC_ROUTER)
828 server->stat.routers++;
830 /* Start packet engine */
831 server->packet_engine =
832 silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
833 &silc_server_stream_cbs, server);
834 if (!server->packet_engine)
837 SILC_LOG_DEBUG(("Server initialized"));
839 /* We are done here, return succesfully */
843 silc_server_config_unref(&server->config_ref);
848 /* Task callback to close a socket connection after rehash */
850 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
852 SilcServer server = context;
853 SilcPacketStream sock = server->sockets[fd];
858 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
859 sock->hostname, sock->port,
860 (sock->type == SILC_CONN_UNKNOWN ? "Unknown" :
861 sock->type == SILC_CONN_CLIENT ? "Client" :
862 sock->type == SILC_CONN_SERVER ? "Server" :
864 silc_schedule_task_del_by_context(server->schedule, sock);
865 silc_server_disconnect_remote(server, sock,
866 SILC_STATUS_ERR_BANNED_FROM_SERVER,
867 "This connection is removed from "
870 silc_server_free_sock_user_data(server, sock, NULL);
874 /* This function basically reads the config file again and switches the config
875 object pointed by the server object. After that, we have to fix various
876 things such as the server_name and the listening ports.
877 Keep in mind that we no longer have the root privileges at this point. */
879 SilcBool silc_server_rehash(SilcServer server)
882 SilcServerConfig newconfig;
884 SILC_LOG_INFO(("Rehashing server"));
886 /* Reset the logging system */
887 silc_log_quick(TRUE);
888 silc_log_flush_all();
890 /* Start the main rehash phase (read again the config file) */
891 newconfig = silc_server_config_alloc(server->config_file, server);
893 SILC_LOG_ERROR(("Rehash FAILED."));
897 /* Reinit scheduler if necessary */
898 if (newconfig->param.connections_max > server->config->param.connections_max)
899 if (!silc_schedule_reinit(server->schedule,
900 newconfig->param.connections_max))
903 /* Fix the server_name field */
904 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
905 silc_free(server->server_name);
907 /* Check server name */
908 server->server_name =
909 silc_identifier_check(newconfig->server_info->server_name,
910 strlen(newconfig->server_info->server_name),
911 SILC_STRING_LOCALE, 256, NULL);
912 if (!server->server_name) {
913 SILC_LOG_ERROR(("Malformed server name string '%s'",
914 server->config->server_info->server_name));
918 /* Update the idcache list with a fresh pointer */
919 silc_free(server->id_entry->server_name);
920 server->id_entry->server_name = strdup(server->server_name);
921 if (!silc_idcache_del_by_context(server->local_list->servers,
924 if (!silc_idcache_add(server->local_list->servers,
925 strdup(server->id_entry->server_name),
926 server->id_entry->id, server->id_entry, 0, NULL))
931 silc_server_config_setlogfiles(server);
933 /* Change new key pair if necessary */
934 if (newconfig->server_info->public_key &&
935 !silc_pkcs_public_key_compare(server->public_key,
936 newconfig->server_info->public_key)) {
937 silc_pkcs_public_key_free(server->public_key);
938 silc_pkcs_private_key_free(server->private_key);
939 server->public_key = newconfig->server_info->public_key;
940 server->private_key = newconfig->server_info->private_key;
941 newconfig->server_info->public_key = NULL;
942 newconfig->server_info->private_key = NULL;
944 /* Allocate PKCS context for local public and private keys */
945 silc_pkcs_free(server->pkcs);
946 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
948 silc_pkcs_public_key_set(server->pkcs, server->public_key);
949 silc_pkcs_private_key_set(server->pkcs, server->private_key);
952 /* Check for unconfigured server and router connections and close
953 connections that were unconfigured. */
955 if (server->config->routers) {
956 SilcServerConfigRouter *ptr;
957 SilcServerConfigRouter *newptr;
960 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
963 /* Check whether new config has this one too */
964 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
965 if (silc_string_compare(newptr->host, ptr->host) &&
966 newptr->port == ptr->port &&
967 newptr->initiator == ptr->initiator) {
973 if (!found && ptr->host) {
974 /* Remove this connection */
975 SilcPacketStream sock;
976 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
977 ptr->host, ptr->port);
978 if (sock && !SILC_IS_LISTENER(sock))
979 silc_schedule_task_add(server->schedule, sock->sock,
980 silc_server_rehash_close_connection,
981 server, 0, 1, SILC_TASK_TIMEOUT,
982 SILC_TASK_PRI_NORMAL);
987 if (server->config->servers) {
988 SilcServerConfigServer *ptr;
989 SilcServerConfigServer *newptr;
992 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
995 /* Check whether new config has this one too */
996 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
997 if (silc_string_compare(newptr->host, ptr->host)) {
1003 if (!found && ptr->host) {
1004 /* Remove this connection */
1005 SilcPacketStream sock;
1006 sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1008 if (sock && !SILC_IS_LISTENER(sock))
1009 silc_schedule_task_add(server->schedule, sock->sock,
1010 silc_server_rehash_close_connection,
1011 server, 0, 1, SILC_TASK_TIMEOUT,
1012 SILC_TASK_PRI_NORMAL);
1017 if (server->config->clients) {
1018 SilcServerConfigClient *ptr;
1019 SilcServerConfigClient *newptr;
1022 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1025 /* Check whether new config has this one too */
1026 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1027 if (silc_string_compare(newptr->host, ptr->host)) {
1033 if (!found && ptr->host) {
1034 /* Remove this connection */
1035 SilcPacketStream sock;
1036 sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1039 silc_schedule_task_add(server->schedule, sock->sock,
1040 silc_server_rehash_close_connection,
1041 server, 0, 1, SILC_TASK_TIMEOUT,
1042 SILC_TASK_PRI_NORMAL);
1047 /* Create connections after rehash */
1048 silc_server_create_connections(server);
1050 /* Check whether our router status has changed */
1051 if (newconfig->servers) {
1052 SilcServerConfigServer *ptr = newconfig->servers;
1054 server->server_type = SILC_ROUTER;
1056 if (ptr->backup_router) {
1057 server->server_type = SILC_BACKUP_ROUTER;
1058 server->backup_router = TRUE;
1059 server->id_entry->server_type = SILC_BACKUP_ROUTER;
1066 /* Our old config is gone now. We'll unreference our reference made in
1067 silc_server_init and then destroy it since we are destroying it
1068 underneath the application (layer which called silc_server_init). */
1069 silc_server_config_unref(&server->config_ref);
1070 silc_server_config_destroy(server->config);
1072 /* Take new config context */
1073 server->config = newconfig;
1074 silc_server_config_ref(&server->config_ref, server->config, server->config);
1077 /* Set debugging on if configured */
1078 if (server->config->debug_string) {
1079 silc_log_debug(TRUE);
1080 silc_log_set_debug_string(server->config->debug_string);
1082 #endif /* SILC_DEBUG */
1084 SILC_LOG_DEBUG(("Server rehashed"));
1090 /* The heart of the server. This runs the scheduler thus runs the server.
1091 When this returns the server has been stopped and the program will
1094 void silc_server_run(SilcServer server)
1096 SILC_LOG_INFO(("SILC Server started"));
1098 /* Start the scheduler, the heart of the SILC server. When this returns
1099 the program will be terminated. */
1100 silc_schedule(server->schedule);
1103 /* Stops the SILC server. This function is used to shutdown the server.
1104 This is usually called after the scheduler has returned. After stopping
1105 the server one should call silc_server_free. */
1107 void silc_server_stop(SilcServer server)
1110 SilcPacketStream ps;
1112 SILC_LOG_INFO(("SILC Server shutting down"));
1114 server->server_shutdown = TRUE;
1116 /* Close all connections */
1117 if (server->packet_engine) {
1118 list = silc_packet_engine_get_streams(server->packet_engine);
1120 silc_dlist_start(list);
1121 while ((ps = silc_dlist_get(list))) {
1122 SilcIDListData idata = silc_packet_get_context(ps);
1125 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1127 silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1128 "Server is shutting down");
1129 silc_server_free_sock_user_data(server, ps,
1130 "Server is shutting down");
1132 silc_dlist_uninit(list);
1135 /* We are not connected to network anymore */
1136 server->standalone = TRUE;
1138 silc_schedule_stop(server->schedule);
1139 silc_schedule_uninit(server->schedule);
1140 server->schedule = NULL;
1142 SILC_LOG_DEBUG(("Server stopped"));
1146 /* Parses whole packet, received earlier. */
1148 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1150 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1151 SilcServer server = (SilcServer)parse_ctx->context;
1152 SilcPacketStream sock = parse_ctx->sock;
1153 SilcPacket *packet = parse_ctx->packet;
1154 SilcIDListData idata = (SilcIDListData)sock->user_data;
1157 if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1158 SILC_LOG_DEBUG(("Connection is disconnected"));
1162 server->stat.packets_received++;
1164 /* Parse the packet */
1165 if (parse_ctx->normal)
1166 ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1168 ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1170 /* If entry is disabled ignore what we got. */
1171 if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
1172 ret != SILC_PACKET_HEARTBEAT && ret != SILC_PACKET_RESUME_ROUTER &&
1173 ret != SILC_PACKET_REKEY && ret != SILC_PACKET_REKEY_DONE &&
1174 ret != SILC_PACKET_KEY_EXCHANGE_1 && ret != SILC_PACKET_KEY_EXCHANGE_2) {
1175 SILC_LOG_DEBUG(("Connection is disabled (packet %s dropped)",
1176 silc_get_packet_name(ret)));
1180 if (ret == SILC_PACKET_NONE) {
1181 SILC_LOG_DEBUG(("Error parsing packet"));
1185 /* Check that the the current client ID is same as in the client's packet. */
1186 if (sock->type == SILC_CONN_CLIENT) {
1187 SilcClientEntry client = (SilcClientEntry)sock->user_data;
1188 if (client && client->id && packet->src_id) {
1189 void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1190 packet->src_id_type);
1191 if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1193 SILC_LOG_DEBUG(("Packet source is not same as sender"));
1200 if (server->server_type == SILC_ROUTER) {
1201 /* Route the packet if it is not destined to us. Other ID types but
1202 server are handled separately after processing them. */
1203 if (packet->dst_id && !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1204 packet->dst_id_type == SILC_ID_SERVER &&
1205 sock->type != SILC_CONN_CLIENT &&
1206 memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1207 SilcPacketStream conn;
1209 /* Route the packet to fastest route for the destination ID */
1210 void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1211 packet->dst_id_type);
1215 conn = silc_server_route_get(server, id, packet->dst_id_type);
1217 SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
1218 silc_id_render(id, SILC_ID_SERVER)));
1222 silc_server_packet_route(server, conn, packet);
1228 /* Parse the incoming packet type */
1229 silc_server_packet_parse_type(server, sock, packet);
1231 /* Broadcast packet if it is marked as broadcast packet and it is
1232 originated from router and we are router. */
1233 if (server->server_type == SILC_ROUTER &&
1234 sock->type == SILC_CONN_ROUTER &&
1235 packet->flags & SILC_PACKET_FLAG_BROADCAST) {
1236 /* Broadcast to our primary route */
1237 silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
1239 /* If we have backup routers then we need to feed all broadcast
1240 data to those servers. */
1241 silc_server_backup_broadcast(server, sock, packet);
1245 silc_packet_context_free(packet);
1246 silc_free(parse_ctx);
1251 /******************************* Connecting *********************************/
1253 /* Free connection context */
1255 static void silc_server_connection_free(SilcServerConnection sconn)
1257 silc_dlist_del(sconn->server->conns, sconn);
1258 silc_server_config_unref(&sconn->conn);
1259 silc_free(sconn->remote_host);
1260 silc_free(sconn->backup_replace_ip);
1264 /* Creates connection to a remote router. */
1266 void silc_server_create_connection(SilcServer server,
1268 const char *remote_host, SilcUInt32 port,
1269 SilcServerConnectCallback callback,
1272 SilcServerConnection sconn;
1274 /* Allocate connection object for hold connection specific stuff. */
1275 sconn = silc_calloc(1, sizeof(*sconn));
1278 sconn->remote_host = strdup(remote_host);
1279 sconn->remote_port = port;
1280 sconn->no_reconnect = reconnect == FALSE;
1281 sconn->callback = callback;
1282 sconn->callback_context = context;
1284 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1288 /* Connection authentication completion callback */
1291 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1294 SilcServerConnection sconn = context;
1295 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1296 SilcServer server = entry->server;
1297 SilcServerConfigServer *conn;
1298 SilcServerConfigConnParams *param;
1299 SilcIDListData idata;
1300 SilcServerEntry id_entry;
1301 unsigned char id[32];
1305 SILC_LOG_DEBUG(("Connection authentication completed"));
1307 if (success == FALSE) {
1308 /* Authentication failed */
1309 /* XXX retry connecting */
1311 silc_server_disconnect_remote(server, sconn->sock,
1312 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1316 SILC_LOG_INFO(("Connected to %s %s",
1317 SILC_CONNTYPE_STRING(entry->data.conn_type),
1318 sconn->remote_host));
1320 /* Create the actual entry for remote entity */
1321 switch (entry->data.conn_type) {
1322 case SILC_CONN_SERVER:
1323 SILC_LOG_DEBUG(("Remote is SILC server"));
1325 /* Add new server. The server must register itself to us before it
1326 becomes registered to SILC network. */
1327 id_entry = silc_idlist_add_server(server->local_list,
1328 strdup(sconn->remote_host),
1329 SILC_SERVER, NULL, NULL, sconn->sock);
1331 silc_server_disconnect_remote(server, sconn->sock,
1332 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1333 silc_server_connection_free(sconn);
1338 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1341 case SILC_CONN_ROUTER:
1342 SILC_LOG_DEBUG(("Remote is SILC router"));
1344 /* Register to network */
1345 silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1346 if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1347 SILC_STR_UI_SHORT(id_len),
1348 SILC_STR_DATA(id, id_len),
1349 SILC_STR_UI_SHORT(strlen(server->server_name)),
1350 SILC_STR_DATA(server->server_name,
1351 strlen(server->server_name)),
1353 silc_server_disconnect_remote(server, sconn->sock,
1354 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1355 silc_server_connection_free(sconn);
1361 silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1363 /* Check that we do not have this ID already */
1364 id_entry = silc_idlist_find_server_by_id(server->local_list,
1365 &remote_id.u.server_id,
1368 silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1370 id_entry = silc_idlist_find_server_by_id(server->global_list,
1371 &remote_id.u.server_id,
1374 silc_idcache_del_by_context(server->global_list->servers, id_entry,
1378 SILC_LOG_DEBUG(("New server id(%s)",
1379 silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1381 /* Add the connected router to global server list. Router is sent
1382 as NULL since it's local to us. */
1383 id_entry = silc_idlist_add_server(server->global_list,
1384 strdup(sconn->remote_host),
1385 SILC_ROUTER, &remote_id.u.server_id,
1388 silc_server_disconnect_remote(server, sconn->sock,
1389 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1390 silc_server_connection_free(sconn);
1396 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1397 idata = (SilcIDListData)entry;
1398 idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1399 SILC_IDLIST_STATUS_LOCAL);
1401 if (!sconn->backup) {
1402 /* Mark this router our primary router if we're still standalone */
1403 if (server->standalone) {
1404 SILC_LOG_DEBUG(("This connection is our primary router"));
1405 server->id_entry->router = id_entry;
1406 server->router = id_entry;
1407 server->router->server_type = SILC_ROUTER;
1408 server->standalone = FALSE;
1409 server->backup_primary = FALSE;
1411 /* Announce data if we are not backup router (unless not as primary
1412 currently). Backup router announces later at the end of
1413 resuming protocol. */
1414 if (server->backup_router && server->server_type == SILC_ROUTER) {
1415 SILC_LOG_DEBUG(("Announce data after resume protocol"));
1417 /* If we are router then announce our possible servers. Backup
1418 router announces also global servers. */
1419 if (server->server_type == SILC_ROUTER)
1420 silc_server_announce_servers(server,
1421 server->backup_router ? TRUE : FALSE,
1422 0, SILC_PRIMARY_ROUTE(server));
1424 /* Announce our clients and channels to the router */
1425 silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1426 silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1430 /* If we are backup router then this primary router is whom we are
1432 if (server->server_type == SILC_BACKUP_ROUTER)
1433 silc_server_backup_add(server, server->id_entry, sock->ip,
1434 sconn->remote_port, TRUE);
1438 /* Add this server to be our backup router */
1439 id_entry->server_type = SILC_BACKUP_ROUTER;
1440 silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1441 sconn->backup_replace_port, FALSE);
1447 silc_server_disconnect_remote(server, sconn->sock,
1448 SILC_STATUS_ERR_AUTH_FAILED, NULL);
1449 silc_server_connection_free(sconn);
1454 conn = sconn->conn.ref_ptr;
1455 param = &server->config->param;
1456 if (conn && conn->param)
1457 param = conn->param;
1459 /* Register rekey timeout */
1460 sconn->rekey_timeout = param->key_exchange_rekey;
1461 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1462 sconn->sock, sconn->rekey_timeout, 0);
1465 /* Perform keepalive. */
1466 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
1467 silc_server_perform_heartbeat,
1471 /* Call the completion callback to indicate that we've connected to
1473 if (sconn && sconn->callback)
1474 (*sconn->callback)(server, id_entry, sconn->callback_context);
1476 /* Free the temporary connection data context */
1478 silc_server_config_unref(&sconn->conn);
1479 silc_free(sconn->remote_host);
1480 silc_free(sconn->backup_replace_ip);
1483 if (sconn == server->router_conn)
1484 server->router_conn = NULL;
1490 /* SKE completion callback */
1492 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1493 SilcSKESecurityProperties prop,
1494 SilcSKEKeyMaterial keymat,
1495 SilcSKERekeyMaterial rekey,
1498 SilcServerConnection sconn = context;
1499 SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1500 SilcServer server = entry->server;
1501 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1502 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1503 void *auth_data = NULL;
1504 SilcUInt32 auth_data_len = 0;
1505 SilcConnAuth connauth;
1506 SilcCipher send_key, receive_key;
1507 SilcHmac hmac_send, hmac_receive;
1510 if (status != SILC_SKE_STATUS_OK) {
1512 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1513 silc_ske_map_status(status), entry->hostname, entry->ip));
1515 /* XXX retry connecting */
1517 silc_server_disconnect_remote(server, sconn->sock,
1518 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1519 silc_server_connection_free(sconn);
1523 SILC_LOG_DEBUG(("Setting keys into use"));
1525 /* Set the keys into use. The data will be encrypted after this. */
1526 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1527 &hmac_send, &hmac_receive, &hash)) {
1529 /* XXX retry connecting */
1531 /* Error setting keys */
1533 silc_server_disconnect_remote(server, sconn->sock,
1534 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1535 silc_server_connection_free(sconn);
1538 silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1539 hmac_receive, FALSE);
1541 SILC_LOG_DEBUG(("Starting connection authentication"));
1543 connauth = silc_connauth_alloc(server->schedule, ske,
1544 server->config->conn_auth_timeout);
1546 /* XXX retry connecting */
1548 /** Error allocating auth protocol */
1550 silc_server_disconnect_remote(server, sconn->sock,
1551 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1552 silc_server_connection_free(sconn);
1556 /* Get authentication method */
1558 if (conn->passphrase) {
1559 if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1560 auth_meth = SILC_AUTH_PUBLIC_KEY;
1561 auth_data = server->private_key;
1563 auth_meth = SILC_AUTH_PASSWORD;
1564 auth_data = conn->passphrase;
1565 auth_data_len = conn->passphrase_len;
1568 auth_meth = SILC_AUTH_PUBLIC_KEY;
1569 auth_data = server->private_key;
1573 /* Start connection authentication */
1574 silc_connauth_initiator(connauth, server->server_type == SILC_ROUTER ?
1575 SILC_CONN_ROUTER : SILC_CONN_SERVER, auth_meth,
1576 auth_data, auth_data_len,
1577 silc_server_ke_auth_compl, sconn);
1580 /* Function that is called when the network connection to a router has
1581 been established. This will continue with the key exchange protocol
1582 with the remote router. */
1584 void silc_server_start_key_exchange(SilcServerConnection sconn)
1586 SilcServer server = sconn->server;
1587 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1588 SilcUnknownEntry entry;
1589 SilcSKEParamsStruct params;
1592 /* Cancel any possible retry timeouts */
1593 silc_schedule_task_del_by_context(server->schedule, sconn);
1595 /* Create packet stream */
1596 sconn->sock = silc_packet_stream_create(server->packet_engine,
1597 server->schedule, sconn->stream);
1599 SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1600 silc_stream_destroy(sconn->stream);
1601 silc_server_connection_free(sconn);
1604 server->stat.conn_num++;
1606 /* Set source ID to packet stream */
1607 if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id,
1609 silc_packet_stream_destroy(sconn->sock);
1610 silc_server_connection_free(sconn);
1614 /* Create entry for remote entity */
1615 entry = silc_calloc(1, sizeof(*entry));
1617 silc_packet_stream_destroy(sconn->sock);
1618 silc_server_connection_free(sconn);
1621 entry->server = server;
1622 silc_packet_set_context(sconn->sock, entry);
1624 /* Set Key Exchange flags from configuration, but fall back to global
1626 memset(¶ms, 0, sizeof(params));
1627 SILC_GET_SKE_FLAGS(conn, params.flags);
1628 if (server->config->param.key_exchange_pfs)
1629 params.flags |= SILC_SKE_SP_FLAG_PFS;
1631 /* Start SILC Key Exchange protocol */
1632 SILC_LOG_DEBUG(("Starting key exchange protocol"));
1633 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1634 server->public_key, server->private_key, sconn->sock);
1637 silc_packet_stream_destroy(sconn->sock);
1638 silc_server_connection_free(sconn);
1641 silc_ske_set_callbacks(ske, silc_server_verify_key,
1642 silc_server_ke_completed, sconn->sock);
1644 /* Start key exchange protocol */
1645 params.version = silc_version_string;
1646 params.timeout_secs = server->config->key_exchange_timeout;
1647 silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
1650 /* Timeout callback that will be called to retry connecting to remote
1651 router. This is used by both normal and router server. This will wait
1652 before retrying the connecting. The timeout is generated by exponential
1653 backoff algorithm. */
1655 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1657 SilcServerConnection sconn = context;
1658 SilcServer server = sconn->server;
1659 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1660 SilcServerConfigConnParams *param =
1661 (conn->param ? conn->param : &server->config->param);
1663 SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1664 sconn->remote_port));
1666 /* Calculate next timeout */
1667 if (sconn->retry_count >= 1) {
1668 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1669 if (sconn->retry_timeout > param->reconnect_interval_max)
1670 sconn->retry_timeout = param->reconnect_interval_max;
1672 sconn->retry_timeout = param->reconnect_interval;
1674 sconn->retry_count++;
1675 sconn->retry_timeout = sconn->retry_timeout +
1676 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1678 /* If we've reached max retry count, give up. */
1679 if ((sconn->retry_count > param->reconnect_count) &&
1680 !param->reconnect_keep_trying) {
1681 SILC_LOG_ERROR(("Could not connect, giving up"));
1682 silc_server_connection_free(sconn);
1686 SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1688 /* We will lookup a fresh pointer later */
1689 silc_server_config_unref(&sconn->conn);
1691 /* Wait before retrying */
1692 silc_schedule_task_del_by_context(server->schedule, sconn);
1693 silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1694 sconn, sconn->retry_timeout, 0);
1697 /* Callback for async connection to remote router */
1699 static void silc_server_connection_established(SilcNetStatus status,
1703 SilcServerConnection sconn = context;
1704 SilcServer server = sconn->server;
1706 silc_schedule_task_del_by_context(server->schedule, sconn);
1711 SILC_LOG_DEBUG(("Connection to %s:%d established",
1712 sconn->remote_host, sconn->remote_port));
1714 /* Continue with key exchange protocol */
1715 sconn->stream = stream;
1716 silc_server_start_key_exchange(sconn);
1719 case SILC_NET_UNKNOWN_IP:
1720 case SILC_NET_UNKNOWN_HOST:
1721 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1722 sconn->remote_host, sconn->remote_port,
1723 silc_net_get_error_string(status)));
1724 silc_server_connection_free(sconn);
1728 SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1729 sconn->remote_host, sconn->remote_port,
1730 silc_net_get_error_string(status)));
1731 if (!sconn->no_reconnect) {
1732 silc_schedule_task_add_timeout(sconn->server->schedule,
1733 silc_server_connect_to_router_retry,
1736 silc_server_connection_free(sconn);
1742 /* Generic routine to use connect to a router. */
1744 SILC_TASK_CALLBACK(silc_server_connect_router)
1746 SilcServerConnection sconn = context;
1747 SilcServer server = sconn->server;
1748 SilcServerConfigRouter *rconn;
1750 silc_schedule_task_del_by_context(server->schedule, sconn);
1752 /* Don't connect if we are shutting down. */
1753 if (server->server_shutdown) {
1754 silc_server_connection_free(sconn);
1758 SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1759 (sconn->backup ? "backup router" : "router"),
1760 sconn->remote_host, sconn->remote_port));
1762 if (!server->no_conf) {
1763 /* Find connection configuration */
1764 rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1765 sconn->remote_port);
1767 SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1768 (sconn->backup ? "backup router" : "router"),
1769 sconn->remote_host, sconn->remote_port));
1770 silc_server_connection_free(sconn);
1773 silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1776 /* Connect to remote host */
1778 silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1779 server->config->server_info->primary->server_ip),
1780 sconn->remote_host, sconn->remote_port,
1781 server->schedule, silc_server_connection_established,
1784 SILC_LOG_ERROR(("Could not connect to router %s:%d",
1785 sconn->remote_host, sconn->remote_port));
1786 silc_server_connection_free(sconn);
1790 /* Add to connection list */
1791 silc_dlist_add(server->conns, sconn);
1794 /* This function connects to our primary router or if we are a router this
1795 establishes all our primary routes. This is called at the start of the
1796 server to do authentication and key exchange with our router - called
1799 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1801 SilcServer server = context;
1802 SilcServerConnection sconn;
1803 SilcServerConfigRouter *ptr;
1805 /* Don't connect if we are shutting down. */
1806 if (server->server_shutdown)
1809 SILC_LOG_DEBUG(("We are %s",
1810 (server->server_type == SILC_SERVER ?
1811 "normal server" : server->server_type == SILC_ROUTER ?
1812 "router" : "backup router/normal server")));
1815 if (!server->config->routers) {
1816 /* There wasn't a configured router, we will continue but we don't
1817 have a connection to outside world. We will be standalone server. */
1818 SILC_LOG_DEBUG(("No router(s), we are standalone"));
1819 server->standalone = TRUE;
1823 /* Create the connections to all our routes */
1824 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1826 SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1827 ptr->backup_router ? "Backup router" : "Router",
1828 ptr->initiator ? "Initiator" : "Responder",
1829 ptr->host, ptr->port));
1831 if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1832 ptr->initiator == FALSE && !server->backup_router &&
1833 !silc_server_config_get_backup_router(server))
1834 server->wait_backup = TRUE;
1836 if (!ptr->initiator)
1839 /* Check whether we are connecting or connected to this host already */
1840 if (silc_server_num_sockets_by_remote(server,
1841 silc_net_is_ip(ptr->host) ?
1843 silc_net_is_ip(ptr->host) ?
1844 NULL : ptr->host, ptr->port)) {
1845 SILC_LOG_DEBUG(("We are already connected to %s:%d",
1846 ptr->host, ptr->port));
1848 /* If we don't have primary router and this connection is our
1849 primary router we are in desync. Reconnect to the primary. */
1850 if (server->standalone && !server->router) {
1852 SilcPacketStream sock;
1853 SilcServerConfigRouter *primary =
1854 silc_server_config_get_primary_router(server);
1857 sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1858 ptr->host, ptr->port);
1861 server->backup_noswitch = TRUE;
1863 if (sock->user_data)
1864 silc_server_free_sock_user_data(server, sock, NULL);
1865 silc_server_disconnect_remote(server, sock, 0, NULL);
1867 server->backup_noswitch = FALSE;
1868 SILC_LOG_DEBUG(("Reconnecting to primary router"));
1874 /* Allocate connection object for hold connection specific stuff. */
1875 sconn = silc_calloc(1, sizeof(*sconn));
1878 sconn->remote_host = strdup(ptr->host);
1879 sconn->remote_port = ptr->port;
1880 sconn->backup = ptr->backup_router;
1881 if (sconn->backup) {
1882 sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1883 sconn->backup_replace_port = ptr->backup_replace_port;
1887 if (!server->router_conn && !sconn->backup)
1888 server->router_conn = sconn;
1891 silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
1897 /************************ Accepting new connection **************************/
1899 /* After this is called, server don't wait for backup router anymore.
1900 This gets called automatically even after we have backup router
1901 connection established. */
1903 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
1905 SilcServer server = context;
1906 server->wait_backup = FALSE;
1909 /* Authentication data callback */
1912 silc_server_accept_get_auth(SilcConnAuth connauth,
1913 SilcConnectionType conn_type,
1914 unsigned char **passphrase,
1915 SilcUInt32 *passphrase_len,
1916 SilcSKR *repository,
1919 SilcPacketStream sock = context;
1920 SilcUnknownEntry entry = silc_packet_get_context(sock);
1921 SilcServer server = entry->server;
1923 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
1925 /* Remote end is client */
1926 if (conn_type == SILC_CONN_CLIENT) {
1927 SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
1931 *passphrase = cconfig->passphrase;
1932 *passphrase_len = cconfig->passphrase_len;
1933 if (cconfig->publickeys)
1934 *repository = server->repository;
1936 entry->data.conn_type = conn_type;
1940 /* Remote end is server */
1941 if (conn_type == SILC_CONN_SERVER) {
1942 SilcServerConfigServer *sconfig = entry->sconfig.ref_ptr;
1946 *passphrase = sconfig->passphrase;
1947 *passphrase_len = sconfig->passphrase_len;
1948 if (sconfig->publickeys)
1949 *repository = server->repository;
1951 entry->data.conn_type = conn_type;
1955 /* Remote end is router */
1956 if (conn_type == SILC_CONN_ROUTER) {
1957 SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
1961 *passphrase = rconfig->passphrase;
1962 *passphrase_len = rconfig->passphrase_len;
1963 if (rconfig->publickeys)
1964 *repository = server->repository;
1966 entry->data.conn_type = conn_type;
1973 /* Authentication completion callback. */
1976 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
1979 SilcPacketStream sock = context;
1980 SilcUnknownEntry entry = silc_packet_get_context(sock);
1981 SilcIDListData idata = (SilcIDListData)entry;
1982 SilcServer server = entry->server;
1983 SilcServerConfigConnParams *param;
1984 SilcServerConnection sconn;
1986 const char *hostname;
1989 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1990 NULL, &hostname, NULL, &port);
1992 if (success == FALSE) {
1993 /* Authentication failed */
1994 SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
1995 entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
1996 server->stat.auth_failures++;
1997 silc_server_disconnect_remote(server, sock,
1998 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2002 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2004 switch (entry->data.conn_type) {
2005 case SILC_CONN_CLIENT:
2007 SilcClientEntry client;
2008 SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2010 /* Verify whether this connection is after all allowed to connect */
2011 if (!silc_server_connection_allowed(server, sock, entry->data.conn_type,
2012 &server->config->param,
2014 silc_connauth_get_ske(connauth))) {
2015 server->stat.auth_failures++;
2019 /* If we are primary router and we have backup router configured
2020 but it has not connected to use yet, do not accept any other
2022 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2023 !server->backup_router) {
2024 SilcServerConfigRouter *router;
2025 router = silc_server_config_get_backup_router(server);
2026 if (router && strcmp(server->config->server_info->primary->server_ip,
2028 silc_server_find_socket_by_host(server,
2030 router->backup_replace_ip, 0)) {
2031 SILC_LOG_INFO(("Will not accept connections because we do "
2032 "not have backup router connection established"));
2033 silc_server_disconnect_remote(server, sock,
2034 SILC_STATUS_ERR_PERM_DENIED,
2035 "We do not have connection to backup "
2036 "router established, try later");
2037 server->stat.auth_failures++;
2039 /* From here on, wait 20 seconds for the backup router to appear. */
2040 silc_schedule_task_add_timeout(server->schedule,
2041 silc_server_backup_router_wait,
2042 (void *)server, 20, 0);
2047 SILC_LOG_DEBUG(("Remote host is client"));
2048 SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2051 /* Add the client to the client ID cache. The nickname and Client ID
2052 and other information is created after we have received NEW_CLIENT
2053 packet from client. */
2054 client = silc_idlist_add_client(server->local_list,
2055 NULL, NULL, NULL, NULL, NULL, sock);
2057 SILC_LOG_ERROR(("Could not add new client to cache"));
2058 server->stat.auth_failures++;
2059 silc_server_disconnect_remote(server, sock,
2060 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2063 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2066 server->stat.my_clients++;
2067 server->stat.clients++;
2068 server->stat.cell_clients++;
2070 /* Get connection parameters */
2072 param = conn->param;
2074 if (!param->keepalive_secs)
2075 param->keepalive_secs = server->config->param.keepalive_secs;
2077 if (!param->qos && server->config->param.qos) {
2078 param->qos = server->config->param.qos;
2079 param->qos_rate_limit = server->config->param.qos_rate_limit;
2080 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2081 param->qos_limit_sec = server->config->param.qos_limit_sec;
2082 param->qos_limit_usec = server->config->param.qos_limit_usec;
2085 /* Check if to be anonymous connection */
2086 if (param->anonymous)
2087 client->mode |= SILC_UMODE_ANONYMOUS;
2090 /* Add public key to repository */
2091 if (!silc_server_get_public_key_by_client(server, client, NULL))
2092 silc_skr_add_public_key_simple(server->repository,
2093 entry->data.public_key,
2094 SILC_SKR_USAGE_IDENTIFICATION, client);
2096 id_entry = (void *)client;
2100 case SILC_CONN_SERVER:
2101 case SILC_CONN_ROUTER:
2103 SilcServerEntry new_server;
2104 SilcBool initiator = FALSE;
2105 SilcBool backup_local = FALSE;
2106 SilcBool backup_router = FALSE;
2107 char *backup_replace_ip = NULL;
2108 SilcUInt16 backup_replace_port = 0;
2109 SilcServerConfigServer *sconn = entry->sconfig.ref_ptr;
2110 SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2112 /* If we are backup router and this is incoming server connection
2113 and we do not have connection to primary router, do not allow
2115 if (server->server_type == SILC_BACKUP_ROUTER &&
2116 entry->data.conn_type == SILC_CONN_SERVER &&
2117 !SILC_PRIMARY_ROUTE(server)) {
2118 SILC_LOG_INFO(("Will not accept server connection because we do "
2119 "not have primary router connection established"));
2120 silc_server_disconnect_remote(server, sock,
2121 SILC_STATUS_ERR_PERM_DENIED,
2122 "We do not have connection to primary "
2123 "router established, try later");
2124 server->stat.auth_failures++;
2128 if (entry->data.conn_type == SILC_CONN_ROUTER) {
2129 /* Verify whether this connection is after all allowed to connect */
2130 if (!silc_server_connection_allowed(server, sock,
2131 entry->data.conn_type,
2132 &server->config->param,
2133 rconn ? rconn->param : NULL,
2134 silc_connauth_get_ske(connauth))) {
2135 server->stat.auth_failures++;
2141 param = rconn->param;
2143 if (!param->keepalive_secs)
2144 param->keepalive_secs = server->config->param.keepalive_secs;
2146 if (!param->qos && server->config->param.qos) {
2147 param->qos = server->config->param.qos;
2148 param->qos_rate_limit = server->config->param.qos_rate_limit;
2149 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2150 param->qos_limit_sec = server->config->param.qos_limit_sec;
2151 param->qos_limit_usec = server->config->param.qos_limit_usec;
2155 initiator = rconn->initiator;
2156 backup_local = rconn->backup_local;
2157 backup_router = rconn->backup_router;
2158 backup_replace_ip = rconn->backup_replace_ip;
2159 backup_replace_port = rconn->backup_replace_port;
2163 if (entry->data.conn_type == SILC_CONN_SERVER) {
2164 /* Verify whether this connection is after all allowed to connect */
2165 if (!silc_server_connection_allowed(server, sock,
2166 entry->data.conn_type,
2167 &server->config->param,
2168 sconn ? sconn->param : NULL,
2169 silc_connauth_get_ske(connauth))) {
2170 server->stat.auth_failures++;
2175 param = sconn->param;
2177 if (!param->keepalive_secs)
2178 param->keepalive_secs = server->config->param.keepalive_secs;
2180 if (!param->qos && server->config->param.qos) {
2181 param->qos = server->config->param.qos;
2182 param->qos_rate_limit = server->config->param.qos_rate_limit;
2183 param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2184 param->qos_limit_sec = server->config->param.qos_limit_sec;
2185 param->qos_limit_usec = server->config->param.qos_limit_usec;
2189 backup_router = sconn->backup_router;
2193 /* If we are primary router and we have backup router configured
2194 but it has not connected to use yet, do not accept any other
2197 if (server->wait_backup && server->server_type == SILC_ROUTER &&
2198 !server->backup_router && !backup_router) {
2199 SilcServerConfigRouter *router;
2200 router = silc_server_config_get_backup_router(server);
2201 if (router && strcmp(server->config->server_info->primary->server_ip,
2203 silc_server_find_socket_by_host(server,
2205 router->backup_replace_ip, 0)) {
2206 SILC_LOG_INFO(("Will not accept connections because we do "
2207 "not have backup router connection established"));
2208 silc_server_disconnect_remote(server, sock,
2209 SILC_STATUS_ERR_PERM_DENIED,
2210 "We do not have connection to backup "
2211 "router established, try later");
2212 server->stat.auth_failures++;
2214 /* From here on, wait 20 seconds for the backup router to appear. */
2215 silc_schedule_task_add_timeout(server->schedule,
2216 silc_server_backup_router_wait,
2217 (void *)server, 20, 0);
2223 SILC_LOG_DEBUG(("Remote host is %s",
2224 entry->data.conn_type == SILC_CONN_SERVER ?
2225 "server" : (backup_router ?
2226 "backup router" : "router")));
2227 SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2228 entry->ip, entry->data.conn_type == SILC_CONN_SERVER ?
2229 "server" : (backup_router ?
2230 "backup router" : "router")));
2232 /* Add the server into server cache. The server name and Server ID
2233 is updated after we have received NEW_SERVER packet from the
2234 server. We mark ourselves as router for this server if we really
2237 silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ?
2238 server->local_list : (backup_router ?
2239 server->local_list :
2240 server->global_list)),
2242 (entry->data.conn_type == SILC_CONN_SERVER ?
2243 SILC_SERVER : SILC_ROUTER),
2245 (entry->data.conn_type == SILC_CONN_SERVER ?
2246 server->id_entry : (backup_router ?
2247 server->id_entry : NULL)),
2250 SILC_LOG_ERROR(("Could not add new server to cache"));
2251 silc_server_disconnect_remote(server, sock,
2252 SILC_STATUS_ERR_AUTH_FAILED, NULL);
2253 server->stat.auth_failures++;
2256 entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2258 id_entry = (void *)new_server;
2260 /* If the incoming connection is router and marked as backup router
2261 then add it to be one of our backups */
2262 if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2263 /* Change it back to SERVER type since that's what it really is. */
2265 entry->data.conn_type = SILC_CONN_SERVER;
2266 new_server->server_type = SILC_BACKUP_ROUTER;
2268 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2269 ("Backup router %s is now online",
2272 /* Remove the backup waiting with timeout */
2273 silc_schedule_task_add_timeout(server->schedule,
2274 silc_server_backup_router_wait,
2275 (void *)server, 10, 0);
2279 if (entry->data.conn_type == SILC_CONN_SERVER) {
2280 server->stat.my_servers++;
2281 server->stat.servers++;
2283 server->stat.my_routers++;
2284 server->stat.routers++;
2287 /* Check whether this connection is to be our primary router connection
2288 if we do not already have the primary route. */
2289 if (!backup_router &&
2290 server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2291 if (silc_server_config_is_primary_route(server) && !initiator)
2294 SILC_LOG_DEBUG(("We are not standalone server anymore"));
2295 server->standalone = FALSE;
2296 if (!server->id_entry->router) {
2297 server->id_entry->router = id_entry;
2298 server->router = id_entry;
2310 /* Add connection to server->conns so that we know we have connection
2312 sconn = silc_calloc(1, sizeof(*sconn));
2313 sconn->server = server;
2315 sconn->remote_host = strdup(hostname);
2316 sconn->remote_port = port;
2317 silc_dlist_add(server->conns, sconn);
2318 idata->sconn = sconn;
2320 /* Add the common data structure to the ID entry. */
2321 silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2322 silc_packet_set_context(sock, id_entry);
2324 /* Connection has been fully established now. Everything is ok. */
2325 SILC_LOG_DEBUG(("New connection authenticated"));
2329 /* Perform keepalive. */
2330 if (param->keepalive_secs)
2331 silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
2332 silc_server_perform_heartbeat,
2335 /* Perform Quality of Service */
2337 silc_socket_set_qos(sock, param->qos_rate_limit, param->qos_bytes_limit,
2338 param->qos_limit_sec, param->qos_limit_usec,
2342 silc_server_config_unref(&entry->cconfig);
2343 silc_server_config_unref(&entry->sconfig);
2344 silc_server_config_unref(&entry->rconfig);
2348 silc_ske_free(silc_connauth_get_ske(connauth));
2349 silc_connauth_free(connauth);
2352 /* SKE completion callback. We set the new keys into use here. */
2355 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2356 SilcSKESecurityProperties prop,
2357 SilcSKEKeyMaterial keymat,
2358 SilcSKERekeyMaterial rekey,
2361 SilcPacketStream sock = context;
2362 SilcUnknownEntry entry = silc_packet_get_context(sock);
2363 SilcIDListData idata = (SilcIDListData)entry;
2364 SilcServer server = entry->server;
2365 SilcConnAuth connauth;
2366 SilcCipher send_key, receive_key;
2367 SilcHmac hmac_send, hmac_receive;
2370 if (status != SILC_SKE_STATUS_OK) {
2372 SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2373 silc_ske_map_status(status), entry->hostname, entry->ip));
2375 silc_server_disconnect_remote(server, sock,
2376 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2380 SILC_LOG_DEBUG(("Setting keys into use"));
2382 /* Set the keys into use. The data will be encrypted after this. */
2383 if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2384 &hmac_send, &hmac_receive, &hash)) {
2385 /* Error setting keys */
2387 silc_server_disconnect_remote(server, sock,
2388 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2391 silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2392 hmac_receive, FALSE);
2394 idata->rekey = rekey;
2395 idata->public_key = silc_pkcs_public_key_copy(prop->public_key);
2397 SILC_LOG_DEBUG(("Starting connection authentication"));
2398 server->stat.auth_attempts++;
2400 connauth = silc_connauth_alloc(server->schedule, ske,
2401 server->config->conn_auth_timeout);
2403 /** Error allocating auth protocol */
2405 silc_server_disconnect_remote(server, sock,
2406 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2410 /* Start connection authentication */
2411 silc_connauth_responder(connauth, silc_server_accept_get_auth,
2412 silc_server_accept_auth_compl, sock);
2415 /* Accept new TCP connection */
2417 static void silc_server_accept_new_connection(SilcNetStatus status,
2421 SilcServer server = context;
2422 SilcPacketStream packet_stream;
2423 SilcServerConfigClient *cconfig = NULL;
2424 SilcServerConfigServer *sconfig = NULL;
2425 SilcServerConfigRouter *rconfig = NULL;
2426 SilcServerConfigDeny *deny;
2427 SilcUnknownEntry entry;
2429 SilcSKEParamsStruct params;
2430 char *hostname, *ip;
2433 SILC_LOG_DEBUG(("Accepting new connection"));
2435 /* Check for maximum allowed connections */
2436 server->stat.conn_attempts++;
2438 if (silc_server_num_connections(server) >
2439 server->config->param.connections_max) {
2440 SILC_LOG_ERROR(("Refusing connection, server is full"));
2441 server->stat.conn_failures++;
2442 silc_stream_destroy(stream);
2447 /* Get hostname, IP and port */
2448 if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2449 (const char **)&ip, &port)) {
2450 /* Bad socket stream */
2451 server->stat.conn_failures++;
2452 silc_stream_destroy(stream);
2456 /* Create packet stream */
2457 packet_stream = silc_packet_stream_create(server->packet_engine,
2458 server->schedule, stream);
2459 if (!packet_stream) {
2460 SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2461 server->stat.conn_failures++;
2462 silc_stream_destroy(stream);
2465 server->stat.conn_num++;
2467 /* Set source ID to packet stream */
2468 if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id,
2471 server->stat.conn_failures++;
2472 silc_packet_stream_destroy(packet_stream);
2476 /* Check whether this connection is denied to connect to us. */
2477 deny = silc_server_config_find_denied(server, ip);
2479 deny = silc_server_config_find_denied(server, hostname);
2481 /* The connection is denied */
2482 SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2483 silc_server_disconnect_remote(server, packet_stream,
2484 SILC_STATUS_ERR_BANNED_FROM_SERVER,
2489 /* Check whether we have configured this sort of connection at all. We
2490 have to check all configurations since we don't know what type of
2491 connection this is. */
2492 if (!(cconfig = silc_server_config_find_client(server, ip)))
2493 cconfig = silc_server_config_find_client(server, hostname);
2494 if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2495 sconfig = silc_server_config_find_server_conn(server, hostname);
2496 if (server->server_type == SILC_ROUTER)
2497 if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2498 rconfig = silc_server_config_find_router_conn(server, hostname, port);
2499 if (!cconfig && !sconfig && !rconfig) {
2500 SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2501 server->stat.conn_failures++;
2502 silc_server_disconnect_remote(server, packet_stream,
2503 SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2507 /* The connection is allowed */
2508 entry = silc_calloc(1, sizeof(*entry));
2510 server->stat.conn_failures++;
2511 silc_server_disconnect_remote(server, packet_stream,
2512 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2515 entry->hostname = hostname;
2518 entry->server = server;
2519 silc_packet_set_context(packet_stream, entry);
2521 silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2522 silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2523 silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2525 /* Take flags for key exchange. Since we do not know what type of connection
2526 this is, we go through all found configurations and use the global ones
2527 as well. This will result always into strictest key exchange flags. */
2528 memset(¶ms, 0, sizeof(params));
2529 SILC_GET_SKE_FLAGS(cconfig, params.flags);
2530 SILC_GET_SKE_FLAGS(sconfig, params.flags);
2531 SILC_GET_SKE_FLAGS(rconfig, params.flags);
2532 if (server->config->param.key_exchange_pfs)
2533 params.flags |= SILC_SKE_SP_FLAG_PFS;
2535 SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2536 server->stat.conn_attempts++;
2538 /* Start SILC Key Exchange protocol */
2539 SILC_LOG_DEBUG(("Starting key exchange protocol"));
2540 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2541 server->public_key, server->private_key,
2544 server->stat.conn_failures++;
2545 silc_server_disconnect_remote(server, packet_stream,
2546 SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2549 silc_ske_set_callbacks(ske, silc_server_verify_key,
2550 silc_server_accept_completed, packet_stream);
2552 /* Start key exchange protocol */
2553 params.version = silc_version_string;
2554 params.timeout_secs = server->config->key_exchange_timeout;
2555 silc_ske_responder(ske, packet_stream, ¶ms);
2559 /********************************** Rekey ***********************************/
2561 /* Initiator rekey completion callback */
2563 static void silc_server_rekey_completion(SilcSKE ske,
2564 SilcSKEStatus status,
2565 const SilcSKESecurityProperties prop,
2566 const SilcSKEKeyMaterial keymat,
2567 SilcSKERekeyMaterial rekey,
2570 SilcPacketStream sock = context;
2571 SilcIDListData idata = silc_packet_get_context(sock);
2572 SilcServer server = idata->sconn->server;
2574 idata->sconn->op = NULL;
2575 if (status != SILC_SKE_STATUS_OK) {
2576 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2577 idata->sconn->remote_host));
2581 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2582 idata->sconn->remote_host, idata->sconn->remote_port,
2583 SILC_CONNTYPE_STRING(idata->conn_type)));
2585 /* Save rekey data for next rekey */
2586 idata->rekey = rekey;
2588 /* Register new rekey timeout */
2589 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2590 sock, idata->sconn->rekey_timeout, 0);
2593 /* Rekey callback. Start rekey as initiator */
2595 SILC_TASK_CALLBACK(silc_server_do_rekey)
2597 SilcServer server = app_context;
2598 SilcPacketStream sock = context;
2599 SilcIDListData idata = silc_packet_get_context(sock);
2602 /* Do not execute rekey with disabled connections */
2603 if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2606 /* If another protocol is active do not start rekey */
2607 if (idata->sconn->op) {
2608 SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2609 silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2614 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2615 idata->sconn->remote_host, idata->sconn->remote_port,
2616 SILC_CONNTYPE_STRING(idata->conn_type)));
2619 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2620 server->public_key, server->private_key, sock);
2624 /* Set SKE callbacks */
2625 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2628 idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2631 /* Responder rekey completion callback */
2634 silc_server_rekey_resp_completion(SilcSKE ske,
2635 SilcSKEStatus status,
2636 const SilcSKESecurityProperties prop,
2637 const SilcSKEKeyMaterial keymat,
2638 SilcSKERekeyMaterial rekey,
2641 SilcPacketStream sock = context;
2642 SilcIDListData idata = silc_packet_get_context(sock);
2644 idata->sconn->op = NULL;
2645 if (status != SILC_SKE_STATUS_OK) {
2646 SILC_LOG_ERROR(("Error during rekey protocol with %s",
2647 idata->sconn->remote_host));
2651 SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2652 idata->sconn->remote_host, idata->sconn->remote_port,
2653 SILC_CONNTYPE_STRING(idata->conn_type)));
2655 /* Save rekey data for next rekey */
2656 idata->rekey = rekey;
2659 /* Start rekey as responder */
2661 static void silc_server_rekey(SilcServer server, SilcPacketStream sock,
2664 SilcIDListData idata = silc_packet_get_context(sock);
2667 SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2668 idata->sconn->remote_host, idata->sconn->remote_port,
2669 SILC_CONNTYPE_STRING(idata->conn_type)));
2672 ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2673 server->public_key, server->private_key, sock);
2675 silc_packet_free(packet);
2679 /* Set SKE callbacks */
2680 silc_ske_set_callbacks(ske, NULL, silc_server_rekey_resp_completion, sock);
2683 idata->sconn->op = silc_ske_rekey_responder(ske, sock, idata->rekey,
2688 /****************************** Disconnection *******************************/
2690 /* Destroys packet stream. */
2692 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2694 silc_packet_stream_destroy(context);
2697 /* Closes connection to socket connection */
2699 void silc_server_close_connection(SilcServer server,
2700 SilcPacketStream sock)
2702 SilcIDListData idata = silc_packet_get_context(sock);
2704 const char *hostname;
2708 /* If any protocol is active cancel its execution. It will call
2709 the final callback which will finalize the disconnection. */
2710 if (sock->protocol && sock->protocol->protocol &&
2711 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
2712 SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
2713 silc_protocol_cancel(sock->protocol, server->schedule);
2714 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2715 silc_protocol_execute_final(sock->protocol, server->schedule);
2716 sock->protocol = NULL;
2721 memset(tmp, 0, sizeof(tmp));
2722 // silc_socket_get_error(sock, tmp, sizeof(tmp));
2723 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2724 NULL, &hostname, NULL, &port);
2725 SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2726 SILC_CONNTYPE_STRING(idata->conn_type),
2727 tmp[0] ? tmp : ""));
2729 // silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2731 /* Close connection with timeout */
2732 server->stat.conn_num--;
2733 silc_schedule_task_add_timeout(server->schedule,
2734 silc_server_close_connection_final,
2738 /* Sends disconnect message to remote connection and disconnects the
2741 void silc_server_disconnect_remote(SilcServer server,
2742 SilcPacketStream sock,
2743 SilcStatus status, ...)
2745 unsigned char buf[512];
2752 SILC_LOG_DEBUG(("Disconnecting remote host"));
2754 va_start(ap, status);
2755 cp = va_arg(ap, char *);
2757 silc_vsnprintf(buf, sizeof(buf), cp, ap);
2760 /* Send SILC_PACKET_DISCONNECT */
2761 silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2762 SILC_STR_UI_CHAR(status),
2763 SILC_STR_UI8_STRING(cp ? buf : NULL),
2766 /* Close connection */
2767 silc_server_close_connection(server, sock);
2770 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2772 SilcClientEntry client = context;
2774 assert(!silc_hash_table_count(client->channels));
2776 silc_idlist_del_data(client);
2777 // silc_idcache_purge_by_context(server->local_list->clients, client);
2780 /* Frees client data and notifies about client's signoff. */
2782 void silc_server_free_client_data(SilcServer server,
2783 SilcPacketStream sock,
2784 SilcClientEntry client,
2786 const char *signoff)
2788 SILC_LOG_DEBUG(("Freeing client data"));
2791 /* Check if anyone is watching this nickname */
2792 if (server->server_type == SILC_ROUTER)
2793 silc_server_check_watcher_list(server, client, NULL,
2794 SILC_NOTIFY_TYPE_SIGNOFF);
2796 /* Send SIGNOFF notify to routers. */
2798 silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2799 SILC_BROADCAST(server), client->id,
2803 /* Remove client from all channels */
2805 silc_server_remove_from_channels(server, NULL, client,
2806 TRUE, (char *)signoff, TRUE, FALSE);
2808 silc_server_remove_from_channels(server, NULL, client,
2809 FALSE, NULL, FALSE, FALSE);
2811 /* Remove this client from watcher list if it is */
2812 silc_server_del_from_watcher_list(server, client);
2814 /* Remove this client from the public key hash list */
2815 if (client->data.public_key)
2816 silc_hash_table_del_by_context(server->pk_hash,
2817 client->data.public_key, client);
2819 /* Update statistics */
2820 server->stat.my_clients--;
2821 server->stat.clients--;
2822 if (server->stat.cell_clients)
2823 server->stat.cell_clients--;
2824 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2825 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2826 silc_schedule_task_del_by_context(server->schedule, client);
2828 /* We will not delete the client entry right away. We will take it
2829 into history (for WHOWAS command) for 5 minutes, unless we're
2830 shutting down server. */
2831 if (!server->server_shutdown) {
2832 silc_schedule_task_add_timeout(server->schedule,
2833 silc_server_free_client_data_timeout,
2835 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2836 client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
2838 client->router = NULL;
2839 client->connection = NULL;
2841 /* Delete directly since we're shutting down server */
2842 silc_idlist_del_data(client);
2843 silc_idlist_del_client(server->local_list, client);
2847 /* Frees user_data pointer from socket connection object. This also sends
2848 appropriate notify packets to the network to inform about leaving
2851 void silc_server_free_sock_user_data(SilcServer server,
2852 SilcPacketStream sock,
2853 const char *signoff_message)
2855 SilcIDListData idata = silc_packet_get_context(sock);
2860 switch (idata->conn_type) {
2861 case SILC_CONN_CLIENT:
2863 SilcClientEntry client_entry = (SilcClientEntry)idata;
2864 silc_server_free_client_data(server, sock, client_entry, TRUE,
2869 case SILC_CONN_SERVER:
2870 case SILC_CONN_ROUTER:
2872 SilcServerEntry user_data = (SilcServerEntry)idata;
2873 SilcServerEntry backup_router = NULL;
2875 SILC_LOG_DEBUG(("Freeing server data"));
2878 backup_router = silc_server_backup_get(server, user_data->id);
2880 if (!server->backup_router && server->server_type == SILC_ROUTER &&
2881 backup_router == server->id_entry &&
2882 idata->conn_type != SILC_CONN_ROUTER)
2883 backup_router = NULL;
2885 if (server->server_shutdown || server->backup_noswitch)
2886 backup_router = NULL;
2888 /* If this was our primary router connection then we're lost to
2889 the outside world. */
2890 if (server->router == user_data) {
2891 /* Check whether we have a backup router connection */
2892 if (!backup_router || backup_router == user_data) {
2893 if (!server->no_reconnect)
2894 silc_server_create_connections(server);
2895 server->id_entry->router = NULL;
2896 server->router = NULL;
2897 server->standalone = TRUE;
2898 server->backup_primary = FALSE;
2899 backup_router = NULL;
2901 if (server->id_entry != backup_router) {
2902 SILC_LOG_INFO(("New primary router is backup router %s",
2903 backup_router->server_name));
2904 server->id_entry->router = backup_router;
2905 server->router = backup_router;
2906 server->router_connect = time(0);
2907 server->backup_primary = TRUE;
2908 backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
2910 /* Send START_USE to backup router to indicate we have switched */
2911 silc_server_backup_send_start_use(server,
2912 backup_router->connection,
2915 SILC_LOG_INFO(("We are now new primary router in this cell"));
2916 server->id_entry->router = NULL;
2917 server->router = NULL;
2918 server->standalone = TRUE;
2921 /* We stop here to take a breath */
2925 if (server->backup_router) {
2926 server->server_type = SILC_ROUTER;
2928 /* We'll need to constantly try to reconnect to the primary
2929 router so that we'll see when it comes back online. */
2930 silc_server_backup_reconnect(server, sock->ip, sock->port,
2931 silc_server_backup_connected,
2936 /* Mark this connection as replaced */
2937 silc_server_backup_replaced_add(server, user_data->id,
2940 } else if (backup_router) {
2941 SILC_LOG_INFO(("Enabling the use of backup router %s",
2942 backup_router->server_name));
2944 /* Mark this connection as replaced */
2945 silc_server_backup_replaced_add(server, user_data->id,
2947 } else if (server->server_type == SILC_SERVER &&
2948 idata->conn_type == SILC_CONN_ROUTER) {
2949 /* Reconnect to the router (backup) */
2950 if (!server->no_reconnect)
2951 silc_server_create_connections(server);
2954 if (user_data->server_name)
2955 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2956 ("Server %s signoff", user_data->server_name));
2958 if (!backup_router) {
2959 /* Remove all servers that are originated from this server, and
2960 remove the clients of those servers too. */
2961 silc_server_remove_servers_by_server(server, user_data, TRUE);
2964 /* Remove the clients that this server owns as they will become
2965 invalid now too. For backup router the server is actually
2966 coming from the primary router, so mark that as the owner
2968 if (server->server_type == SILC_BACKUP_ROUTER &&
2969 sock->type == SILC_CONN_SERVER)
2970 silc_server_remove_clients_by_server(server, server->router,
2974 silc_server_remove_clients_by_server(server, user_data,
2977 /* Remove channels owned by this server */
2978 if (server->server_type == SILC_SERVER)
2979 silc_server_remove_channels_by_server(server, user_data);
2981 /* Enable local server connections that may be disabled */
2982 silc_server_local_servers_toggle_enabled(server, TRUE);
2984 /* Update the client entries of this server to the new backup
2985 router. If we are the backup router we also resolve the real
2986 servers for the clients. After updating is over this also
2987 removes the clients that this server explicitly owns. */
2988 silc_server_update_clients_by_server(server, user_data,
2989 backup_router, TRUE);
2991 /* If we are router and just lost our primary router (now standlaone)
2992 we remove everything that was behind it, since we don't know
2994 if (server->server_type == SILC_ROUTER && server->standalone)
2995 /* Remove all servers that are originated from this server, and
2996 remove the clients of those servers too. */
2997 silc_server_remove_servers_by_server(server, user_data, TRUE);
2999 /* Finally remove the clients that are explicitly owned by this
3000 server. They go down with the server. */
3001 silc_server_remove_clients_by_server(server, user_data,
3004 /* Update our server cache to use the new backup router too. */
3005 silc_server_update_servers_by_server(server, user_data, backup_router);
3006 if (server->server_type == SILC_SERVER)
3007 silc_server_update_channels_by_server(server, user_data,
3010 /* Send notify about primary router going down to local operators */
3011 if (server->backup_router)
3012 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3013 SILC_NOTIFY_TYPE_NONE,
3014 ("%s switched to backup router %s "
3015 "(we are primary router now)",
3016 server->server_name, server->server_name));
3017 else if (server->router)
3018 SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
3019 SILC_NOTIFY_TYPE_NONE,
3020 ("%s switched to backup router %s",
3021 server->server_name,
3022 server->router->server_name));
3024 server->backup_noswitch = FALSE;
3026 /* Free the server entry */
3027 silc_server_backup_del(server, user_data);
3028 silc_server_backup_replaced_del(server, user_data);
3029 silc_idlist_del_data(user_data);
3030 if (!silc_idlist_del_server(server->local_list, user_data))
3031 silc_idlist_del_server(server->global_list, user_data);
3032 if (idata->conn_type == SILC_CONN_SERVER) {
3033 server->stat.my_servers--;
3034 server->stat.servers--;
3036 server->stat.my_routers--;
3037 server->stat.routers--;
3039 if (server->server_type == SILC_ROUTER)
3040 server->stat.cell_servers--;
3042 if (backup_router && backup_router != server->id_entry) {
3043 /* Announce all of our stuff that was created about 5 minutes ago.
3044 The backup router knows all the other stuff already. */
3045 if (server->server_type == SILC_ROUTER)
3046 silc_server_announce_servers(server, FALSE, time(0) - 300,
3047 backup_router->connection);
3049 /* Announce our clients and channels to the router */
3050 silc_server_announce_clients(server, time(0) - 300,
3051 backup_router->connection);
3052 silc_server_announce_channels(server, time(0) - 300,
3053 backup_router->connection);
3060 SilcUnknownEntry entry = (SilcUnknownEntry)idata;
3062 SILC_LOG_DEBUG(("Freeing unknown connection data"));
3064 silc_idlist_del_data(idata);
3071 /* Removes client from all channels it has joined. This is used when client
3072 connection is disconnected. If the client on a channel is last, the
3073 channel is removed as well. This sends the SIGNOFF notify types. */
3075 void silc_server_remove_from_channels(SilcServer server,
3076 SilcPacketStream sock,
3077 SilcClientEntry client,
3079 const char *signoff_message,
3083 SilcChannelEntry channel;
3084 SilcChannelClientEntry chl;
3085 SilcHashTableList htl;
3086 SilcBuffer clidp = NULL;
3091 if (notify && !client->id)
3094 SILC_LOG_DEBUG(("Removing client %s from joined channels",
3095 notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3098 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3103 /* Remove the client from all channels. The client is removed from
3104 the channels' user list. */
3105 silc_hash_table_list(client->channels, &htl);
3106 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3107 channel = chl->channel;
3109 /* Remove channel if this is last client leaving the channel, unless
3110 the channel is permanent. */
3111 if (server->server_type != SILC_SERVER &&
3112 silc_hash_table_count(channel->user_list) < 2) {
3113 silc_server_channel_delete(server, channel);
3117 silc_hash_table_del(client->channels, channel);
3118 silc_hash_table_del(channel->user_list, client);
3119 channel->user_count--;
3121 /* If there is no global users on the channel anymore mark the channel
3122 as local channel. Do not check if the removed client is local client. */
3123 if (server->server_type == SILC_SERVER && channel->global_users &&
3124 chl->client->router && !silc_server_channel_has_global(channel))
3125 channel->global_users = FALSE;
3127 memset(chl, 'A', sizeof(*chl));
3130 /* Update statistics */
3131 if (SILC_IS_LOCAL(client))
3132 server->stat.my_chanclients--;
3133 if (server->server_type == SILC_ROUTER) {
3134 server->stat.cell_chanclients--;
3135 server->stat.chanclients--;
3138 /* If there is not at least one local user on the channel then we don't
3139 need the channel entry anymore, we can remove it safely, unless the
3140 channel is permanent channel */
3141 if (server->server_type == SILC_SERVER &&
3142 !silc_server_channel_has_local(channel)) {
3143 /* Notify about leaving client if this channel has global users. */
3144 if (notify && channel->global_users)
3145 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3146 SILC_NOTIFY_TYPE_SIGNOFF,
3147 signoff_message ? 2 : 1,
3148 clidp->data, silc_buffer_len(clidp),
3149 signoff_message, signoff_message ?
3150 strlen(signoff_message) : 0);
3152 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3153 silc_server_channel_delete(server, channel);
3157 /* Send notify to channel about client leaving SILC and channel too */
3159 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3160 SILC_NOTIFY_TYPE_SIGNOFF,
3161 signoff_message ? 2 : 1,
3162 clidp->data, silc_buffer_len(clidp),
3163 signoff_message, signoff_message ?
3164 strlen(signoff_message) : 0);
3166 if (killed && clidp) {
3167 /* Remove the client from channel's invite list */
3168 if (channel->invite_list &&
3169 silc_hash_table_count(channel->invite_list)) {
3171 SilcArgumentPayload iargs;
3172 ab = silc_argument_payload_encode_one(NULL, clidp->data,
3173 silc_buffer_len(clidp), 3);
3174 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3175 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3176 silc_buffer_free(ab);
3177 silc_argument_payload_free(iargs);
3181 /* Don't create keys if we are shutting down */
3182 if (server->server_shutdown)
3185 /* Re-generate channel key if needed */
3186 if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3187 if (!silc_server_create_channel_key(server, channel, 0))
3190 /* Send the channel key to the channel. The key of course is not sent
3191 to the client who was removed from the channel. */
3192 silc_server_send_channel_key(server, client->connection, channel,
3193 server->server_type == SILC_ROUTER ?
3194 FALSE : !server->standalone);
3198 silc_hash_table_list_reset(&htl);
3200 silc_buffer_free(clidp);
3203 /* Removes client from one channel. This is used for example when client
3204 calls LEAVE command to remove itself from the channel. Returns TRUE
3205 if channel still exists and FALSE if the channel is removed when
3206 last client leaves the channel. If `notify' is FALSE notify messages
3209 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3210 SilcPacketStream sock,
3211 SilcChannelEntry channel,
3212 SilcClientEntry client,
3215 SilcChannelClientEntry chl;
3218 SILC_LOG_DEBUG(("Removing %s from channel %s",
3219 silc_id_render(client->id, SILC_ID_CLIENT),
3220 channel->channel_name));
3222 /* Get the entry to the channel, if this client is not on the channel
3224 if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3227 /* Remove channel if this is last client leaving the channel, unless
3228 the channel is permanent. */
3229 if (server->server_type != SILC_SERVER &&
3230 silc_hash_table_count(channel->user_list) < 2) {
3231 silc_server_channel_delete(server, channel);
3235 silc_hash_table_del(client->channels, channel);
3236 silc_hash_table_del(channel->user_list, client);
3237 channel->user_count--;
3239 /* If there is no global users on the channel anymore mark the channel
3240 as local channel. Do not check if the client is local client. */
3241 if (server->server_type == SILC_SERVER && channel->global_users &&
3242 chl->client->router && !silc_server_channel_has_global(channel))
3243 channel->global_users = FALSE;
3245 memset(chl, 'O', sizeof(*chl));
3248 /* Update statistics */
3249 if (SILC_IS_LOCAL(client))
3250 server->stat.my_chanclients--;
3251 if (server->server_type == SILC_ROUTER) {
3252 server->stat.cell_chanclients--;
3253 server->stat.chanclients--;
3256 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3260 /* If there is not at least one local user on the channel then we don't
3261 need the channel entry anymore, we can remove it safely, unless the
3262 channel is permanent channel */
3263 if (server->server_type == SILC_SERVER &&
3264 !silc_server_channel_has_local(channel)) {
3265 /* Notify about leaving client if this channel has global users. */
3266 if (notify && channel->global_users)
3267 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3268 SILC_NOTIFY_TYPE_LEAVE, 1,
3269 clidp->data, silc_buffer_len(clidp));
3271 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3272 silc_server_channel_delete(server, channel);
3273 silc_buffer_free(clidp);
3277 /* Send notify to channel about client leaving the channel */
3279 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3280 SILC_NOTIFY_TYPE_LEAVE, 1,
3281 clidp->data, silc_buffer_len(clidp));
3283 silc_buffer_free(clidp);
3288 /* Timeout callback. This is called if connection is idle or for some
3289 other reason is not responding within some period of time. This
3290 disconnects the remote end. */
3292 SILC_TASK_CALLBACK(silc_server_timeout_remote)
3294 SilcServer server = (SilcServer)context;
3295 SilcPacketStream sock = server->sockets[fd];
3297 SILC_LOG_DEBUG(("Start"));
3302 SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
3303 sock->hostname, sock->ip));
3305 /* If we have protocol active we must assure that we call the protocol's
3306 final callback so that all the memory is freed. */
3307 if (sock->protocol && sock->protocol->protocol &&
3308 sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3309 protocol = sock->protocol->protocol->type;
3310 silc_protocol_cancel(sock->protocol, server->schedule);
3311 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3312 silc_protocol_execute_final(sock->protocol, server->schedule);
3313 sock->protocol = NULL;
3317 silc_server_disconnect_remote(server, sock,
3319 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3320 SILC_STATUS_ERR_AUTH_FAILED :
3321 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3322 "Connection timeout");
3324 if (sock->user_data)
3325 silc_server_free_sock_user_data(server, sock, NULL);
3329 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3330 function may be used only by router. In real SILC network all channels
3331 are created by routers thus this function is never used by normal
3334 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3335 SilcServerID *router_id,
3341 SilcChannelID *channel_id;
3342 SilcChannelEntry entry;
3343 SilcCipher send_key, receive_key;
3346 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3349 cipher = SILC_DEFAULT_CIPHER;
3351 hmac = SILC_DEFAULT_HMAC;
3353 /* Allocate cipher */
3354 if (!silc_cipher_alloc(cipher, &send_key))
3356 if (!silc_cipher_alloc(cipher, &receive_key)) {
3357 silc_cipher_free(send_key);
3362 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3363 silc_cipher_free(send_key);
3364 silc_cipher_free(receive_key);
3368 channel_name = strdup(channel_name);
3370 /* Create the channel ID */
3371 if (!silc_id_create_channel_id(server, router_id, server->rng,
3373 silc_free(channel_name);
3374 silc_cipher_free(send_key);
3375 silc_cipher_free(receive_key);
3376 silc_hmac_free(newhmac);
3380 /* Create the channel */
3381 entry = silc_idlist_add_channel(server->local_list, channel_name,
3382 SILC_CHANNEL_MODE_NONE, channel_id,
3383 NULL, send_key, receive_key, newhmac);
3385 silc_free(channel_name);
3386 silc_cipher_free(send_key);
3387 silc_cipher_free(receive_key);
3388 silc_hmac_free(newhmac);
3389 silc_free(channel_id);
3393 entry->cipher = strdup(cipher);
3394 entry->hmac_name = strdup(hmac);
3396 /* Now create the actual key material */
3397 if (!silc_server_create_channel_key(server, entry,
3398 silc_cipher_get_key_len(send_key) / 8)) {
3399 silc_idlist_del_channel(server->local_list, entry);
3403 /* Notify other routers about the new channel. We send the packet
3404 to our primary route. */
3406 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3407 channel_name, entry->id,
3408 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3411 /* Distribute to backup routers */
3412 if (broadcast && server->server_type == SILC_ROUTER) {
3414 unsigned char cid[32];
3415 SilcUInt32 name_len = strlen(channel_name);
3418 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3419 packet = silc_channel_payload_encode(channel_name, name_len,
3420 cid, id_len, entry->mode);
3421 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3422 packet->data, silc_buffer_len(packet), FALSE,
3424 silc_buffer_free(packet);
3427 server->stat.my_channels++;
3428 if (server->server_type == SILC_ROUTER) {
3429 server->stat.channels++;
3430 server->stat.cell_channels++;
3431 entry->users_resolved = TRUE;
3437 /* Same as above but creates the channel with Channel ID `channel_id. */
3440 silc_server_create_new_channel_with_id(SilcServer server,
3444 SilcChannelID *channel_id,
3447 SilcChannelEntry entry;
3448 SilcCipher send_key, receive_key;
3451 SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3454 cipher = SILC_DEFAULT_CIPHER;
3456 hmac = SILC_DEFAULT_HMAC;
3458 /* Allocate cipher */
3459 if (!silc_cipher_alloc(cipher, &send_key))
3461 if (!silc_cipher_alloc(cipher, &receive_key)) {
3462 silc_cipher_free(send_key);
3467 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3468 silc_cipher_free(send_key);
3469 silc_cipher_free(receive_key);
3473 channel_name = strdup(channel_name);
3475 /* Create the channel */
3476 entry = silc_idlist_add_channel(server->local_list, channel_name,
3477 SILC_CHANNEL_MODE_NONE, channel_id,
3478 NULL, send_key, receive_key, newhmac);
3480 silc_cipher_free(send_key);
3481 silc_cipher_free(receive_key);
3482 silc_hmac_free(newhmac);
3483 silc_free(channel_name);
3487 /* Now create the actual key material */
3488 if (!silc_server_create_channel_key(server, entry,
3489 silc_cipher_get_key_len(send_key) / 8)) {
3490 silc_idlist_del_channel(server->local_list, entry);
3494 /* Notify other routers about the new channel. We send the packet
3495 to our primary route. */
3497 silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3498 channel_name, entry->id,
3499 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3502 /* Distribute to backup routers */
3503 if (broadcast && server->server_type == SILC_ROUTER) {
3505 unsigned char cid[32];
3506 SilcUInt32 name_len = strlen(channel_name);
3509 silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3510 packet = silc_channel_payload_encode(channel_name, name_len,
3511 cid, id_len, entry->mode);
3512 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3513 packet->data, silc_buffer_len(packet), FALSE,
3515 silc_buffer_free(packet);
3518 server->stat.my_channels++;
3519 if (server->server_type == SILC_ROUTER) {
3520 server->stat.channels++;
3521 server->stat.cell_channels++;
3522 entry->users_resolved = TRUE;
3528 /* Channel's key re-key timeout callback. */
3530 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3532 SilcServer server = app_context;
3533 SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3537 /* Return now if we are shutting down */
3538 if (server->server_shutdown)
3541 if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3544 silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3547 /* Generates new channel key. This is used to create the initial channel key
3548 but also to re-generate new key for channel. If `key_len' is provided
3549 it is the bytes of the key length. */
3551 SilcBool silc_server_create_channel_key(SilcServer server,
3552 SilcChannelEntry channel,
3556 unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3559 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3560 SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3564 SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3566 if (!channel->send_key)
3567 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3568 channel->send_key = NULL;
3571 if (!channel->receive_key)
3572 if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3573 silc_cipher_free(channel->send_key);
3574 channel->send_key = channel->receive_key = NULL;
3580 else if (channel->key_len)
3581 len = channel->key_len / 8;
3583 len = silc_cipher_get_key_len(channel->send_key) / 8;
3585 /* Create channel key */
3586 for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3589 silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3590 silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3592 /* Remove old key if exists */
3594 memset(channel->key, 0, channel->key_len / 8);
3595 silc_free(channel->key);
3599 channel->key_len = len * 8;
3600 channel->key = silc_memdup(channel_key, len);
3601 memset(channel_key, 0, sizeof(channel_key));
3603 /* Generate HMAC key from the channel key data and set it */
3605 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3606 memset(channel->key, 0, channel->key_len / 8);
3607 silc_free(channel->key);
3608 silc_cipher_free(channel->send_key);
3609 silc_cipher_free(channel->receive_key);
3610 channel->send_key = channel->receive_key = NULL;
3613 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3614 silc_hmac_set_key(channel->hmac, hash,
3615 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3616 memset(hash, 0, sizeof(hash));
3618 if (server->server_type == SILC_ROUTER) {
3619 if (!channel->rekey)
3620 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3621 channel->rekey->channel = channel;
3622 channel->rekey->key_len = key_len;
3623 if (channel->rekey->task)
3624 silc_schedule_task_del(server->schedule, channel->rekey->task);
3626 channel->rekey->task =
3627 silc_schedule_task_add_timeout(server->schedule,
3628 silc_server_channel_key_rekey,
3629 (void *)channel->rekey,
3630 server->config->channel_rekey_secs, 0);
3636 /* Saves the channel key found in the encoded `key_payload' buffer. This
3637 function is used when we receive Channel Key Payload and also when we're
3638 processing JOIN command reply. Returns entry to the channel. */
3640 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3641 SilcBuffer key_payload,
3642 SilcChannelEntry channel)
3644 SilcChannelKeyPayload payload = NULL;
3646 unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3650 /* Decode channel key payload */
3651 payload = silc_channel_key_payload_parse(key_payload->data,
3652 silc_buffer_len(key_payload));
3654 SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3659 /* Get the channel entry */
3662 /* Get channel ID */
3663 tmp = silc_channel_key_get_id(payload, &tmp_len);
3664 if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3669 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3671 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3673 if (server->server_type == SILC_ROUTER)
3674 SILC_LOG_ERROR(("Received key for non-existent channel %s",
3675 silc_id_render(&id, SILC_ID_CHANNEL)));
3681 SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3683 tmp = silc_channel_key_get_key(payload, &tmp_len);
3689 cipher = silc_channel_key_get_cipher(payload, NULL);
3695 /* Remove old key if exists */
3697 memset(channel->key, 0, channel->key_len / 8);
3698 silc_free(channel->key);
3699 silc_cipher_free(channel->send_key);
3700 silc_cipher_free(channel->receive_key);
3703 /* Create new cipher */
3704 if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3705 channel->send_key = NULL;
3709 if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3710 silc_cipher_free(channel->send_key);
3711 channel->send_key = channel->receive_key = NULL;
3716 if (channel->cipher)
3717 silc_free(channel->cipher);
3718 channel->cipher = strdup(cipher);
3721 channel->key_len = tmp_len * 8;
3722 channel->key = silc_memdup(tmp, tmp_len);
3723 silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3724 silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3726 /* Generate HMAC key from the channel key data and set it */
3728 if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3729 memset(channel->key, 0, channel->key_len / 8);
3730 silc_free(channel->key);
3731 silc_cipher_free(channel->send_key);
3732 silc_cipher_free(channel->receive_key);
3733 channel->send_key = channel->receive_key = NULL;
3736 silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3737 silc_hmac_set_key(channel->hmac, hash,
3738 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3740 memset(hash, 0, sizeof(hash));
3741 memset(tmp, 0, tmp_len);
3743 if (server->server_type == SILC_ROUTER) {
3744 if (!channel->rekey)
3745 channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3746 channel->rekey->channel = channel;
3747 if (channel->rekey->task)
3748 silc_schedule_task_del(server->schedule, channel->rekey->task);
3750 channel->rekey->task =
3751 silc_schedule_task_add_timeout(server->schedule,
3752 silc_server_channel_key_rekey,
3753 (void *)channel->rekey,
3754 server->config->channel_rekey_secs, 0);
3759 silc_channel_key_payload_free(payload);
3764 /* Returns assembled of all servers in the given ID list. The packet's
3765 form is dictated by the New ID payload. */
3767 static void silc_server_announce_get_servers(SilcServer server,
3768 SilcServerEntry remote,
3770 SilcBuffer *servers,
3771 unsigned long creation_time)
3774 SilcIDCacheEntry id_cache;
3775 SilcServerEntry entry;
3778 /* Go through all clients in the list */
3779 if (silc_idcache_get_all(id_list->servers, &list)) {
3780 silc_list_start(list);
3781 while ((id_cache = silc_list_get(list))) {
3782 entry = (SilcServerEntry)id_cache->context;
3784 /* Do not announce the one we've sending our announcements and
3785 do not announce ourself. Also check the creation time if it's
3787 if ((entry == remote) || (entry == server->id_entry) ||
3788 (creation_time && entry->data.created < creation_time))
3791 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3793 *servers = silc_buffer_realloc(*servers,
3795 silc_buffer_truelen((*servers)) +
3796 silc_buffer_len(idp) :
3797 silc_buffer_len(idp)));
3798 silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3799 silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3800 silc_buffer_pull(*servers, silc_buffer_len(idp));
3801 silc_buffer_free(idp);
3807 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3813 p = silc_notify_payload_encode(notify, argc, ap);
3819 /* This function is used by router to announce existing servers to our
3820 primary router when we've connected to it. If `creation_time' is non-zero
3821 then only the servers that has been created after the `creation_time'
3822 will be announced. */
3824 void silc_server_announce_servers(SilcServer server, SilcBool global,
3825 unsigned long creation_time,
3826 SilcPacketStream remote)
3828 SilcBuffer servers = NULL;
3830 SILC_LOG_DEBUG(("Announcing servers"));
3832 /* Get servers in local list */
3833 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3834 server->local_list, &servers,
3838 /* Get servers in global list */
3839 silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3840 server->global_list, &servers,
3844 silc_buffer_push(servers, servers->data - servers->head);
3845 SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
3847 /* Send the packet */
3848 silc_server_packet_send(server, remote,
3849 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3850 servers->data, silc_buffer_len(servers));
3852 silc_buffer_free(servers);
3856 /* Returns assembled packet of all clients in the given ID list. The
3857 packet's form is dictated by the New ID Payload. */
3859 static void silc_server_announce_get_clients(SilcServer server,
3861 SilcBuffer *clients,
3863 unsigned long creation_time)
3866 SilcIDCacheEntry id_cache;
3867 SilcClientEntry client;
3870 unsigned char mode[4];
3872 /* Go through all clients in the list */
3873 if (silc_idcache_get_all(id_list->clients, &list)) {
3874 silc_list_start(list);
3875 while ((id_cache = silc_list_get(list))) {
3876 client = (SilcClientEntry)id_cache->context;
3878 if (creation_time && client->data.created < creation_time)
3880 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
3882 if (!client->connection && !client->router)
3885 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3887 *clients = silc_buffer_realloc(*clients,
3889 silc_buffer_truelen((*clients)) +
3890 silc_buffer_len(idp) :
3891 silc_buffer_len(idp)));
3892 silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3893 silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
3894 silc_buffer_pull(*clients, silc_buffer_len(idp));
3896 SILC_PUT32_MSB(client->mode, mode);
3898 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3899 2, idp->data, silc_buffer_len(idp),
3901 *umodes = silc_buffer_realloc(*umodes,
3903 silc_buffer_truelen((*umodes)) +
3904 silc_buffer_len(tmp) :
3905 silc_buffer_len(tmp)));
3906 silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3907 silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
3908 silc_buffer_pull(*umodes, silc_buffer_len(tmp));
3909 silc_buffer_free(tmp);
3911 silc_buffer_free(idp);
3916 /* This function is used to announce our existing clients to our router
3917 when we've connected to it. If `creation_time' is non-zero then only
3918 the clients that has been created after the `creation_time' will be
3921 void silc_server_announce_clients(SilcServer server,
3922 unsigned long creation_time,
3923 SilcPacketStream remote)
3925 SilcBuffer clients = NULL;
3926 SilcBuffer umodes = NULL;
3928 SILC_LOG_DEBUG(("Announcing clients"));
3930 /* Get clients in local list */
3931 silc_server_announce_get_clients(server, server->local_list,
3932 &clients, &umodes, creation_time);
3934 /* As router we announce our global list as well */
3935 if (server->server_type == SILC_ROUTER)
3936 silc_server_announce_get_clients(server, server->global_list,
3937 &clients, &umodes, creation_time);
3940 silc_buffer_push(clients, clients->data - clients->head);
3941 SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
3943 /* Send the packet */
3944 silc_server_packet_send(server, remote,
3945 SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3946 clients->data, silc_buffer_len(clients));
3948 silc_buffer_free(clients);
3952 silc_buffer_push(umodes, umodes->data - umodes->head);
3953 SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
3955 /* Send the packet */
3956 silc_server_packet_send(server, remote,
3957 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3958 umodes->data, silc_buffer_len(umodes));
3960 silc_buffer_free(umodes);
3964 /* Returns channel's topic for announcing it */
3966 void silc_server_announce_get_channel_topic(SilcServer server,
3967 SilcChannelEntry channel,
3972 if (channel->topic) {
3973 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3974 *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3976 silc_buffer_len(chidp),
3978 strlen(channel->topic));
3979 silc_buffer_free(chidp);
3983 /* Returns channel's invite and ban lists */
3985 void silc_server_announce_get_inviteban(SilcServer server,
3986 SilcChannelEntry channel,
3990 SilcBuffer list, idp, idp2, tmp2;
3992 SilcHashTableList htl;
3993 const unsigned char a[1] = { 0x03 };
3995 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
3997 /* Encode invite list */
3998 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
3999 list = silc_buffer_alloc_size(2);
4000 type = silc_hash_table_count(channel->invite_list);
4001 SILC_PUT16_MSB(type, list->data);
4002 silc_hash_table_list(channel->invite_list, &htl);
4003 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4004 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4006 silc_hash_table_list_reset(&htl);
4008 idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4010 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
4011 idp->data, silc_buffer_len(idp),
4012 channel->channel_name,
4013 strlen(channel->channel_name),
4014 idp2->data, silc_buffer_len(idp2),
4016 list->data, silc_buffer_len(list));
4017 silc_buffer_free(idp2);
4018 silc_buffer_free(list);
4021 /* Encode ban list */
4022 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4023 list = silc_buffer_alloc_size(2);
4024 type = silc_hash_table_count(channel->ban_list);
4025 SILC_PUT16_MSB(type, list->data);
4026 silc_hash_table_list(channel->ban_list, &htl);
4027 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4028 list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
4030 silc_hash_table_list_reset(&htl);
4033 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
4034 idp->data, silc_buffer_len(idp),
4036 list->data, silc_buffer_len(list));
4037 silc_buffer_free(list);
4040 silc_buffer_free(idp);
4043 /* Returns assembled packets for channel users of the `channel'. */
4045 void silc_server_announce_get_channel_users(SilcServer server,
4046 SilcChannelEntry channel,
4047 SilcBuffer *channel_modes,
4048 SilcBuffer *channel_users,
4049 SilcBuffer *channel_users_modes)
4051 SilcChannelClientEntry chl;
4052 SilcHashTableList htl;
4053 SilcBuffer chidp, clidp, csidp;
4054 SilcBuffer tmp, fkey = NULL, chpklist;
4056 unsigned char mode[4], ulimit[4];
4059 SILC_LOG_DEBUG(("Start"));
4061 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4062 csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4063 chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4066 SILC_PUT32_MSB(channel->mode, mode);
4067 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4068 SILC_PUT32_MSB(channel->user_limit, ulimit);
4069 hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4070 if (channel->founder_key)
4071 fkey = silc_public_key_payload_encode(channel->founder_key);
4073 silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4075 silc_buffer_len(csidp),
4078 hmac, hmac ? strlen(hmac) : 0,
4079 channel->passphrase,
4080 channel->passphrase ?
4081 strlen(channel->passphrase) : 0,
4082 fkey ? fkey->data : NULL,
4083 fkey ? silc_buffer_len(fkey) : 0,
4084 chpklist ? chpklist->data : NULL,
4086 silc_buffer_len(chpklist) : 0,
4088 SILC_CHANNEL_MODE_ULIMIT ?
4091 SILC_CHANNEL_MODE_ULIMIT ?
4092 sizeof(ulimit) : 0));
4093 len = silc_buffer_len(tmp);
4095 silc_buffer_realloc(*channel_modes,
4097 silc_buffer_truelen((*channel_modes)) + len : len));
4098 silc_buffer_pull_tail(*channel_modes,
4099 ((*channel_modes)->end -
4100 (*channel_modes)->data));
4101 silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4102 silc_buffer_pull(*channel_modes, len);
4103 silc_buffer_free(tmp);
4104 silc_buffer_free(fkey);
4107 /* Now find all users on the channel */
4108 silc_hash_table_list(channel->user_list, &htl);
4109 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4110 clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4113 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4115 silc_buffer_len(clidp),
4117 silc_buffer_len(chidp));
4118 len = silc_buffer_len(tmp);
4120 silc_buffer_realloc(*channel_users,
4122 silc_buffer_truelen((*channel_users)) + len : len));
4123 silc_buffer_pull_tail(*channel_users,
4124 ((*channel_users)->end -
4125 (*channel_users)->data));
4127 silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4128 silc_buffer_pull(*channel_users, len);
4129 silc_buffer_free(tmp);
4131 /* CUMODE notify for mode change on the channel */
4132 SILC_PUT32_MSB(chl->mode, mode);
4133 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4134 fkey = silc_public_key_payload_encode(channel->founder_key);
4135 tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4137 silc_buffer_len(csidp),
4140 silc_buffer_len(clidp),
4141 fkey ? fkey->data : NULL,
4142 fkey ? silc_buffer_len(fkey) : 0);
4143 len = silc_buffer_len(tmp);
4144 *channel_users_modes =
4145 silc_buffer_realloc(*channel_users_modes,
4146 (*channel_users_modes ?
4147 silc_buffer_truelen((*channel_users_modes)) +
4149 silc_buffer_pull_tail(*channel_users_modes,
4150 ((*channel_users_modes)->end -
4151 (*channel_users_modes)->data));
4153 silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4154 silc_buffer_pull(*channel_users_modes, len);
4155 silc_buffer_free(tmp);
4156 silc_buffer_free(fkey);
4158 silc_buffer_free(clidp);
4160 silc_hash_table_list_reset(&htl);
4161 silc_buffer_free(chidp);
4162 silc_buffer_free(csidp);
4165 /* Returns assembled packets for all channels and users on those channels
4166 from the given ID List. The packets are in the form dictated by the
4167 New Channel and New Channel User payloads. */
4169 void silc_server_announce_get_channels(SilcServer server,
4171 SilcBuffer *channels,
4172 SilcBuffer **channel_modes,
4173 SilcBuffer *channel_users,
4174 SilcBuffer **channel_users_modes,
4175 SilcUInt32 *channel_users_modes_c,
4176 SilcBuffer **channel_topics,
4177 SilcBuffer **channel_invites,
4178 SilcBuffer **channel_bans,
4179 SilcChannelID ***channel_ids,
4180 unsigned long creation_time)
4183 SilcIDCacheEntry id_cache;
4184 SilcChannelEntry channel;
4185 unsigned char cid[32];
4187 SilcUInt16 name_len;
4189 int i = *channel_users_modes_c;
4192 SILC_LOG_DEBUG(("Start"));
4194 /* Go through all channels in the list */
4195 if (silc_idcache_get_all(id_list->channels, &list)) {
4196 silc_list_start(list);
4197 while ((id_cache = silc_list_get(list))) {
4198 channel = (SilcChannelEntry)id_cache->context;
4200 if (creation_time && channel->created < creation_time)
4205 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4206 name_len = strlen(channel->channel_name);
4209 len = 4 + name_len + id_len + 4;
4211 silc_buffer_realloc(*channels,
4213 silc_buffer_truelen((*channels)) +
4215 silc_buffer_pull_tail(*channels,
4216 ((*channels)->end - (*channels)->data));
4217 silc_buffer_format(*channels,
4218 SILC_STR_UI_SHORT(name_len),
4219 SILC_STR_UI_XNSTRING(channel->channel_name,
4221 SILC_STR_UI_SHORT(id_len),
4222 SILC_STR_UI_XNSTRING(cid, id_len),
4223 SILC_STR_UI_INT(channel->mode),
4225 silc_buffer_pull(*channels, len);
4228 if (creation_time && channel->updated < creation_time)
4234 /* Channel user modes */
4235 *channel_users_modes = silc_realloc(*channel_users_modes,
4236 sizeof(**channel_users_modes) *
4238 (*channel_users_modes)[i] = NULL;
4239 *channel_modes = silc_realloc(*channel_modes,
4240 sizeof(**channel_modes) * (i + 1));
4241 (*channel_modes)[i] = NULL;
4242 *channel_ids = silc_realloc(*channel_ids,
4243 sizeof(**channel_ids) * (i + 1));
4244 (*channel_ids)[i] = NULL;
4245 silc_server_announce_get_channel_users(server, channel,
4246 &(*channel_modes)[i],
4248 &(*channel_users_modes)[i]);
4249 (*channel_ids)[i] = channel->id;
4251 /* Channel's topic */
4252 *channel_topics = silc_realloc(*channel_topics,
4253 sizeof(**channel_topics) * (i + 1));
4254 (*channel_topics)[i] = NULL;
4255 silc_server_announce_get_channel_topic(server, channel,
4256 &(*channel_topics)[i]);
4258 /* Channel's invite and ban list */
4259 *channel_invites = silc_realloc(*channel_invites,
4260 sizeof(**channel_invites) * (i + 1));
4261 (*channel_invites)[i] = NULL;
4262 *channel_bans = silc_realloc(*channel_bans,
4263 sizeof(**channel_bans) * (i + 1));
4264 (*channel_bans)[i] = NULL;
4265 silc_server_announce_get_inviteban(server, channel,
4266 &(*channel_invites)[i],
4267 &(*channel_bans)[i]);
4269 (*channel_users_modes_c)++;
4277 /* This function is used to announce our existing channels to our router
4278 when we've connected to it. This also announces the users on the
4279 channels to the router. If the `creation_time' is non-zero only the
4280 channels that was created after the `creation_time' are announced.
4281 Note that the channel users are still announced even if the `creation_time'
4284 void silc_server_announce_channels(SilcServer server,
4285 unsigned long creation_time,
4286 SilcPacketStream remote)
4288 SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4289 SilcBuffer *channel_users_modes = NULL;
4290 SilcBuffer *channel_topics = NULL;
4291 SilcBuffer *channel_invites = NULL;
4292 SilcBuffer *channel_bans = NULL;
4293 SilcUInt32 channel_users_modes_c = 0;
4294 SilcChannelID **channel_ids = NULL;
4296 SILC_LOG_DEBUG(("Announcing channels and channel users"));
4298 /* Get channels and channel users in local list */
4299 silc_server_announce_get_channels(server, server->local_list,
4300 &channels, &channel_modes,
4302 &channel_users_modes,
4303 &channel_users_modes_c,
4307 &channel_ids, creation_time);
4309 /* Get channels and channel users in global list */
4310 if (server->server_type != SILC_SERVER)
4311 silc_server_announce_get_channels(server, server->global_list,
4312 &channels, &channel_modes,
4314 &channel_users_modes,
4315 &channel_users_modes_c,
4319 &channel_ids, creation_time);
4322 silc_buffer_push(channels, channels->data - channels->head);
4323 SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4325 /* Send the packet */
4326 silc_server_packet_send(server, remote,
4327 SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4328 channels->data, silc_buffer_len(channels));
4330 silc_buffer_free(channels);
4333 if (channel_users) {
4334 silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4335 SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4336 silc_buffer_len(channel_users));
4338 /* Send the packet */
4339 silc_server_packet_send(server, remote,
4340 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4341 channel_users->data, silc_buffer_len(channel_users));
4343 silc_buffer_free(channel_users);
4346 if (channel_modes) {
4349 for (i = 0; i < channel_users_modes_c; i++) {
4350 if (!channel_modes[i])
4352 silc_buffer_push(channel_modes[i],
4353 channel_modes[i]->data -
4354 channel_modes[i]->head);
4355 SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4356 silc_buffer_len(channel_modes[i]));
4357 silc_server_packet_send_dest(server, remote,
4358 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4359 channel_ids[i], SILC_ID_CHANNEL,
4360 channel_modes[i]->data,
4361 silc_buffer_len(channel_modes[i]));
4362 silc_buffer_free(channel_modes[i]);
4364 silc_free(channel_modes);
4367 if (channel_users_modes) {
4370 for (i = 0; i < channel_users_modes_c; i++) {
4371 if (!channel_users_modes[i])
4373 silc_buffer_push(channel_users_modes[i],
4374 channel_users_modes[i]->data -
4375 channel_users_modes[i]->head);
4376 SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4377 silc_buffer_len(channel_users_modes[i]));
4378 silc_server_packet_send_dest(server, remote,
4379 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4380 channel_ids[i], SILC_ID_CHANNEL,
4381 channel_users_modes[i]->data,
4382 silc_buffer_len(channel_users_modes[i]));
4383 silc_buffer_free(channel_users_modes[i]);
4385 silc_free(channel_users_modes);
4388 if (channel_topics) {
4391 for (i = 0; i < channel_users_modes_c; i++) {
4392 if (!channel_topics[i])
4395 silc_buffer_push(channel_topics[i],
4396 channel_topics[i]->data -
4397 channel_topics[i]->head);
4398 SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4399 silc_buffer_len(channel_topics[i]));
4400 silc_server_packet_send_dest(server, remote,
4401 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4402 channel_ids[i], SILC_ID_CHANNEL,
4403 channel_topics[i]->data,
4404 silc_buffer_len(channel_topics[i]));
4405 silc_buffer_free(channel_topics[i]);
4407 silc_free(channel_topics);
4410 if (channel_invites) {
4413 for (i = 0; i < channel_users_modes_c; i++) {
4414 if (!channel_invites[i])
4417 silc_buffer_push(channel_invites[i],
4418 channel_invites[i]->data -
4419 channel_invites[i]->head);
4420 SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4421 silc_buffer_len(channel_invites[i]));
4422 silc_server_packet_send_dest(server, remote,
4423 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4424 channel_ids[i], SILC_ID_CHANNEL,
4425 channel_invites[i]->data,
4426 silc_buffer_len(channel_invites[i]));
4427 silc_buffer_free(channel_invites[i]);
4429 silc_free(channel_invites);
4435 for (i = 0; i < channel_users_modes_c; i++) {
4436 if (!channel_bans[i])
4439 silc_buffer_push(channel_bans[i],
4440 channel_bans[i]->data -
4441 channel_bans[i]->head);
4442 SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4443 silc_buffer_len(channel_bans[i]));
4444 silc_server_packet_send_dest(server, remote,
4445 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4446 channel_ids[i], SILC_ID_CHANNEL,
4447 channel_bans[i]->data,
4448 silc_buffer_len(channel_bans[i]));
4449 silc_buffer_free(channel_bans[i]);
4451 silc_free(channel_bans);
4454 silc_free(channel_ids);
4457 /* Announces WATCH list. */
4459 void silc_server_announce_watches(SilcServer server,
4460 SilcPacketStream remote)
4462 SilcHashTableList htl;
4463 SilcBuffer buffer, idp, args, pkp;
4464 SilcClientEntry client;
4467 SILC_LOG_DEBUG(("Announcing watch list"));
4469 /* XXX because way we save the nicks (hash) we cannot announce them. */
4471 /* XXX we should send all public keys in one command if client is
4472 watching more than one key */
4473 silc_hash_table_list(server->watcher_list_pk, &htl);
4474 while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4475 if (!client || !client->id)
4478 server->stat.commands_sent++;
4480 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4481 args = silc_buffer_alloc_size(2);
4482 silc_buffer_format(args,
4483 SILC_STR_UI_SHORT(1),
4485 pkp = silc_public_key_payload_encode(key);
4486 args = silc_argument_payload_encode_one(args, pkp->data,
4487 silc_buffer_len(pkp), 0x00);
4488 buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4489 ++server->cmd_ident, 2,
4490 1, idp->data, silc_buffer_len(idp),
4492 silc_buffer_len(args));
4495 silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4496 buffer->data, silc_buffer_len(buffer));
4498 silc_buffer_free(pkp);
4499 silc_buffer_free(args);
4500 silc_buffer_free(idp);
4501 silc_buffer_free(buffer);
4503 silc_hash_table_list_reset(&htl);
4506 /* Assembles user list and users mode list from the `channel'. */
4508 SilcBool silc_server_get_users_on_channel(SilcServer server,
4509 SilcChannelEntry channel,
4510 SilcBuffer *user_list,
4511 SilcBuffer *mode_list,
4512 SilcUInt32 *user_count)
4514 SilcChannelClientEntry chl;
4515 SilcHashTableList htl;
4516 SilcBuffer client_id_list;
4517 SilcBuffer client_mode_list;
4519 SilcUInt32 list_count = 0, len = 0;
4521 if (!silc_hash_table_count(channel->user_list))
4524 silc_hash_table_list(channel->user_list, &htl);
4525 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4526 len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4527 silc_hash_table_list_reset(&htl);
4529 client_id_list = silc_buffer_alloc(len);
4531 silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4532 silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4533 silc_buffer_pull_tail(client_mode_list,
4534 silc_buffer_truelen(client_mode_list));
4536 silc_hash_table_list(channel->user_list, &htl);
4537 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4539 idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4540 silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4541 silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4542 silc_buffer_free(idp);
4544 /* Client's mode on channel */
4545 SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4546 silc_buffer_pull(client_mode_list, 4);
4550 silc_hash_table_list_reset(&htl);
4551 silc_buffer_push(client_id_list,
4552 client_id_list->data - client_id_list->head);
4553 silc_buffer_push(client_mode_list,
4554 client_mode_list->data - client_mode_list->head);
4556 *user_list = client_id_list;
4557 *mode_list = client_mode_list;
4558 *user_count = list_count;
4562 /* Saves users and their modes to the `channel'. */
4564 void silc_server_save_users_on_channel(SilcServer server,
4565 SilcPacketStream sock,
4566 SilcChannelEntry channel,
4567 SilcClientID *noadd,
4568 SilcBuffer user_list,
4569 SilcBuffer mode_list,
4570 SilcUInt32 user_count)
4576 SilcClientEntry client;
4577 SilcIDCacheEntry cache;
4578 SilcChannelClientEntry chl;
4580 SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4581 channel->channel_name));
4583 for (i = 0; i < user_count; i++) {
4585 SILC_GET16_MSB(idp_len, user_list->data + 2);
4587 if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4589 silc_buffer_pull(user_list, idp_len);
4592 SILC_GET32_MSB(mode, mode_list->data);
4593 silc_buffer_pull(mode_list, 4);
4595 if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4600 /* Check if we have this client cached already. */
4601 client = silc_idlist_find_client_by_id(server->local_list,
4603 server->server_type, &cache);
4605 client = silc_idlist_find_client_by_id(server->global_list,
4607 server->server_type, &cache);
4609 /* If router did not find such Client ID in its lists then this must
4610 be bogus client or some router in the net is buggy. */
4611 if (server->server_type != SILC_SERVER)
4614 /* We don't have that client anywhere, add it. The client is added
4615 to global list since server didn't have it in the lists so it must be
4617 client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4618 silc_id_dup(&id.u.client_id,
4620 silc_packet_get_context(sock),
4623 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4627 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4630 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4631 SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4632 "%s", channel->channel_name));
4636 if (!silc_server_client_on_channel(client, channel, &chl)) {
4637 /* Client was not on the channel, add it. */
4638 chl = silc_calloc(1, sizeof(*chl));
4639 chl->client = client;
4641 chl->channel = channel;
4642 silc_hash_table_add(channel->user_list, chl->client, chl);
4643 silc_hash_table_add(client->channels, chl->channel, chl);
4644 channel->user_count++;
4652 /* Saves channels and channels user modes to the `client'. Removes
4653 the client from those channels that are not sent in the list but
4656 void silc_server_save_user_channels(SilcServer server,
4657 SilcPacketStream sock,
4658 SilcClientEntry client,
4659 SilcBuffer channels,
4660 SilcBuffer channels_user_modes)
4663 SilcUInt32 *chumodes;
4664 SilcChannelPayload entry;
4665 SilcChannelEntry channel;
4666 SilcChannelID channel_id;
4667 SilcChannelClientEntry chl;
4668 SilcHashTable ht = NULL;
4669 SilcHashTableList htl;
4673 if (!channels || !channels_user_modes ||
4674 !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4677 ch = silc_channel_payload_parse_list(channels->data,
4678 silc_buffer_len(channels));
4679 if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4681 ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4682 NULL, NULL, NULL, TRUE);
4683 silc_dlist_start(ch);
4684 while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4685 /* Check if we have this channel, and add it if we don't have it.
4686 Also add the client on the channel unless it is there already. */
4687 if (!silc_channel_get_id_parse(entry, &channel_id))
4689 channel = silc_idlist_find_channel_by_id(server->local_list,
4692 channel = silc_idlist_find_channel_by_id(server->global_list,
4695 if (server->server_type != SILC_SERVER) {
4700 /* We don't have that channel anywhere, add it. */
4701 name = silc_channel_get_name(entry, NULL);
4702 channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4703 silc_id_dup(&channel_id,
4705 server->router, NULL, NULL, 0);
4712 channel->mode = silc_channel_get_mode(entry);
4714 /* Add the client on the channel */
4715 if (!silc_server_client_on_channel(client, channel, &chl)) {
4716 chl = silc_calloc(1, sizeof(*chl));
4717 chl->client = client;
4718 chl->mode = chumodes[i++];
4719 chl->channel = channel;
4720 silc_hash_table_add(channel->user_list, chl->client, chl);
4721 silc_hash_table_add(client->channels, chl->channel, chl);
4722 channel->user_count++;
4725 chl->mode = chumodes[i++];
4728 silc_hash_table_add(ht, channel, channel);
4730 silc_channel_payload_list_free(ch);
4731 silc_free(chumodes);
4735 /* Go through the list again and remove client from channels that
4736 are no part of the list. */
4738 silc_hash_table_list(client->channels, &htl);
4739 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4740 if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4741 silc_hash_table_del(chl->channel->user_list, chl->client);
4742 silc_hash_table_del(chl->client->channels, chl->channel);
4746 silc_hash_table_list_reset(&htl);
4747 silc_hash_table_free(ht);
4749 silc_hash_table_list(client->channels, &htl);
4750 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4751 silc_hash_table_del(chl->channel->user_list, chl->client);
4752 silc_hash_table_del(chl->client->channels, chl->channel);
4755 silc_hash_table_list_reset(&htl);
4759 /* Lookups route to the client indicated by the `id_data'. The connection
4760 object and internal data object is returned. Returns NULL if route
4761 could not be found to the client. If the `client_id' is specified then
4762 it is used and the `id_data' is ignored. */
4765 silc_server_get_client_route(SilcServer server,
4766 unsigned char *id_data,
4768 SilcClientID *client_id,
4769 SilcIDListData *idata,
4770 SilcClientEntry *client_entry)
4772 SilcClientID *id, clid;
4773 SilcClientEntry client;
4775 SILC_LOG_DEBUG(("Start"));
4778 *client_entry = NULL;
4780 /* Decode destination Client ID */
4782 if (!silc_id_str2id(id_data, id_len, SILC_ID_CLIENT, &clid, sizeof(clid)))
4784 id = silc_id_dup(&clid, SILC_ID_CLIENT);
4786 id = silc_id_dup(client_id, SILC_ID_CLIENT);
4789 /* If the destination belongs to our server we don't have to route
4790 the packet anywhere but to send it to the local destination. */
4791 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4795 /* If we are router and the client has router then the client is in
4796 our cell but not directly connected to us. */
4797 if (server->server_type == SILC_ROUTER && client->router) {
4798 /* We are of course in this case the client's router thus the route
4799 to the client is the server who owns the client. So, we will send
4800 the packet to that server. */
4802 *idata = (SilcIDListData)client->router;
4803 return client->router->connection;
4806 /* Seems that client really is directly connected to us */
4808 *idata = (SilcIDListData)client;
4810 *client_entry = client;
4811 return client->connection;
4814 /* Destination belongs to someone not in this server. If we are normal
4815 server our action is to send the packet to our router. */
4816 if (server->server_type != SILC_ROUTER && !server->standalone) {
4819 *idata = (SilcIDListData)server->router;
4820 return SILC_PRIMARY_ROUTE(server);
4823 /* We are router and we will perform route lookup for the destination
4824 and send the packet to fastest route. */
4825 if (server->server_type == SILC_ROUTER && !server->standalone) {
4826 /* Check first that the ID is valid */
4827 client = silc_idlist_find_client_by_id(server->global_list, id,
4830 SilcPacketStream dst_sock;
4832 dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4835 if (idata && dst_sock)
4836 *idata = silc_packet_get_context(dst_sock);
4845 /* Encodes and returns channel list of channels the `client' has joined.
4846 Secret channels are not put to the list. */
4848 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4849 SilcClientEntry client,
4850 SilcBool get_private,
4851 SilcBool get_secret,
4852 SilcBuffer *user_mode_list)
4854 SilcBuffer buffer = NULL;
4855 SilcChannelEntry channel;
4856 SilcChannelClientEntry chl;
4857 SilcHashTableList htl;
4858 unsigned char cid[32];
4860 SilcUInt16 name_len;
4864 *user_mode_list = NULL;
4866 silc_hash_table_list(client->channels, &htl);
4867 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4868 channel = chl->channel;
4870 if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4872 if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4875 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4876 name_len = strlen(channel->channel_name);
4878 len = 4 + name_len + id_len + 4;
4879 buffer = silc_buffer_realloc(buffer,
4881 silc_buffer_truelen(buffer) + len : len));
4882 silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4883 silc_buffer_format(buffer,
4884 SILC_STR_UI_SHORT(name_len),
4885 SILC_STR_DATA(channel->channel_name, name_len),
4886 SILC_STR_UI_SHORT(id_len),
4887 SILC_STR_DATA(cid, id_len),
4888 SILC_STR_UI_INT(chl->channel->mode),
4890 silc_buffer_pull(buffer, len);
4892 if (user_mode_list) {
4894 silc_buffer_realloc(*user_mode_list,
4896 silc_buffer_truelen((*user_mode_list)) + 4 : 4));
4897 silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
4898 (*user_mode_list)->data));
4899 SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
4900 silc_buffer_pull(*user_mode_list, 4);
4903 silc_hash_table_list_reset(&htl);
4906 silc_buffer_push(buffer, buffer->data - buffer->head);
4907 if (user_mode_list && *user_mode_list)
4908 silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
4909 (*user_mode_list)->head));
4914 /* Task callback used to retrieve network statistical information from
4915 router server once in a while. */
4917 SILC_TASK_CALLBACK(silc_server_get_stats)
4919 SilcServer server = (SilcServer)context;
4920 SilcBuffer idp, packet;
4922 if (!server->standalone) {
4923 SILC_LOG_DEBUG(("Retrieving stats from router"));
4924 server->stat.commands_sent++;
4925 idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
4926 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
4927 ++server->cmd_ident, 1,
4929 silc_buffer_len(idp));
4930 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4931 SILC_PACKET_COMMAND, 0, packet->data,
4932 silc_buffer_len(packet));
4933 silc_buffer_free(packet);
4934 silc_buffer_free(idp);
4937 silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,