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 struct config_file;
     53 struct listen_list;
     54 struct listen_port;
     55 struct worker;
     56 struct comm_reply;
     57 struct comm_point;
     58 struct daemon_remote;
     59 struct config_strlist_head;
     60 
     61 /** number of milliseconds timeout on incoming remote control handshake */
     62 #define REMOTE_CONTROL_TCP_TIMEOUT 120000
     63 
     64 /**
     65  * a busy control command connection, SSL state
     66  */
     67 struct rc_state {
     68 	/** the next item in list */
     69 	struct rc_state* next;
     70 	/** the commpoint */
     71 	struct comm_point* c;
     72 	/** in the handshake part */
     73 	enum { rc_none, rc_hs_read, rc_hs_write } shake_state;
     74 #ifdef HAVE_SSL
     75 	/** the ssl state */
     76 	SSL* ssl;
     77 #endif
     78 	/** file descriptor */
     79         int fd;
     80 	/** the rc this is part of */
     81 	struct daemon_remote* rc;
     82 };
     83 
     84 /**
     85  * The remote control tool state.
     86  * The state is only created for the first thread, other threads
     87  * are called from this thread.  Only the first threads listens to
     88  * the control port.  The other threads do not, but are called on the
     89  * command channel(pipe) from the first thread.
     90  */
     91 struct daemon_remote {
     92 	/** the worker for this remote control */
     93 	struct worker* worker;
     94 	/** commpoints for accepting remote control connections */
     95 	struct listen_list* accept_list;
     96 	/* if certificates are used */
     97 	int use_cert;
     98 	/** number of active commpoints that are handling remote control */
     99 	int active;
    100 	/** max active commpoints */
    101 	int max_active;
    102 	/** current commpoints busy; should be a short list, malloced */
    103 	struct rc_state* busy_list;
    104 #ifdef HAVE_SSL
    105 	/** the SSL context for creating new SSL streams */
    106 	SSL_CTX* ctx;
    107 #endif
    108 };
    109 
    110 /**
    111  * Connection to print to, either SSL or plain over fd
    112  */
    113 struct remote_stream {
    114 #ifdef HAVE_SSL
    115 	/** SSL structure, nonNULL if using SSL */
    116 	SSL* ssl;
    117 #endif
    118 	/** file descriptor for plain transfer */
    119 	int fd;
    120 };
    121 typedef struct remote_stream RES;
    122 
    123 /**
    124  * Notification status. This is exchanged between the fast reload thread
    125  * and the server thread, over the commpair sockets.
    126  */
    127 enum fast_reload_notification {
    128 	/** nothing, not used */
    129 	fast_reload_notification_none = 0,
    130 	/** the fast reload thread is done */
    131 	fast_reload_notification_done = 1,
    132 	/** the fast reload thread is done but with an error, it failed */
    133 	fast_reload_notification_done_error = 2,
    134 	/** the fast reload thread is told to exit by the server thread.
    135 	 * Sent on server quit while the reload is running. */
    136 	fast_reload_notification_exit = 3,
    137 	/** the fast reload thread has exited, after being told to exit */
    138 	fast_reload_notification_exited = 4,
    139 	/** the fast reload thread has information to print out */
    140 	fast_reload_notification_printout = 5,
    141 	/** stop as part of the reload the thread and other threads */
    142 	fast_reload_notification_reload_stop = 6,
    143 	/** ack the stop as part of the reload, and also ack start */
    144 	fast_reload_notification_reload_ack = 7,
    145 	/** resume from stop as part of the reload */
    146 	fast_reload_notification_reload_start = 8,
    147 	/** the fast reload thread wants the mainthread to poll workers,
    148 	 * after the reload, sent when nopause is used */
    149 	fast_reload_notification_reload_nopause_poll = 9
    150 };
    151 
    152 /**
    153  * Fast reload printout queue. Contains a list of strings, that need to be
    154  * printed over the file descriptor.
    155  */
    156 struct fast_reload_printq {
    157 	/** if this item is in a list, the previous and next */
    158 	struct fast_reload_printq *prev, *next;
    159 	/** if this item is in a list, it is true. */
    160 	int in_list;
    161 	/** list of strings to printout */
    162 	struct config_strlist_head* to_print;
    163 	/** the current item to print. It is malloced. NULL if none. */
    164 	char* client_item;
    165 	/** The length, strlen, of the client_item, that has to be sent. */
    166 	int client_len;
    167 	/** The number of bytes sent of client_item. */
    168 	int client_byte_count;
    169 	/** the comm point for the client connection, the remote control
    170 	 * client. */
    171 	struct comm_point* client_cp;
    172 	/** the remote control connection to print output to. */
    173 	struct remote_stream remote;
    174 	/** the worker that the event is added in */
    175 	struct worker* worker;
    176 };
    177 
    178 /**
    179  * Fast reload auth zone change. Keeps track if an auth zone was removed,
    180  * added or changed. This is needed because workers can have events for
    181  * dealing with auth zones, like transfers, and those have to be removed
    182  * too, not just the auth zone structure from the tree. */
    183 struct fast_reload_auth_change {
    184 	/** next in the list of auth zone changes. */
    185 	struct fast_reload_auth_change* next;
    186 	/** the zone in the old config */
    187 	struct auth_zone* old_z;
    188 	/** the zone in the new config */
    189 	struct auth_zone* new_z;
    190 	/** if the zone was deleted */
    191 	int is_deleted;
    192 	/** if the zone was added */
    193 	int is_added;
    194 	/** if the zone has been changed */
    195 	int is_changed;
    196 };
    197 
    198 /**
    199  * Fast reload thread structure
    200  */
    201 struct fast_reload_thread {
    202 	/** the thread number for the dtio thread,
    203 	 * must be first to cast thread arg to int* in checklock code. */
    204 	int threadnum;
    205 	/** communication socket pair, that sends commands */
    206 	int commpair[2];
    207 	/** thread id, of the io thread */
    208 	ub_thread_type tid;
    209 #ifdef HAVE_GETTID
    210 	/** thread tid, the LWP id */
    211 	pid_t thread_tid;
    212 	/** if logging should include the LWP id */
    213 	int thread_tid_log;
    214 #endif
    215 	/** if the io processing has started */
    216 	int started;
    217 	/** if the thread has to quit */
    218 	int need_to_quit;
    219 	/** verbosity of the fast_reload command, the number of +v options */
    220 	int fr_verb;
    221 	/** option to not pause threads during reload */
    222 	int fr_nopause;
    223 	/** option to drop mesh queries */
    224 	int fr_drop_mesh;
    225 
    226 	/** the event that listens on the remote service worker to the
    227 	 * commpair, it receives content from the fast reload thread. */
    228 	void* service_event;
    229 	/** if the event that listens on the remote service worker has
    230 	 * been added to the comm base. */
    231 	int service_event_is_added;
    232 	/** the service event can read a cmd, nonblocking, so it can
    233 	 * save the partial read cmd here */
    234 	uint32_t service_read_cmd;
    235 	/** the number of bytes in service_read_cmd */
    236 	int service_read_cmd_count;
    237 	/** the worker that the service_event is added in */
    238 	struct worker* worker;
    239 
    240 	/** the printout of output to the remote client. */
    241 	struct fast_reload_printq *printq;
    242 
    243 	/** lock on fr_output, to stop race when both remote control thread
    244 	 * and fast reload thread use fr_output list. */
    245 	lock_basic_type fr_output_lock;
    246 	/** list of strings, that the fast reload thread produces that have
    247 	 * to be printed. The remote control thread can pick them up with
    248 	 * the lock. */
    249 	struct config_strlist_head* fr_output;
    250 
    251 	/** communication socket pair, to respond to the reload request */
    252 	int commreload[2];
    253 
    254 	/** the list of auth zone changes. */
    255 	struct fast_reload_auth_change* auth_zone_change_list;
    256 	/** the old tree of auth zones, to lookup. */
    257 	struct auth_zones* old_auth_zones;
    258 	/** If the ssl ctxs have changed. */
    259 	int sslctxs_changed;
    260 };
    261 
    262 /**
    263  * Create new remote control state for the daemon.
    264  * @param cfg: config file with key file settings.
    265  * @return new state, or NULL on failure.
    266  */
    267 struct daemon_remote* daemon_remote_create(struct config_file* cfg);
    268 
    269 /**
    270  * remote control state to delete.
    271  * @param rc: state to delete.
    272  */
    273 void daemon_remote_delete(struct daemon_remote* rc);
    274 
    275 /**
    276  * remote control state to clear up. Busy and accept points are closed.
    277  * Does not delete the rc itself, or the ssl context (with its keys).
    278  * @param rc: state to clear.
    279  */
    280 void daemon_remote_clear(struct daemon_remote* rc);
    281 
    282 /**
    283  * Open and create listening ports for remote control.
    284  * @param cfg: config options.
    285  * @return list of ports or NULL on failure.
    286  *	can be freed with listening_ports_free().
    287  */
    288 struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
    289 
    290 /**
    291  * Setup comm points for accepting remote control connections.
    292  * @param rc: state
    293  * @param ports: already opened ports.
    294  * @param worker: worker with communication base. and links to command channels.
    295  * @return false on error.
    296  */
    297 int daemon_remote_open_accept(struct daemon_remote* rc,
    298 	struct listen_port* ports, struct worker* worker);
    299 
    300 /**
    301  * Stop accept handlers for TCP (until enabled again)
    302  * @param rc: state
    303  */
    304 void daemon_remote_stop_accept(struct daemon_remote* rc);
    305 
    306 /**
    307  * Stop accept handlers for TCP (until enabled again)
    308  * @param rc: state
    309  */
    310 void daemon_remote_start_accept(struct daemon_remote* rc);
    311 
    312 /**
    313  * Handle nonthreaded remote cmd execution.
    314  * @param worker: this worker (the remote worker).
    315  */
    316 void daemon_remote_exec(struct worker* worker);
    317 
    318 #ifdef HAVE_SSL
    319 /**
    320  * Print fixed line of text over ssl connection in blocking mode
    321  * @param ssl: print to
    322  * @param text: the text.
    323  * @return false on connection failure.
    324  */
    325 int ssl_print_text(RES* ssl, const char* text);
    326 
    327 /**
    328  * printf style printing to the ssl connection
    329  * @param ssl: the RES connection to print to. Blocking.
    330  * @param format: printf style format string.
    331  * @return success or false on a network failure.
    332  */
    333 int ssl_printf(RES* ssl, const char* format, ...)
    334         ATTR_FORMAT(printf, 2, 3);
    335 
    336 /**
    337  * Read until \n is encountered
    338  * If stream signals EOF, the string up to then is returned (without \n).
    339  * @param ssl: the RES connection to read from. blocking.
    340  * @param buf: buffer to read to.
    341  * @param max: size of buffer.
    342  * @return false on connection failure.
    343  */
    344 int ssl_read_line(RES* ssl, char* buf, size_t max);
    345 #endif /* HAVE_SSL */
    346 
    347 /**
    348  * Start fast reload thread
    349  * @param ssl: the RES connection to print to.
    350  * @param worker: the remote servicing worker.
    351  * @param s: the rc_state that is servicing the remote control connection to
    352  *	the remote control client. It needs to be moved away to stay connected
    353  *	while the fast reload is running.
    354  * @param fr_verb: verbosity to print output at. 0 is nothing, 1 is some
    355  *	and 2 is more detail.
    356  * @param fr_nopause: option to not pause threads during reload.
    357  * @param fr_drop_mesh: option to drop mesh queries.
    358  */
    359 void fast_reload_thread_start(RES* ssl, struct worker* worker,
    360 	struct rc_state* s, int fr_verb, int fr_nopause, int fr_drop_mesh);
    361 
    362 /**
    363  * Stop fast reload thread
    364  * @param fast_reload_thread: the thread struct.
    365  */
    366 void fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread);
    367 
    368 /** fast reload thread commands to remote service thread event callback */
    369 void fast_reload_service_cb(int fd, short bits, void* arg);
    370 
    371 /** fast reload callback for the remote control client connection */
    372 int fast_reload_client_callback(struct comm_point* c, void* arg, int err,
    373 	struct comm_reply* rep);
    374 
    375 /** fast reload printq delete list */
    376 void fast_reload_printq_list_delete(struct fast_reload_printq* list);
    377 
    378 /** Pick up per worker changes after a fast reload. */
    379 void fast_reload_worker_pickup_changes(struct worker* worker);
    380 
    381 #endif /* DAEMON_REMOTE_H */
    382