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