Home | History | Annotate | Line # | Download | only in daemon
      1 /*
      2  * daemon/remote.h - remote control for the unbound daemon.
      3  *
      4  * Copyright (c) 2008, NLnet Labs. All rights reserved.
      5  *
      6  * This software is open source.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * Redistributions of source code must retain the above copyright notice,
     13  * this list of conditions and the following disclaimer.
     14  *
     15  * Redistributions in binary form must reproduce the above copyright notice,
     16  * this list of conditions and the following disclaimer in the documentation
     17  * and/or other materials provided with the distribution.
     18  *
     19  * Neither the name of the NLNET LABS nor the names of its contributors may
     20  * be used to endorse or promote products derived from this software without
     21  * specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 
     36 /**
     37  * \file
     38  *
     39  * This file contains the remote control functionality for the daemon.
     40  * The remote control can be performed using either the commandline
     41  * unbound-control tool, or a SSLv3/TLS capable web browser.
     42  * The channel is secured using SSLv3 or TLSv1, and certificates.
     43  * Both the server and the client(control tool) have their own keys.
     44  */
     45 
     46 #ifndef DAEMON_REMOTE_H
     47 #define DAEMON_REMOTE_H
     48 #ifdef HAVE_OPENSSL_SSL_H
     49 #include <openssl/ssl.h>
     50 #endif
     51 #include "util/locks.h"
     52 #include "libunbound/remote.h"
     53 struct config_file;
     54 struct listen_list;
     55 struct listen_port;
     56 struct worker;
     57 struct comm_reply;
     58 struct comm_point;
     59 struct daemon_remote;
     60 struct config_strlist_head;
     61 
     62 /** number of milliseconds timeout on incoming remote control handshake */
     63 #define REMOTE_CONTROL_TCP_TIMEOUT 120000
     64 
     65 /**
     66  * a busy control command connection, SSL state
     67  */
     68 struct rc_state {
     69 	/** the next item in list */
     70 	struct rc_state* next;
     71 	/** the commpoint */
     72 	struct comm_point* c;
     73 	/** in the handshake part */
     74 	enum { rc_none, rc_hs_read, rc_hs_write } shake_state;
     75 #ifdef HAVE_SSL
     76 	/** the ssl state */
     77 	SSL* ssl;
     78 #endif
     79 	/** file descriptor */
     80         int fd;
     81 	/** the rc this is part of */
     82 	struct daemon_remote* rc;
     83 };
     84 
     85 /**
     86  * The remote control tool state.
     87  * The state is only created for the first thread, other threads
     88  * are called from this thread.  Only the first threads listens to
     89  * the control port.  The other threads do not, but are called on the
     90  * command channel(pipe) from the first thread.
     91  */
     92 struct daemon_remote {
     93 	/** the worker for this remote control */
     94 	struct worker* worker;
     95 	/** commpoints for accepting remote control connections */
     96 	struct listen_list* accept_list;
     97 	/* if certificates are used */
     98 	int use_cert;
     99 	/** number of active commpoints that are handling remote control */
    100 	int active;
    101 	/** max active commpoints */
    102 	int max_active;
    103 	/** current commpoints busy; should be a short list, malloced */
    104 	struct rc_state* busy_list;
    105 #ifdef HAVE_SSL
    106 	/** the SSL context for creating new SSL streams */
    107 	SSL_CTX* ctx;
    108 #endif
    109 };
    110 
    111 /**
    112  * Connection to print to, either SSL or plain over fd
    113  */
    114 struct remote_stream {
    115 #ifdef HAVE_SSL
    116 	/** SSL structure, nonNULL if using SSL */
    117 	SSL* ssl;
    118 #endif
    119 	/** file descriptor for plain transfer */
    120 	int fd;
    121 };
    122 typedef struct remote_stream RES;
    123 
    124 /**
    125  * Notification status. This is exchanged between the fast reload thread
    126  * and the server thread, over the commpair sockets.
    127  */
    128 enum fast_reload_notification {
    129 	/** nothing, not used */
    130 	fast_reload_notification_none = 0,
    131 	/** the fast reload thread is done */
    132 	fast_reload_notification_done = 1,
    133 	/** the fast reload thread is done but with an error, it failed */
    134 	fast_reload_notification_done_error = 2,
    135 	/** the fast reload thread is told to exit by the server thread.
    136 	 * Sent on server quit while the reload is running. */
    137 	fast_reload_notification_exit = 3,
    138 	/** the fast reload thread has exited, after being told to exit */
    139 	fast_reload_notification_exited = 4,
    140 	/** the fast reload thread has information to print out */
    141 	fast_reload_notification_printout = 5,
    142 	/** stop as part of the reload the thread and other threads */
    143 	fast_reload_notification_reload_stop = 6,
    144 	/** ack the stop as part of the reload, and also ack start */
    145 	fast_reload_notification_reload_ack = 7,
    146 	/** resume from stop as part of the reload */
    147 	fast_reload_notification_reload_start = 8,
    148 	/** the fast reload thread wants the mainthread to poll workers,
    149 	 * after the reload, sent when nopause is used */
    150 	fast_reload_notification_reload_nopause_poll = 9
    151 };
    152 
    153 /**
    154  * Fast reload printout queue. Contains a list of strings, that need to be
    155  * printed over the file descriptor.
    156  */
    157 struct fast_reload_printq {
    158 	/** if this item is in a list, the previous and next */
    159 	struct fast_reload_printq *prev, *next;
    160 	/** if this item is in a list, it is true. */
    161 	int in_list;
    162 	/** list of strings to printout */
    163 	struct config_strlist_head* to_print;
    164 	/** the current item to print. It is malloced. NULL if none. */
    165 	char* client_item;
    166 	/** The length, strlen, of the client_item, that has to be sent. */
    167 	int client_len;
    168 	/** The number of bytes sent of client_item. */
    169 	int client_byte_count;
    170 	/** the comm point for the client connection, the remote control
    171 	 * client. */
    172 	struct comm_point* client_cp;
    173 	/** the remote control connection to print output to. */
    174 	struct remote_stream remote;
    175 	/** the worker that the event is added in */
    176 	struct worker* worker;
    177 };
    178 
    179 /**
    180  * Fast reload auth zone change. Keeps track if an auth zone was removed,
    181  * added or changed. This is needed because workers can have events for
    182  * dealing with auth zones, like transfers, and those have to be removed
    183  * too, not just the auth zone structure from the tree. */
    184 struct fast_reload_auth_change {
    185 	/** next in the list of auth zone changes. */
    186 	struct fast_reload_auth_change* next;
    187 	/** the zone in the old config */
    188 	struct auth_zone* old_z;
    189 	/** the zone in the new config */
    190 	struct auth_zone* new_z;
    191 	/** if the zone was deleted */
    192 	int is_deleted;
    193 	/** if the zone was added */
    194 	int is_added;
    195 	/** if the zone has been changed */
    196 	int is_changed;
    197 };
    198 
    199 /**
    200  * Fast reload thread structure
    201  */
    202 struct fast_reload_thread {
    203 	/** the thread number for the dtio thread,
    204 	 * must be first to cast thread arg to int* in checklock code. */
    205 	int threadnum;
    206 	/** communication socket pair, that sends commands */
    207 	int commpair[2];
    208 	/** thread id, of the io thread */
    209 	ub_thread_type tid;
    210 #ifdef HAVE_GETTID
    211 	/** thread tid, the LWP id */
    212 	pid_t thread_tid;
    213 	/** if logging should include the LWP id */
    214 	int thread_tid_log;
    215 #endif
    216 	/** if the io processing has started */
    217 	int started;
    218 	/** if the thread has to quit */
    219 	int need_to_quit;
    220 	/** verbosity of the fast_reload command, the number of +v options */
    221 	int fr_verb;
    222 	/** option to not pause threads during reload */
    223 	int fr_nopause;
    224 	/** option to drop mesh queries */
    225 	int fr_drop_mesh;
    226 
    227 	/** the event that listens on the remote service worker to the
    228 	 * commpair, it receives content from the fast reload thread. */
    229 	void* service_event;
    230 	/** if the event that listens on the remote service worker has
    231 	 * been added to the comm base. */
    232 	int service_event_is_added;
    233 	/** the service event can read a cmd, nonblocking, so it can
    234 	 * save the partial read cmd here */
    235 	uint32_t service_read_cmd;
    236 	/** the number of bytes in service_read_cmd */
    237 	int service_read_cmd_count;
    238 	/** the worker that the service_event is added in */
    239 	struct worker* worker;
    240 
    241 	/** the printout of output to the remote client. */
    242 	struct fast_reload_printq *printq;
    243 
    244 	/** lock on fr_output, to stop race when both remote control thread
    245 	 * and fast reload thread use fr_output list. */
    246 	lock_basic_type fr_output_lock;
    247 	/** list of strings, that the fast reload thread produces that have
    248 	 * to be printed. The remote control thread can pick them up with
    249 	 * the lock. */
    250 	struct config_strlist_head* fr_output;
    251 
    252 	/** communication socket pair, to respond to the reload request */
    253 	int commreload[2];
    254 
    255 	/** the list of auth zone changes. */
    256 	struct fast_reload_auth_change* auth_zone_change_list;
    257 	/** the old tree of auth zones, to lookup. */
    258 	struct auth_zones* old_auth_zones;
    259 	/** If the ssl ctxs have changed. */
    260 	int sslctxs_changed;
    261 };
    262 
    263 /**
    264  * Create new remote control state for the daemon.
    265  * @param cfg: config file with key file settings.
    266  * @return new state, or NULL on failure.
    267  */
    268 struct daemon_remote* daemon_remote_create(struct config_file* cfg);
    269 
    270 /**
    271  * remote control state to delete.
    272  * @param rc: state to delete.
    273  */
    274 void daemon_remote_delete(struct daemon_remote* rc);
    275 
    276 /**
    277  * remote control state to clear up. Busy and accept points are closed.
    278  * Does not delete the rc itself, or the ssl context (with its keys).
    279  * @param rc: state to clear.
    280  */
    281 void daemon_remote_clear(struct daemon_remote* rc);
    282 
    283 /**
    284  * Open and create listening ports for remote control.
    285  * @param cfg: config options.
    286  * @return list of ports or NULL on failure.
    287  *	can be freed with listening_ports_free().
    288  */
    289 struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
    290 
    291 /**
    292  * Setup comm points for accepting remote control connections.
    293  * @param rc: state
    294  * @param ports: already opened ports.
    295  * @param worker: worker with communication base. and links to command channels.
    296  * @return false on error.
    297  */
    298 int daemon_remote_open_accept(struct daemon_remote* rc,
    299 	struct listen_port* ports, struct worker* worker);
    300 
    301 /**
    302  * Stop accept handlers for TCP (until enabled again)
    303  * @param rc: state
    304  */
    305 void daemon_remote_stop_accept(struct daemon_remote* rc);
    306 
    307 /**
    308  * Stop accept handlers for TCP (until enabled again)
    309  * @param rc: state
    310  */
    311 void daemon_remote_start_accept(struct daemon_remote* rc);
    312 
    313 /**
    314  * Handle nonthreaded remote cmd execution.
    315  * @param worker: this worker (the remote worker).
    316  */
    317 void daemon_remote_exec(struct worker* worker);
    318 
    319 #ifdef HAVE_SSL
    320 /**
    321  * Print fixed line of text over ssl connection in blocking mode
    322  * @param ssl: print to
    323  * @param text: the text.
    324  * @return false on connection failure.
    325  */
    326 int ssl_print_text(RES* ssl, const char* text);
    327 
    328 /**
    329  * printf style printing to the ssl connection
    330  * @param ssl: the RES connection to print to. Blocking.
    331  * @param format: printf style format string.
    332  * @return success or false on a network failure.
    333  */
    334 int ssl_printf(RES* ssl, const char* format, ...)
    335         ATTR_FORMAT(printf, 2, 3);
    336 
    337 /**
    338  * Read until \n is encountered
    339  * If stream signals EOF, the string up to then is returned (without \n).
    340  * @param ssl: the RES connection to read from. blocking.
    341  * @param buf: buffer to read to.
    342  * @param max: size of buffer.
    343  * @return false on connection failure.
    344  */
    345 int ssl_read_line(RES* ssl, char* buf, size_t max);
    346 #endif /* HAVE_SSL */
    347 
    348 /**
    349  * Start fast reload thread
    350  * @param ssl: the RES connection to print to.
    351  * @param worker: the remote servicing worker.
    352  * @param s: the rc_state that is servicing the remote control connection to
    353  *	the remote control client. It needs to be moved away to stay connected
    354  *	while the fast reload is running.
    355  * @param fr_verb: verbosity to print output at. 0 is nothing, 1 is some
    356  *	and 2 is more detail.
    357  * @param fr_nopause: option to not pause threads during reload.
    358  * @param fr_drop_mesh: option to drop mesh queries.
    359  */
    360 void fast_reload_thread_start(RES* ssl, struct worker* worker,
    361 	struct rc_state* s, int fr_verb, int fr_nopause, int fr_drop_mesh);
    362 
    363 /**
    364  * Stop fast reload thread
    365  * @param fast_reload_thread: the thread struct.
    366  */
    367 void fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread);
    368 
    369 /** fast reload printq delete list */
    370 void fast_reload_printq_list_delete(struct fast_reload_printq* list);
    371 
    372 /** Pick up per worker changes after a fast reload. */
    373 void fast_reload_worker_pickup_changes(struct worker* worker);
    374 
    375 #endif /* DAEMON_REMOTE_H */
    376