xref: /freebsd/contrib/unbound/daemon/remote.h (revision be771a7b7f4580a30d99e41a5bb1b93a385a119d)
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 	/** if the io processing has started */
210 	int started;
211 	/** if the thread has to quit */
212 	int need_to_quit;
213 	/** verbosity of the fast_reload command, the number of +v options */
214 	int fr_verb;
215 	/** option to not pause threads during reload */
216 	int fr_nopause;
217 	/** option to drop mesh queries */
218 	int fr_drop_mesh;
219 
220 	/** the event that listens on the remote service worker to the
221 	 * commpair, it receives content from the fast reload thread. */
222 	void* service_event;
223 	/** if the event that listens on the remote service worker has
224 	 * been added to the comm base. */
225 	int service_event_is_added;
226 	/** the service event can read a cmd, nonblocking, so it can
227 	 * save the partial read cmd here */
228 	uint32_t service_read_cmd;
229 	/** the number of bytes in service_read_cmd */
230 	int service_read_cmd_count;
231 	/** the worker that the service_event is added in */
232 	struct worker* worker;
233 
234 	/** the printout of output to the remote client. */
235 	struct fast_reload_printq *printq;
236 
237 	/** lock on fr_output, to stop race when both remote control thread
238 	 * and fast reload thread use fr_output list. */
239 	lock_basic_type fr_output_lock;
240 	/** list of strings, that the fast reload thread produces that have
241 	 * to be printed. The remote control thread can pick them up with
242 	 * the lock. */
243 	struct config_strlist_head* fr_output;
244 
245 	/** communication socket pair, to respond to the reload request */
246 	int commreload[2];
247 
248 	/** the list of auth zone changes. */
249 	struct fast_reload_auth_change* auth_zone_change_list;
250 	/** the old tree of auth zones, to lookup. */
251 	struct auth_zones* old_auth_zones;
252 };
253 
254 /**
255  * Create new remote control state for the daemon.
256  * @param cfg: config file with key file settings.
257  * @return new state, or NULL on failure.
258  */
259 struct daemon_remote* daemon_remote_create(struct config_file* cfg);
260 
261 /**
262  * remote control state to delete.
263  * @param rc: state to delete.
264  */
265 void daemon_remote_delete(struct daemon_remote* rc);
266 
267 /**
268  * remote control state to clear up. Busy and accept points are closed.
269  * Does not delete the rc itself, or the ssl context (with its keys).
270  * @param rc: state to clear.
271  */
272 void daemon_remote_clear(struct daemon_remote* rc);
273 
274 /**
275  * Open and create listening ports for remote control.
276  * @param cfg: config options.
277  * @return list of ports or NULL on failure.
278  *	can be freed with listening_ports_free().
279  */
280 struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
281 
282 /**
283  * Setup comm points for accepting remote control connections.
284  * @param rc: state
285  * @param ports: already opened ports.
286  * @param worker: worker with communication base. and links to command channels.
287  * @return false on error.
288  */
289 int daemon_remote_open_accept(struct daemon_remote* rc,
290 	struct listen_port* ports, struct worker* worker);
291 
292 /**
293  * Stop accept handlers for TCP (until enabled again)
294  * @param rc: state
295  */
296 void daemon_remote_stop_accept(struct daemon_remote* rc);
297 
298 /**
299  * Stop accept handlers for TCP (until enabled again)
300  * @param rc: state
301  */
302 void daemon_remote_start_accept(struct daemon_remote* rc);
303 
304 /**
305  * Handle nonthreaded remote cmd execution.
306  * @param worker: this worker (the remote worker).
307  */
308 void daemon_remote_exec(struct worker* worker);
309 
310 #ifdef HAVE_SSL
311 /**
312  * Print fixed line of text over ssl connection in blocking mode
313  * @param ssl: print to
314  * @param text: the text.
315  * @return false on connection failure.
316  */
317 int ssl_print_text(RES* ssl, const char* text);
318 
319 /**
320  * printf style printing to the ssl connection
321  * @param ssl: the RES connection to print to. Blocking.
322  * @param format: printf style format string.
323  * @return success or false on a network failure.
324  */
325 int ssl_printf(RES* ssl, const char* format, ...)
326         ATTR_FORMAT(printf, 2, 3);
327 
328 /**
329  * Read until \n is encountered
330  * If stream signals EOF, the string up to then is returned (without \n).
331  * @param ssl: the RES connection to read from. blocking.
332  * @param buf: buffer to read to.
333  * @param max: size of buffer.
334  * @return false on connection failure.
335  */
336 int ssl_read_line(RES* ssl, char* buf, size_t max);
337 #endif /* HAVE_SSL */
338 
339 /**
340  * Start fast reload thread
341  * @param ssl: the RES connection to print to.
342  * @param worker: the remote servicing worker.
343  * @param s: the rc_state that is servicing the remote control connection to
344  *	the remote control client. It needs to be moved away to stay connected
345  *	while the fast reload is running.
346  * @param fr_verb: verbosity to print output at. 0 is nothing, 1 is some
347  *	and 2 is more detail.
348  * @param fr_nopause: option to not pause threads during reload.
349  * @param fr_drop_mesh: option to drop mesh queries.
350  */
351 void fast_reload_thread_start(RES* ssl, struct worker* worker,
352 	struct rc_state* s, int fr_verb, int fr_nopause, int fr_drop_mesh);
353 
354 /**
355  * Stop fast reload thread
356  * @param fast_reload_thread: the thread struct.
357  */
358 void fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread);
359 
360 /** fast reload thread commands to remote service thread event callback */
361 void fast_reload_service_cb(int fd, short bits, void* arg);
362 
363 /** fast reload callback for the remote control client connection */
364 int fast_reload_client_callback(struct comm_point* c, void* arg, int err,
365 	struct comm_reply* rep);
366 
367 /** fast reload printq delete list */
368 void fast_reload_printq_list_delete(struct fast_reload_printq* list);
369 
370 /** Pick up per worker changes after a fast reload. */
371 void fast_reload_worker_pickup_changes(struct worker* worker);
372 
373 #endif /* DAEMON_REMOTE_H */
374