xref: /freebsd/contrib/unbound/daemon/remote.c (revision 7a789145f88a6aceacc59029a0cafe7de7aeefea)
1 /*
2  * daemon/remote.c - 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 TLS capable web browser.
42  * The channel is secured using TLSv1, and certificates.
43  * Both the server and the client(control tool) have their own keys.
44  */
45 #include "config.h"
46 #ifdef HAVE_OPENSSL_ERR_H
47 #include <openssl/err.h>
48 #endif
49 #ifdef HAVE_OPENSSL_DH_H
50 #include <openssl/dh.h>
51 #endif
52 #ifdef HAVE_OPENSSL_BN_H
53 #include <openssl/bn.h>
54 #endif
55 #ifdef HAVE_STDATOMIC_H
56 #include <stdatomic.h>
57 #endif
58 
59 #include <ctype.h>
60 #include "daemon/remote.h"
61 #include "daemon/worker.h"
62 #include "daemon/daemon.h"
63 #include "daemon/stats.h"
64 #include "daemon/cachedump.h"
65 #include "util/log.h"
66 #include "util/config_file.h"
67 #include "util/net_help.h"
68 #include "util/module.h"
69 #include "util/ub_event.h"
70 #include "services/listen_dnsport.h"
71 #include "services/cache/rrset.h"
72 #include "services/cache/infra.h"
73 #include "services/mesh.h"
74 #include "services/localzone.h"
75 #include "services/authzone.h"
76 #include "services/rpz.h"
77 #include "util/storage/slabhash.h"
78 #include "util/fptr_wlist.h"
79 #include "util/data/dname.h"
80 #include "validator/validator.h"
81 #include "validator/val_kcache.h"
82 #include "validator/val_kentry.h"
83 #include "validator/val_anchor.h"
84 #include "validator/val_neg.h"
85 #include "iterator/iterator.h"
86 #include "iterator/iter_fwd.h"
87 #include "iterator/iter_hints.h"
88 #include "iterator/iter_delegpt.h"
89 #include "iterator/iter_utils.h"
90 #include "iterator/iter_donotq.h"
91 #include "iterator/iter_priv.h"
92 #include "services/outbound_list.h"
93 #include "services/outside_network.h"
94 #include "sldns/str2wire.h"
95 #include "sldns/parseutil.h"
96 #include "sldns/wire2str.h"
97 #include "sldns/sbuffer.h"
98 #include "util/timeval_func.h"
99 #include "util/tcp_conn_limit.h"
100 #include "util/edns.h"
101 #ifdef USE_CACHEDB
102 #include "cachedb/cachedb.h"
103 #endif
104 #ifdef CLIENT_SUBNET
105 #include "edns-subnet/subnetmod.h"
106 #include "edns-subnet/addrtree.h"
107 #endif
108 
109 #ifdef HAVE_SYS_TYPES_H
110 #  include <sys/types.h>
111 #endif
112 #ifdef HAVE_SYS_STAT_H
113 #include <sys/stat.h>
114 #endif
115 #ifdef HAVE_NETDB_H
116 #include <netdb.h>
117 #endif
118 #ifdef HAVE_POLL_H
119 #include <poll.h>
120 #endif
121 
122 /* just for portability */
123 #ifdef SQ
124 #undef SQ
125 #endif
126 
127 /** what to put on statistics lines between var and value, ": " or "=" */
128 #define SQ "="
129 
130 /** Acceptable lengths of str lines */
131 #define MAX_CMD_STRLINE 1024
132 #define MAX_STDIN_STRLINE 2048
133 /** What number of loop iterations is too much for ipc retries */
134 #define IPC_LOOP_MAX 200
135 /** Timeout in msec for ipc socket poll. */
136 #define IPC_NOTIFICATION_WAIT 200
137 
138 static void fr_printq_delete(struct fast_reload_printq* printq);
139 static void fr_main_perform_printout(struct fast_reload_thread* fr);
140 static int fr_printq_empty(struct fast_reload_printq* printq);
141 static void fr_printq_list_insert(struct fast_reload_printq* printq,
142 	struct daemon* daemon);
143 static void fr_printq_remove(struct fast_reload_printq* printq);
144 static void fr_check_cmd_from_thread(struct fast_reload_thread* fr);
145 
146 static int
remote_setup_ctx(struct daemon_remote * rc,struct config_file * cfg)147 remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
148 {
149 	char* s_cert;
150 	char* s_key;
151 	rc->ctx = SSL_CTX_new(SSLv23_server_method());
152 	if(!rc->ctx) {
153 		log_crypto_err("could not SSL_CTX_new");
154 		return 0;
155 	}
156 	if(!listen_sslctx_setup(rc->ctx, cfg->tls_protocols)) {
157 		return 0;
158 	}
159 
160 	s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
161 	s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
162 	if(!s_cert || !s_key) {
163 		log_err("out of memory in remote control fname");
164 		goto setup_error;
165 	}
166 	verbose(VERB_ALGO, "setup SSL certificates");
167 	if (!SSL_CTX_use_certificate_chain_file(rc->ctx,s_cert)) {
168 		log_err("Error for server-cert-file: %s", s_cert);
169 		log_crypto_err("Error in SSL_CTX use_certificate_chain_file");
170 		goto setup_error;
171 	}
172 	if(!SSL_CTX_use_PrivateKey_file(rc->ctx,s_key,SSL_FILETYPE_PEM)) {
173 		log_err("Error for server-key-file: %s", s_key);
174 		log_crypto_err("Error in SSL_CTX use_PrivateKey_file");
175 		goto setup_error;
176 	}
177 	if(!SSL_CTX_check_private_key(rc->ctx)) {
178 		log_err("Error for server-key-file: %s", s_key);
179 		log_crypto_err("Error in SSL_CTX check_private_key");
180 		goto setup_error;
181 	}
182 	listen_sslctx_setup_2(rc->ctx);
183 	if(!SSL_CTX_load_verify_locations(rc->ctx, s_cert, NULL)) {
184 		log_crypto_err("Error setting up SSL_CTX verify locations");
185 	setup_error:
186 		free(s_cert);
187 		free(s_key);
188 		return 0;
189 	}
190 	SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert));
191 	SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL);
192 	free(s_cert);
193 	free(s_key);
194 	return 1;
195 }
196 
197 struct daemon_remote*
daemon_remote_create(struct config_file * cfg)198 daemon_remote_create(struct config_file* cfg)
199 {
200 	struct daemon_remote* rc = (struct daemon_remote*)calloc(1,
201 		sizeof(*rc));
202 	if(!rc) {
203 		log_err("out of memory in daemon_remote_create");
204 		return NULL;
205 	}
206 	rc->max_active = 10;
207 
208 	if(!cfg->remote_control_enable) {
209 		rc->ctx = NULL;
210 		return rc;
211 	}
212 	if(options_remote_is_address(cfg) && cfg->control_use_cert) {
213 		if(!remote_setup_ctx(rc, cfg)) {
214 			daemon_remote_delete(rc);
215 			return NULL;
216 		}
217 		rc->use_cert = 1;
218 	} else {
219 		struct config_strlist* p;
220 		rc->ctx = NULL;
221 		rc->use_cert = 0;
222 		if(!options_remote_is_address(cfg))
223 		  for(p = cfg->control_ifs.first; p; p = p->next) {
224 			if(p->str && p->str[0] != '/')
225 				log_warn("control-interface %s is not using TLS, but plain transfer, because first control-interface in config file is a local socket (starts with a /).", p->str);
226 		}
227 	}
228 	return rc;
229 }
230 
daemon_remote_clear(struct daemon_remote * rc)231 void daemon_remote_clear(struct daemon_remote* rc)
232 {
233 	struct rc_state* p, *np;
234 	if(!rc) return;
235 	/* but do not close the ports */
236 	listen_list_delete(rc->accept_list);
237 	rc->accept_list = NULL;
238 	/* do close these sockets */
239 	p = rc->busy_list;
240 	while(p) {
241 		np = p->next;
242 		if(p->ssl)
243 			SSL_free(p->ssl);
244 		comm_point_delete(p->c);
245 		free(p);
246 		p = np;
247 	}
248 	rc->busy_list = NULL;
249 	rc->active = 0;
250 	rc->worker = NULL;
251 }
252 
daemon_remote_delete(struct daemon_remote * rc)253 void daemon_remote_delete(struct daemon_remote* rc)
254 {
255 	if(!rc) return;
256 	daemon_remote_clear(rc);
257 	if(rc->ctx) {
258 		SSL_CTX_free(rc->ctx);
259 	}
260 	free(rc);
261 }
262 
263 /**
264  * Add and open a new control port
265  * @param ip: ip str
266  * @param nr: port nr
267  * @param list: list head
268  * @param noproto_is_err: if lack of protocol support is an error.
269  * @param cfg: config with username for chown of unix-sockets.
270  * @return false on failure.
271  */
272 static int
add_open(const char * ip,int nr,struct listen_port ** list,int noproto_is_err,struct config_file * cfg)273 add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
274 	struct config_file* cfg)
275 {
276 	struct addrinfo hints;
277 	struct addrinfo* res;
278 	struct listen_port* n;
279 	int noproto = 0;
280 	int fd, r;
281 	char port[15];
282 	snprintf(port, sizeof(port), "%d", nr);
283 	port[sizeof(port)-1]=0;
284 	memset(&hints, 0, sizeof(hints));
285 	log_assert(ip);
286 
287 	if(ip[0] == '/') {
288 		/* This looks like a local socket */
289 		fd = create_local_accept_sock(ip, &noproto, cfg->use_systemd);
290 		/*
291 		 * Change socket ownership and permissions so users other
292 		 * than root can access it provided they are in the same
293 		 * group as the user we run as.
294 		 */
295 		if(fd != -1) {
296 #ifdef HAVE_CHOWN
297 			chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
298 			if (cfg->username && cfg->username[0] &&
299 				cfg_uid != (uid_t)-1) {
300 				if(chown(ip, cfg_uid, cfg_gid) == -1)
301 					verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
302 					  (unsigned)cfg_uid, (unsigned)cfg_gid,
303 					  ip, strerror(errno));
304 			}
305 #else
306 			(void)cfg;
307 #endif
308 		}
309 	} else {
310 		const char* s = strchr(ip, '@');
311 		char newif[128];
312 		if(s) {
313 			/* override port with ifspec@port */
314 			int portnr;
315 			if((size_t)(s-ip) >= sizeof(newif)) {
316 				log_err("ifname too long: %s", ip);
317 				return -1;
318 			}
319 			portnr = atoi(s+1);
320 			if(portnr < 0 || 0 == portnr || portnr > 65535) {
321 				log_err("invalid portnumber in control-interface: %s", ip);
322 				return -1;
323 			}
324 			(void)strlcpy(newif, ip, sizeof(newif));
325 			newif[s-ip] = 0;
326 			ip = newif;
327 			snprintf(port, sizeof(port), "%d", portnr);
328 			port[sizeof(port)-1]=0;
329 		}
330 		hints.ai_socktype = SOCK_STREAM;
331 		hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
332 		if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
333 #ifdef USE_WINSOCK
334 			if(!noproto_is_err && r == EAI_NONAME) {
335 				/* tried to lookup the address as name */
336 				return 1; /* return success, but do nothing */
337 			}
338 #endif /* USE_WINSOCK */
339 			log_err("control interface %s:%s getaddrinfo: %s %s",
340 				ip?ip:"default", port, gai_strerror(r),
341 #ifdef EAI_SYSTEM
342 				r==EAI_SYSTEM?(char*)strerror(errno):""
343 #else
344 				""
345 #endif
346 			);
347 			return 0;
348 		}
349 
350 		/* open fd */
351 		fd = create_tcp_accept_sock(res, 1, &noproto, 0,
352 			cfg->ip_transparent, 0, 0, cfg->ip_freebind,
353 			cfg->use_systemd, cfg->ip_dscp, "unbound-control");
354 		freeaddrinfo(res);
355 	}
356 
357 	if(fd == -1 && noproto) {
358 		if(!noproto_is_err)
359 			return 1; /* return success, but do nothing */
360 		log_err("cannot open control interface %s %d : "
361 			"protocol not supported", ip, nr);
362 		return 0;
363 	}
364 	if(fd == -1) {
365 		log_err("cannot open control interface %s %d", ip, nr);
366 		return 0;
367 	}
368 
369 	/* alloc */
370 	n = (struct listen_port*)calloc(1, sizeof(*n));
371 	if(!n) {
372 		sock_close(fd);
373 		log_err("out of memory");
374 		return 0;
375 	}
376 	n->next = *list;
377 	*list = n;
378 	n->fd = fd;
379 	return 1;
380 }
381 
daemon_remote_open_ports(struct config_file * cfg)382 struct listen_port* daemon_remote_open_ports(struct config_file* cfg)
383 {
384 	struct listen_port* l = NULL;
385 	log_assert(cfg->remote_control_enable && cfg->control_port);
386 	if(cfg->control_ifs.first) {
387 		char** rcif = NULL;
388 		int i, num_rcif = 0;
389 		if(!resolve_interface_names(NULL, 0, cfg->control_ifs.first,
390 			&rcif, &num_rcif)) {
391 			return NULL;
392 		}
393 		for(i=0; i<num_rcif; i++) {
394 			if(!add_open(rcif[i], cfg->control_port, &l, 1, cfg)) {
395 				listening_ports_free(l);
396 				config_del_strarray(rcif, num_rcif);
397 				return NULL;
398 			}
399 		}
400 		config_del_strarray(rcif, num_rcif);
401 	} else {
402 		/* defaults */
403 		if(cfg->do_ip6 &&
404 			!add_open("::1", cfg->control_port, &l, 0, cfg)) {
405 			listening_ports_free(l);
406 			return NULL;
407 		}
408 		if(cfg->do_ip4 &&
409 			!add_open("127.0.0.1", cfg->control_port, &l, 1, cfg)) {
410 			listening_ports_free(l);
411 			return NULL;
412 		}
413 	}
414 	return l;
415 }
416 
417 /** open accept commpoint */
418 static int
accept_open(struct daemon_remote * rc,int fd)419 accept_open(struct daemon_remote* rc, int fd)
420 {
421 	struct listen_list* n = (struct listen_list*)malloc(sizeof(*n));
422 	if(!n) {
423 		log_err("out of memory");
424 		return 0;
425 	}
426 	n->next = rc->accept_list;
427 	rc->accept_list = n;
428 	/* open commpt */
429 	n->com = comm_point_create_raw(rc->worker->base, fd, 0,
430 		&remote_accept_callback, rc);
431 	if(!n->com)
432 		return 0;
433 	/* keep this port open, its fd is kept in the rc portlist */
434 	n->com->do_not_close = 1;
435 	return 1;
436 }
437 
daemon_remote_open_accept(struct daemon_remote * rc,struct listen_port * ports,struct worker * worker)438 int daemon_remote_open_accept(struct daemon_remote* rc,
439 	struct listen_port* ports, struct worker* worker)
440 {
441 	struct listen_port* p;
442 	rc->worker = worker;
443 	for(p = ports; p; p = p->next) {
444 		if(!accept_open(rc, p->fd)) {
445 			log_err("could not create accept comm point");
446 			return 0;
447 		}
448 	}
449 	return 1;
450 }
451 
daemon_remote_stop_accept(struct daemon_remote * rc)452 void daemon_remote_stop_accept(struct daemon_remote* rc)
453 {
454 	struct listen_list* p;
455 	for(p=rc->accept_list; p; p=p->next) {
456 		comm_point_stop_listening(p->com);
457 	}
458 }
459 
daemon_remote_start_accept(struct daemon_remote * rc)460 void daemon_remote_start_accept(struct daemon_remote* rc)
461 {
462 	struct listen_list* p;
463 	for(p=rc->accept_list; p; p=p->next) {
464 		comm_point_start_listening(p->com, -1, -1);
465 	}
466 }
467 
remote_accept_callback(struct comm_point * c,void * arg,int err,struct comm_reply * ATTR_UNUSED (rep))468 int remote_accept_callback(struct comm_point* c, void* arg, int err,
469 	struct comm_reply* ATTR_UNUSED(rep))
470 {
471 	struct daemon_remote* rc = (struct daemon_remote*)arg;
472 	struct sockaddr_storage addr;
473 	socklen_t addrlen;
474 	int newfd;
475 	struct rc_state* n;
476 	if(err != NETEVENT_NOERROR) {
477 		log_err("error %d on remote_accept_callback", err);
478 		return 0;
479 	}
480 	/* perform the accept */
481 	newfd = comm_point_perform_accept(c, &addr, &addrlen);
482 	if(newfd == -1)
483 		return 0;
484 	/* create new commpoint unless we are servicing already */
485 	if(rc->active >= rc->max_active) {
486 		log_warn("drop incoming remote control: too many connections");
487 	close_exit:
488 		sock_close(newfd);
489 		return 0;
490 	}
491 
492 	/* setup commpoint to service the remote control command */
493 	n = (struct rc_state*)calloc(1, sizeof(*n));
494 	if(!n) {
495 		log_err("out of memory");
496 		goto close_exit;
497 	}
498 	n->fd = newfd;
499 	/* start in reading state */
500 	n->c = comm_point_create_raw(rc->worker->base, newfd, 0,
501 		&remote_control_callback, n);
502 	if(!n->c) {
503 		log_err("out of memory");
504 		free(n);
505 		goto close_exit;
506 	}
507 	log_addr(VERB_QUERY, "new control connection from", &addr, addrlen);
508 	n->c->do_not_close = 0;
509 	comm_point_stop_listening(n->c);
510 	comm_point_start_listening(n->c, -1, REMOTE_CONTROL_TCP_TIMEOUT);
511 	memcpy(&n->c->repinfo.remote_addr, &addr, addrlen);
512 	n->c->repinfo.remote_addrlen = addrlen;
513 	if(rc->use_cert) {
514 		n->shake_state = rc_hs_read;
515 		n->ssl = SSL_new(rc->ctx);
516 		if(!n->ssl) {
517 			log_crypto_err("could not SSL_new");
518 			comm_point_delete(n->c);
519 			free(n);
520 			goto close_exit;
521 		}
522 		SSL_set_accept_state(n->ssl);
523 		(void)SSL_set_mode(n->ssl, (long)SSL_MODE_AUTO_RETRY);
524 		if(!SSL_set_fd(n->ssl, newfd)) {
525 			log_crypto_err("could not SSL_set_fd");
526 			SSL_free(n->ssl);
527 			comm_point_delete(n->c);
528 			free(n);
529 			goto close_exit;
530 		}
531 	} else {
532 		n->ssl = NULL;
533 	}
534 
535 	n->rc = rc;
536 	n->next = rc->busy_list;
537 	rc->busy_list = n;
538 	rc->active ++;
539 
540 	/* perform the first nonblocking read already, for windows,
541 	 * so it can return wouldblock. could be faster too. */
542 	(void)remote_control_callback(n->c, n, NETEVENT_NOERROR, NULL);
543 	return 0;
544 }
545 
546 /** delete from list */
547 static void
state_list_remove_elem(struct rc_state ** list,struct comm_point * c)548 state_list_remove_elem(struct rc_state** list, struct comm_point* c)
549 {
550 	while(*list) {
551 		if( (*list)->c == c) {
552 			*list = (*list)->next;
553 			return;
554 		}
555 		list = &(*list)->next;
556 	}
557 }
558 
559 /** decrease active count and remove commpoint from busy list */
560 static void
clean_point(struct daemon_remote * rc,struct rc_state * s)561 clean_point(struct daemon_remote* rc, struct rc_state* s)
562 {
563 	if(!s->rc) {
564 		/* the state has been picked up and moved away */
565 		free(s);
566 		return;
567 	}
568 	state_list_remove_elem(&rc->busy_list, s->c);
569 	rc->active --;
570 	if(s->ssl) {
571 		SSL_shutdown(s->ssl);
572 		SSL_free(s->ssl);
573 	}
574 	comm_point_delete(s->c);
575 	free(s);
576 }
577 
578 int
ssl_print_text(RES * res,const char * text)579 ssl_print_text(RES* res, const char* text)
580 {
581 	int r;
582 	if(!res)
583 		return 0;
584 	if(res->ssl) {
585 		ERR_clear_error();
586 		if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) {
587 			int r2;
588 			if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN) {
589 				verbose(VERB_QUERY, "warning, in SSL_write, peer "
590 					"closed connection");
591 				return 0;
592 			}
593 			log_crypto_err_io("could not SSL_write", r2);
594 			return 0;
595 		}
596 	} else {
597 		size_t at = 0;
598 		while(at < strlen(text)) {
599 			ssize_t r = send(res->fd, text+at, strlen(text)-at, 0);
600 			if(r == -1) {
601 				if(errno == EAGAIN || errno == EINTR)
602 					continue;
603 				log_err("could not send: %s",
604 					sock_strerror(errno));
605 				return 0;
606 			}
607 			at += r;
608 		}
609 	}
610 	return 1;
611 }
612 
613 /** print text over the ssl connection */
614 static int
ssl_print_vmsg(RES * ssl,const char * format,va_list args)615 ssl_print_vmsg(RES* ssl, const char* format, va_list args)
616 {
617 	char msg[65535];
618 	vsnprintf(msg, sizeof(msg), format, args);
619 	return ssl_print_text(ssl, msg);
620 }
621 
622 /** printf style printing to the ssl connection */
ssl_printf(RES * ssl,const char * format,...)623 int ssl_printf(RES* ssl, const char* format, ...)
624 {
625 	va_list args;
626 	int ret;
627 	va_start(args, format);
628 	ret = ssl_print_vmsg(ssl, format, args);
629 	va_end(args);
630 	return ret;
631 }
632 
633 int
ssl_read_line(RES * res,char * buf,size_t max)634 ssl_read_line(RES* res, char* buf, size_t max)
635 {
636 	int r;
637 	size_t len = 0;
638 	if(!res)
639 		return 0;
640 	while(len < max) {
641 		if(res->ssl) {
642 			ERR_clear_error();
643 			if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) {
644 				int r2;
645 				if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN) {
646 					buf[len] = 0;
647 					return 1;
648 				}
649 				log_crypto_err_io("could not SSL_read", r2);
650 				return 0;
651 			}
652 		} else {
653 			while(1) {
654 				ssize_t rr = recv(res->fd, buf+len, 1, 0);
655 				if(rr <= 0) {
656 					if(rr == 0) {
657 						buf[len] = 0;
658 						return 1;
659 					}
660 					if(errno == EINTR || errno == EAGAIN)
661 						continue;
662 					if(rr < 0) log_err("could not recv: %s",
663 						sock_strerror(errno));
664 					return 0;
665 				}
666 				break;
667 			}
668 		}
669 		if(buf[len] == '\n') {
670 			/* return string without \n */
671 			buf[len] = 0;
672 			return 1;
673 		}
674 		len++;
675 	}
676 	buf[max-1] = 0;
677 	log_err("control line too long (%d): %s", (int)max, buf);
678 	return 0;
679 }
680 
681 /** skip whitespace, return new pointer into string */
682 static char*
skipwhite(char * str)683 skipwhite(char* str)
684 {
685 	/* EOS \0 is not a space */
686 	while( isspace((unsigned char)*str) )
687 		str++;
688 	return str;
689 }
690 
691 /** send the OK to the control client */
send_ok(RES * ssl)692 static void send_ok(RES* ssl)
693 {
694 	(void)ssl_printf(ssl, "ok\n");
695 }
696 
697 /** tell other processes to execute the command */
698 static void
distribute_cmd(struct daemon_remote * rc,RES * ssl,char * cmd)699 distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
700 {
701 	int i;
702 	if(!cmd || !ssl)
703 		return;
704 	/* skip i=0 which is me */
705 	for(i=1; i<rc->worker->daemon->num; i++) {
706 		worker_send_cmd(rc->worker->daemon->workers[i],
707 			worker_cmd_remote);
708 		if(!tube_write_msg(rc->worker->daemon->workers[i]->cmd,
709 			(uint8_t*)cmd, strlen(cmd)+1, 0)) {
710 			(void)ssl_printf(ssl, "error could not distribute cmd\n");
711 			return;
712 		}
713 	}
714 }
715 
716 /** do the stop command */
717 static void
do_stop(RES * ssl,struct worker * worker)718 do_stop(RES* ssl, struct worker* worker)
719 {
720 	worker->need_to_exit = 1;
721 	comm_base_exit(worker->base);
722 	send_ok(ssl);
723 }
724 
725 /** do the reload command */
726 static void
do_reload(RES * ssl,struct worker * worker,int reuse_cache)727 do_reload(RES* ssl, struct worker* worker, int reuse_cache)
728 {
729 	worker->reuse_cache = reuse_cache;
730 	worker->need_to_exit = 0;
731 	comm_base_exit(worker->base);
732 	send_ok(ssl);
733 }
734 
735 #ifndef THREADS_DISABLED
736 /** parse fast reload command options. */
737 static int
fr_parse_options(RES * ssl,char * arg,int * fr_verb,int * fr_nopause,int * fr_drop_mesh)738 fr_parse_options(RES* ssl, char* arg, int* fr_verb, int* fr_nopause,
739 	int* fr_drop_mesh)
740 {
741 	char* argp = arg;
742 	while(*argp=='+') {
743 		argp++;
744 		while(*argp!=0 && *argp!=' ' && *argp!='\t') {
745 			if(*argp == 'v') {
746 				(*fr_verb)++;
747 			} else if(*argp == 'p') {
748 				(*fr_nopause) = 1;
749 			} else if(*argp == 'd') {
750 				(*fr_drop_mesh) = 1;
751 			} else {
752 				if(!ssl_printf(ssl,
753 					"error: unknown option '+%c'\n",
754 					*argp))
755 					return 0;
756 				return 0;
757 			}
758 			argp++;
759 		}
760 		argp = skipwhite(argp);
761 	}
762 	if(*argp!=0) {
763 		if(!ssl_printf(ssl, "error: unknown option '%s'\n", argp))
764 			return 0;
765 		return 0;
766 	}
767 	return 1;
768 }
769 #endif /* !THREADS_DISABLED */
770 
771 /** do the fast_reload command */
772 static void
do_fast_reload(RES * ssl,struct worker * worker,struct rc_state * s,char * arg)773 do_fast_reload(RES* ssl, struct worker* worker, struct rc_state* s, char* arg)
774 {
775 #ifdef THREADS_DISABLED
776 	if(!ssl_printf(ssl, "error: no threads for fast_reload, compiled without threads.\n"))
777 		return;
778 	(void)worker;
779 	(void)s;
780 	(void)arg;
781 #else
782 	int fr_verb = 0, fr_nopause = 0, fr_drop_mesh = 0;
783 	if(!fr_parse_options(ssl, arg, &fr_verb, &fr_nopause, &fr_drop_mesh))
784 		return;
785 	if(fr_verb >= 1) {
786 		if(!ssl_printf(ssl, "start fast_reload\n"))
787 			return;
788 	}
789 	fast_reload_thread_start(ssl, worker, s, fr_verb, fr_nopause,
790 		fr_drop_mesh);
791 #endif
792 }
793 
794 /** do the verbosity command */
795 static void
do_verbosity(RES * ssl,char * str)796 do_verbosity(RES* ssl, char* str)
797 {
798 	int val = atoi(str);
799 	if(val == 0 && strcmp(str, "0") != 0) {
800 		ssl_printf(ssl, "error in verbosity number syntax: %s\n", str);
801 		return;
802 	}
803 	verbosity = val;
804 	send_ok(ssl);
805 }
806 
807 /** print stats from statinfo */
808 static int
print_stats(RES * ssl,const char * nm,struct ub_stats_info * s)809 print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
810 {
811 	struct timeval sumwait, avg;
812 	if(!ssl_printf(ssl, "%s.num.queries"SQ"%lu\n", nm,
813 		(unsigned long)s->svr.num_queries)) return 0;
814 	if(!ssl_printf(ssl, "%s.num.queries_ip_ratelimited"SQ"%lu\n", nm,
815 		(unsigned long)s->svr.num_queries_ip_ratelimited)) return 0;
816 	if(!ssl_printf(ssl, "%s.num.queries_cookie_valid"SQ"%lu\n", nm,
817 		(unsigned long)s->svr.num_queries_cookie_valid)) return 0;
818 	if(!ssl_printf(ssl, "%s.num.queries_cookie_client"SQ"%lu\n", nm,
819 		(unsigned long)s->svr.num_queries_cookie_client)) return 0;
820 	if(!ssl_printf(ssl, "%s.num.queries_cookie_invalid"SQ"%lu\n", nm,
821 		(unsigned long)s->svr.num_queries_cookie_invalid)) return 0;
822 	if(!ssl_printf(ssl, "%s.num.queries_discard_timeout"SQ"%lu\n", nm,
823 		(unsigned long)s->svr.num_queries_discard_timeout)) return 0;
824 	if(!ssl_printf(ssl, "%s.num.queries_replyaddr_limit"SQ"%lu\n", nm,
825 		(unsigned long)s->svr.num_queries_replyaddr_limit)) return 0;
826 	if(!ssl_printf(ssl, "%s.num.queries_wait_limit"SQ"%lu\n", nm,
827 		(unsigned long)s->svr.num_queries_wait_limit)) return 0;
828 	if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
829 		(unsigned long)(s->svr.num_queries
830 			- s->svr.num_queries_missed_cache))) return 0;
831 	if(!ssl_printf(ssl, "%s.num.cachemiss"SQ"%lu\n", nm,
832 		(unsigned long)s->svr.num_queries_missed_cache)) return 0;
833 	if(!ssl_printf(ssl, "%s.num.prefetch"SQ"%lu\n", nm,
834 		(unsigned long)s->svr.num_queries_prefetch)) return 0;
835 	if(!ssl_printf(ssl, "%s.num.queries_timed_out"SQ"%lu\n", nm,
836 		(unsigned long)s->svr.num_queries_timed_out)) return 0;
837 	if(!ssl_printf(ssl, "%s.query.queue_time_us.max"SQ"%lu\n", nm,
838 		(unsigned long)s->svr.max_query_time_us)) return 0;
839 	if(!ssl_printf(ssl, "%s.num.expired"SQ"%lu\n", nm,
840 		(unsigned long)s->svr.ans_expired)) return 0;
841 	if(!ssl_printf(ssl, "%s.num.recursivereplies"SQ"%lu\n", nm,
842 		(unsigned long)s->mesh_replies_sent)) return 0;
843 #ifdef USE_DNSCRYPT
844 	if(!ssl_printf(ssl, "%s.num.dnscrypt.crypted"SQ"%lu\n", nm,
845 		(unsigned long)s->svr.num_query_dnscrypt_crypted)) return 0;
846 	if(!ssl_printf(ssl, "%s.num.dnscrypt.cert"SQ"%lu\n", nm,
847 		(unsigned long)s->svr.num_query_dnscrypt_cert)) return 0;
848 	if(!ssl_printf(ssl, "%s.num.dnscrypt.cleartext"SQ"%lu\n", nm,
849 		(unsigned long)s->svr.num_query_dnscrypt_cleartext)) return 0;
850 	if(!ssl_printf(ssl, "%s.num.dnscrypt.malformed"SQ"%lu\n", nm,
851 		(unsigned long)s->svr.num_query_dnscrypt_crypted_malformed)) return 0;
852 #endif
853 	if(!ssl_printf(ssl, "%s.num.dns_error_reports"SQ"%lu\n", nm,
854 		(unsigned long)s->svr.num_dns_error_reports)) return 0;
855 	if(!ssl_printf(ssl, "%s.requestlist.avg"SQ"%g\n", nm,
856 		(s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)?
857 			(double)s->svr.sum_query_list_size/
858 			(double)(s->svr.num_queries_missed_cache+
859 			s->svr.num_queries_prefetch) : 0.0)) return 0;
860 	if(!ssl_printf(ssl, "%s.requestlist.max"SQ"%lu\n", nm,
861 		(unsigned long)s->svr.max_query_list_size)) return 0;
862 	if(!ssl_printf(ssl, "%s.requestlist.overwritten"SQ"%lu\n", nm,
863 		(unsigned long)s->mesh_jostled)) return 0;
864 	if(!ssl_printf(ssl, "%s.requestlist.exceeded"SQ"%lu\n", nm,
865 		(unsigned long)s->mesh_dropped)) return 0;
866 	if(!ssl_printf(ssl, "%s.requestlist.current.all"SQ"%lu\n", nm,
867 		(unsigned long)s->mesh_num_states)) return 0;
868 	if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm,
869 		(unsigned long)s->mesh_num_reply_states)) return 0;
870 	if(!ssl_printf(ssl, "%s.requestlist.current.replies"SQ"%lu\n", nm,
871 		(unsigned long)s->mesh_num_reply_addrs)) return 0;
872 #ifndef S_SPLINT_S
873 	sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
874 	sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
875 #endif
876 	timeval_divide(&avg, &sumwait, s->mesh_replies_sent);
877 	if(!ssl_printf(ssl, "%s.recursion.time.avg"SQ ARG_LL "d.%6.6d\n", nm,
878 		(long long)avg.tv_sec, (int)avg.tv_usec)) return 0;
879 	if(!ssl_printf(ssl, "%s.recursion.time.median"SQ"%g\n", nm,
880 		s->mesh_time_median)) return 0;
881 	if(!ssl_printf(ssl, "%s.tcpusage"SQ"%lu\n", nm,
882 		(unsigned long)s->svr.tcp_accept_usage)) return 0;
883 	return 1;
884 }
885 
886 /** print stats for one thread */
887 static int
print_thread_stats(RES * ssl,int i,struct ub_stats_info * s)888 print_thread_stats(RES* ssl, int i, struct ub_stats_info* s)
889 {
890 	char nm[32];
891 	snprintf(nm, sizeof(nm), "thread%d", i);
892 	nm[sizeof(nm)-1]=0;
893 	return print_stats(ssl, nm, s);
894 }
895 
896 /** print long number */
897 static int
print_longnum(RES * ssl,const char * desc,size_t x)898 print_longnum(RES* ssl, const char* desc, size_t x)
899 {
900 	if(x > 1024*1024*1024) {
901 		/* more than a Gb */
902 		size_t front = x / (size_t)1000000;
903 		size_t back = x % (size_t)1000000;
904 		return ssl_printf(ssl, "%s%u%6.6u\n", desc,
905 			(unsigned)front, (unsigned)back);
906 	} else {
907 		return ssl_printf(ssl, "%s%lu\n", desc, (unsigned long)x);
908 	}
909 }
910 
911 /** print mem stats */
912 static int
print_mem(RES * ssl,struct worker * worker,struct daemon * daemon,struct ub_stats_info * s)913 print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
914 	struct ub_stats_info* s)
915 {
916 	size_t msg, rrset, val, iter, respip;
917 #ifdef CLIENT_SUBNET
918 	size_t subnet = 0;
919 #endif /* CLIENT_SUBNET */
920 #ifdef USE_IPSECMOD
921 	size_t ipsecmod = 0;
922 #endif /* USE_IPSECMOD */
923 #ifdef USE_DNSCRYPT
924 	size_t dnscrypt_shared_secret = 0;
925 	size_t dnscrypt_nonce = 0;
926 #endif /* USE_DNSCRYPT */
927 #ifdef WITH_DYNLIBMODULE
928     size_t dynlib = 0;
929 #endif /* WITH_DYNLIBMODULE */
930 	msg = slabhash_get_mem(daemon->env->msg_cache);
931 	rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
932 	val = mod_get_mem(&worker->env, "validator");
933 	iter = mod_get_mem(&worker->env, "iterator");
934 	respip = mod_get_mem(&worker->env, "respip");
935 #ifdef CLIENT_SUBNET
936 	subnet = mod_get_mem(&worker->env, "subnetcache");
937 #endif /* CLIENT_SUBNET */
938 #ifdef USE_IPSECMOD
939 	ipsecmod = mod_get_mem(&worker->env, "ipsecmod");
940 #endif /* USE_IPSECMOD */
941 #ifdef USE_DNSCRYPT
942 	if(daemon->dnscenv) {
943 		dnscrypt_shared_secret = slabhash_get_mem(
944 			daemon->dnscenv->shared_secrets_cache);
945 		dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
946 	}
947 #endif /* USE_DNSCRYPT */
948 #ifdef WITH_DYNLIBMODULE
949     dynlib = mod_get_mem(&worker->env, "dynlib");
950 #endif /* WITH_DYNLIBMODULE */
951 
952 	if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
953 		return 0;
954 	if(!print_longnum(ssl, "mem.cache.message"SQ, msg))
955 		return 0;
956 	if(!print_longnum(ssl, "mem.mod.iterator"SQ, iter))
957 		return 0;
958 	if(!print_longnum(ssl, "mem.mod.validator"SQ, val))
959 		return 0;
960 	if(!print_longnum(ssl, "mem.mod.respip"SQ, respip))
961 		return 0;
962 #ifdef CLIENT_SUBNET
963 	if(!print_longnum(ssl, "mem.mod.subnet"SQ, subnet))
964 		return 0;
965 #endif /* CLIENT_SUBNET */
966 #ifdef USE_IPSECMOD
967 	if(!print_longnum(ssl, "mem.mod.ipsecmod"SQ, ipsecmod))
968 		return 0;
969 #endif /* USE_IPSECMOD */
970 #ifdef USE_DNSCRYPT
971 	if(!print_longnum(ssl, "mem.cache.dnscrypt_shared_secret"SQ,
972 			dnscrypt_shared_secret))
973 		return 0;
974 	if(!print_longnum(ssl, "mem.cache.dnscrypt_nonce"SQ,
975 			dnscrypt_nonce))
976 		return 0;
977 #endif /* USE_DNSCRYPT */
978 #ifdef WITH_DYNLIBMODULE
979 	if(!print_longnum(ssl, "mem.mod.dynlibmod"SQ, dynlib))
980 		return 0;
981 #endif /* WITH_DYNLIBMODULE */
982 	if(!print_longnum(ssl, "mem.streamwait"SQ,
983 		(size_t)s->svr.mem_stream_wait))
984 		return 0;
985 	if(!print_longnum(ssl, "mem.http.query_buffer"SQ,
986 		(size_t)s->svr.mem_http2_query_buffer))
987 		return 0;
988 	if(!print_longnum(ssl, "mem.http.response_buffer"SQ,
989 		(size_t)s->svr.mem_http2_response_buffer))
990 		return 0;
991 #ifdef HAVE_NGTCP2
992 	if(!print_longnum(ssl, "mem.quic"SQ, (size_t)s->svr.mem_quic))
993 		return 0;
994 #endif /* HAVE_NGTCP2 */
995 	return 1;
996 }
997 
998 /** print uptime stats */
999 static int
print_uptime(RES * ssl,struct worker * worker,int reset)1000 print_uptime(RES* ssl, struct worker* worker, int reset)
1001 {
1002 	struct timeval now = *worker->env.now_tv;
1003 	struct timeval up, dt;
1004 	timeval_subtract(&up, &now, &worker->daemon->time_boot);
1005 	timeval_subtract(&dt, &now, &worker->daemon->time_last_stat);
1006 	if(reset)
1007 		worker->daemon->time_last_stat = now;
1008 	if(!ssl_printf(ssl, "time.now"SQ ARG_LL "d.%6.6d\n",
1009 		(long long)now.tv_sec, (unsigned)now.tv_usec)) return 0;
1010 	if(!ssl_printf(ssl, "time.up"SQ ARG_LL "d.%6.6d\n",
1011 		(long long)up.tv_sec, (unsigned)up.tv_usec)) return 0;
1012 	if(!ssl_printf(ssl, "time.elapsed"SQ ARG_LL "d.%6.6d\n",
1013 		(long long)dt.tv_sec, (unsigned)dt.tv_usec)) return 0;
1014 	return 1;
1015 }
1016 
1017 /** print extended histogram */
1018 static int
print_hist(RES * ssl,struct ub_stats_info * s)1019 print_hist(RES* ssl, struct ub_stats_info* s)
1020 {
1021 	struct timehist* hist;
1022 	size_t i;
1023 	hist = timehist_setup();
1024 	if(!hist) {
1025 		log_err("out of memory");
1026 		return 0;
1027 	}
1028 	timehist_import(hist, s->svr.hist, NUM_BUCKETS_HIST);
1029 	for(i=0; i<hist->num; i++) {
1030 		if(!ssl_printf(ssl,
1031 			"histogram.%6.6d.%6.6d.to.%6.6d.%6.6d=%lu\n",
1032 			(int)hist->buckets[i].lower.tv_sec,
1033 			(int)hist->buckets[i].lower.tv_usec,
1034 			(int)hist->buckets[i].upper.tv_sec,
1035 			(int)hist->buckets[i].upper.tv_usec,
1036 			(unsigned long)hist->buckets[i].count)) {
1037 			timehist_delete(hist);
1038 			return 0;
1039 		}
1040 	}
1041 	timehist_delete(hist);
1042 	return 1;
1043 }
1044 
1045 /** print extended stats */
1046 static int
print_ext(RES * ssl,struct ub_stats_info * s,int inhibit_zero)1047 print_ext(RES* ssl, struct ub_stats_info* s, int inhibit_zero)
1048 {
1049 	int i;
1050 	char nm[32];
1051 	const sldns_rr_descriptor* desc;
1052 	const sldns_lookup_table* lt;
1053 	/* TYPE */
1054 	for(i=0; i<UB_STATS_QTYPE_NUM; i++) {
1055 		if(inhibit_zero && s->svr.qtype[i] == 0)
1056 			continue;
1057 		desc = sldns_rr_descript((uint16_t)i);
1058 		if(desc && desc->_name) {
1059 			snprintf(nm, sizeof(nm), "%s", desc->_name);
1060 		} else if (i == LDNS_RR_TYPE_IXFR) {
1061 			snprintf(nm, sizeof(nm), "IXFR");
1062 		} else if (i == LDNS_RR_TYPE_AXFR) {
1063 			snprintf(nm, sizeof(nm), "AXFR");
1064 		} else if (i == LDNS_RR_TYPE_MAILA) {
1065 			snprintf(nm, sizeof(nm), "MAILA");
1066 		} else if (i == LDNS_RR_TYPE_MAILB) {
1067 			snprintf(nm, sizeof(nm), "MAILB");
1068 		} else if (i == LDNS_RR_TYPE_ANY) {
1069 			snprintf(nm, sizeof(nm), "ANY");
1070 		} else {
1071 			snprintf(nm, sizeof(nm), "TYPE%d", i);
1072 		}
1073 		if(!ssl_printf(ssl, "num.query.type.%s"SQ"%lu\n",
1074 			nm, (unsigned long)s->svr.qtype[i])) return 0;
1075 	}
1076 	if(!inhibit_zero || s->svr.qtype_big) {
1077 		if(!ssl_printf(ssl, "num.query.type.other"SQ"%lu\n",
1078 			(unsigned long)s->svr.qtype_big)) return 0;
1079 	}
1080 	/* CLASS */
1081 	for(i=0; i<UB_STATS_QCLASS_NUM; i++) {
1082 		if(inhibit_zero && s->svr.qclass[i] == 0)
1083 			continue;
1084 		lt = sldns_lookup_by_id(sldns_rr_classes, i);
1085 		if(lt && lt->name) {
1086 			snprintf(nm, sizeof(nm), "%s", lt->name);
1087 		} else {
1088 			snprintf(nm, sizeof(nm), "CLASS%d", i);
1089 		}
1090 		if(!ssl_printf(ssl, "num.query.class.%s"SQ"%lu\n",
1091 			nm, (unsigned long)s->svr.qclass[i])) return 0;
1092 	}
1093 	if(!inhibit_zero || s->svr.qclass_big) {
1094 		if(!ssl_printf(ssl, "num.query.class.other"SQ"%lu\n",
1095 			(unsigned long)s->svr.qclass_big)) return 0;
1096 	}
1097 	/* OPCODE */
1098 	for(i=0; i<UB_STATS_OPCODE_NUM; i++) {
1099 		if(inhibit_zero && s->svr.qopcode[i] == 0)
1100 			continue;
1101 		lt = sldns_lookup_by_id(sldns_opcodes, i);
1102 		if(lt && lt->name) {
1103 			snprintf(nm, sizeof(nm), "%s", lt->name);
1104 		} else {
1105 			snprintf(nm, sizeof(nm), "OPCODE%d", i);
1106 		}
1107 		if(!ssl_printf(ssl, "num.query.opcode.%s"SQ"%lu\n",
1108 			nm, (unsigned long)s->svr.qopcode[i])) return 0;
1109 	}
1110 	/* transport */
1111 	if(!ssl_printf(ssl, "num.query.tcp"SQ"%lu\n",
1112 		(unsigned long)s->svr.qtcp)) return 0;
1113 	if(!ssl_printf(ssl, "num.query.tcpout"SQ"%lu\n",
1114 		(unsigned long)s->svr.qtcp_outgoing)) return 0;
1115 	if(!ssl_printf(ssl, "num.query.udpout"SQ"%lu\n",
1116 		(unsigned long)s->svr.qudp_outgoing)) return 0;
1117 	if(!ssl_printf(ssl, "num.query.tls"SQ"%lu\n",
1118 		(unsigned long)s->svr.qtls)) return 0;
1119 	if(!ssl_printf(ssl, "num.query.tls.resume"SQ"%lu\n",
1120 		(unsigned long)s->svr.qtls_resume)) return 0;
1121 	if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n",
1122 		(unsigned long)s->svr.qipv6)) return 0;
1123 	if(!ssl_printf(ssl, "num.query.https"SQ"%lu\n",
1124 		(unsigned long)s->svr.qhttps)) return 0;
1125 #ifdef HAVE_NGTCP2
1126 	if(!ssl_printf(ssl, "num.query.quic"SQ"%lu\n",
1127 		(unsigned long)s->svr.qquic)) return 0;
1128 #endif /* HAVE_NGTCP2 */
1129 	/* flags */
1130 	if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%lu\n",
1131 		(unsigned long)s->svr.qbit_QR)) return 0;
1132 	if(!ssl_printf(ssl, "num.query.flags.AA"SQ"%lu\n",
1133 		(unsigned long)s->svr.qbit_AA)) return 0;
1134 	if(!ssl_printf(ssl, "num.query.flags.TC"SQ"%lu\n",
1135 		(unsigned long)s->svr.qbit_TC)) return 0;
1136 	if(!ssl_printf(ssl, "num.query.flags.RD"SQ"%lu\n",
1137 		(unsigned long)s->svr.qbit_RD)) return 0;
1138 	if(!ssl_printf(ssl, "num.query.flags.RA"SQ"%lu\n",
1139 		(unsigned long)s->svr.qbit_RA)) return 0;
1140 	if(!ssl_printf(ssl, "num.query.flags.Z"SQ"%lu\n",
1141 		(unsigned long)s->svr.qbit_Z)) return 0;
1142 	if(!ssl_printf(ssl, "num.query.flags.AD"SQ"%lu\n",
1143 		(unsigned long)s->svr.qbit_AD)) return 0;
1144 	if(!ssl_printf(ssl, "num.query.flags.CD"SQ"%lu\n",
1145 		(unsigned long)s->svr.qbit_CD)) return 0;
1146 	if(!ssl_printf(ssl, "num.query.edns.present"SQ"%lu\n",
1147 		(unsigned long)s->svr.qEDNS)) return 0;
1148 	if(!ssl_printf(ssl, "num.query.edns.DO"SQ"%lu\n",
1149 		(unsigned long)s->svr.qEDNS_DO)) return 0;
1150 
1151 	/* RCODE */
1152 	for(i=0; i<UB_STATS_RCODE_NUM; i++) {
1153 		/* Always include RCODEs 0-5 */
1154 		if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0)
1155 			continue;
1156 		lt = sldns_lookup_by_id(sldns_rcodes, i);
1157 		if(lt && lt->name) {
1158 			snprintf(nm, sizeof(nm), "%s", lt->name);
1159 		} else {
1160 			snprintf(nm, sizeof(nm), "RCODE%d", i);
1161 		}
1162 		if(!ssl_printf(ssl, "num.answer.rcode.%s"SQ"%lu\n",
1163 			nm, (unsigned long)s->svr.ans_rcode[i])) return 0;
1164 	}
1165 	if(!inhibit_zero || s->svr.ans_rcode_nodata) {
1166 		if(!ssl_printf(ssl, "num.answer.rcode.nodata"SQ"%lu\n",
1167 			(unsigned long)s->svr.ans_rcode_nodata)) return 0;
1168 	}
1169 	/* iteration */
1170 	if(!ssl_printf(ssl, "num.query.ratelimited"SQ"%lu\n",
1171 		(unsigned long)s->svr.queries_ratelimited)) return 0;
1172 	/* validation */
1173 	if(!ssl_printf(ssl, "num.answer.secure"SQ"%lu\n",
1174 		(unsigned long)s->svr.ans_secure)) return 0;
1175 	if(!ssl_printf(ssl, "num.answer.bogus"SQ"%lu\n",
1176 		(unsigned long)s->svr.ans_bogus)) return 0;
1177 	if(!ssl_printf(ssl, "num.rrset.bogus"SQ"%lu\n",
1178 		(unsigned long)s->svr.rrset_bogus)) return 0;
1179 	if(!ssl_printf(ssl, "num.valops"SQ"%lu\n",
1180 		(unsigned long)s->svr.val_ops)) return 0;
1181 	if(!ssl_printf(ssl, "num.query.aggressive.NOERROR"SQ"%lu\n",
1182 		(unsigned long)s->svr.num_neg_cache_noerror)) return 0;
1183 	if(!ssl_printf(ssl, "num.query.aggressive.NXDOMAIN"SQ"%lu\n",
1184 		(unsigned long)s->svr.num_neg_cache_nxdomain)) return 0;
1185 	/* threat detection */
1186 	if(!ssl_printf(ssl, "unwanted.queries"SQ"%lu\n",
1187 		(unsigned long)s->svr.unwanted_queries)) return 0;
1188 	if(!ssl_printf(ssl, "unwanted.replies"SQ"%lu\n",
1189 		(unsigned long)s->svr.unwanted_replies)) return 0;
1190 	/* cache counts */
1191 	if(!ssl_printf(ssl, "msg.cache.count"SQ"%u\n",
1192 		(unsigned)s->svr.msg_cache_count)) return 0;
1193 	if(!ssl_printf(ssl, "rrset.cache.count"SQ"%u\n",
1194 		(unsigned)s->svr.rrset_cache_count)) return 0;
1195 	if(!ssl_printf(ssl, "infra.cache.count"SQ"%u\n",
1196 		(unsigned)s->svr.infra_cache_count)) return 0;
1197 	if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n",
1198 		(unsigned)s->svr.key_cache_count)) return 0;
1199 	/* max collisions */
1200 	if(!ssl_printf(ssl, "msg.cache.max_collisions"SQ"%u\n",
1201 		(unsigned)s->svr.msg_cache_max_collisions)) return 0;
1202 	if(!ssl_printf(ssl, "rrset.cache.max_collisions"SQ"%u\n",
1203 		(unsigned)s->svr.rrset_cache_max_collisions)) return 0;
1204 	/* applied RPZ actions */
1205 	for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
1206 		if(i == RPZ_NO_OVERRIDE_ACTION)
1207 			continue;
1208 		if(inhibit_zero && s->svr.rpz_action[i] == 0)
1209 			continue;
1210 		if(!ssl_printf(ssl, "num.rpz.action.%s"SQ"%lu\n",
1211 			rpz_action_to_string(i),
1212 			(unsigned long)s->svr.rpz_action[i])) return 0;
1213 	}
1214 #ifdef USE_DNSCRYPT
1215 	if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n",
1216 		(unsigned)s->svr.shared_secret_cache_count)) return 0;
1217 	if(!ssl_printf(ssl, "dnscrypt_nonce.cache.count"SQ"%u\n",
1218 		(unsigned)s->svr.nonce_cache_count)) return 0;
1219 	if(!ssl_printf(ssl, "num.query.dnscrypt.shared_secret.cachemiss"SQ"%lu\n",
1220 		(unsigned long)s->svr.num_query_dnscrypt_secret_missed_cache)) return 0;
1221 	if(!ssl_printf(ssl, "num.query.dnscrypt.replay"SQ"%lu\n",
1222 		(unsigned long)s->svr.num_query_dnscrypt_replay)) return 0;
1223 #endif /* USE_DNSCRYPT */
1224 	if(!ssl_printf(ssl, "num.query.authzone.up"SQ"%lu\n",
1225 		(unsigned long)s->svr.num_query_authzone_up)) return 0;
1226 	if(!ssl_printf(ssl, "num.query.authzone.down"SQ"%lu\n",
1227 		(unsigned long)s->svr.num_query_authzone_down)) return 0;
1228 #ifdef CLIENT_SUBNET
1229 	if(!ssl_printf(ssl, "num.query.subnet"SQ"%lu\n",
1230 		(unsigned long)s->svr.num_query_subnet)) return 0;
1231 	if(!ssl_printf(ssl, "num.query.subnet_cache"SQ"%lu\n",
1232 		(unsigned long)s->svr.num_query_subnet_cache)) return 0;
1233 #endif /* CLIENT_SUBNET */
1234 #ifdef USE_CACHEDB
1235 	if(!ssl_printf(ssl, "num.query.cachedb"SQ"%lu\n",
1236 		(unsigned long)s->svr.num_query_cachedb)) return 0;
1237 #endif /* USE_CACHEDB */
1238 	return 1;
1239 }
1240 
1241 /** do the stats command */
1242 static void
do_stats(RES * ssl,struct worker * worker,int reset)1243 do_stats(RES* ssl, struct worker* worker, int reset)
1244 {
1245 	struct daemon* daemon = worker->daemon;
1246 	struct ub_stats_info total;
1247 	struct ub_stats_info s;
1248 	int i;
1249 	memset(&total, 0, sizeof(total));
1250 	log_assert(daemon->num > 0);
1251 	/* gather all thread statistics in one place */
1252 	for(i=0; i<daemon->num; i++) {
1253 		server_stats_obtain(worker, daemon->workers[i], &s, reset);
1254 		if(!print_thread_stats(ssl, i, &s))
1255 			return;
1256 		if(i == 0)
1257 			total = s;
1258 		else	server_stats_add(&total, &s);
1259 	}
1260 	/* print the thread statistics */
1261 	total.mesh_time_median /= (double)daemon->num;
1262 	if(!print_stats(ssl, "total", &total))
1263 		return;
1264 	if(!print_uptime(ssl, worker, reset))
1265 		return;
1266 	if(daemon->cfg->stat_extended) {
1267 		if(!print_mem(ssl, worker, daemon, &total))
1268 			return;
1269 		if(!print_hist(ssl, &total))
1270 			return;
1271 		if(!print_ext(ssl, &total, daemon->cfg->stat_inhibit_zero))
1272 			return;
1273 	}
1274 }
1275 
1276 /** parse commandline argument domain name */
1277 static int
parse_arg_name(RES * ssl,char * str,uint8_t ** res,size_t * len,int * labs)1278 parse_arg_name(RES* ssl, char* str, uint8_t** res, size_t* len, int* labs)
1279 {
1280 	uint8_t nm[LDNS_MAX_DOMAINLEN+1];
1281 	size_t nmlen = sizeof(nm);
1282 	int status;
1283 	*res = NULL;
1284 	*len = 0;
1285 	*labs = 0;
1286 	if(str[0] == '\0') {
1287 		ssl_printf(ssl, "error: this option requires a domain name\n");
1288 		return 0;
1289 	}
1290 	status = sldns_str2wire_dname_buf(str, nm, &nmlen);
1291 	if(status != 0) {
1292 		ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", str,
1293 			LDNS_WIREPARSE_OFFSET(status),
1294 			sldns_get_errorstr_parse(status));
1295 		return 0;
1296 	}
1297 	*res = memdup(nm, nmlen);
1298 	if(!*res) {
1299 		ssl_printf(ssl, "error out of memory\n");
1300 		return 0;
1301 	}
1302 	*labs = dname_count_size_labels(*res, len);
1303 	return 1;
1304 }
1305 
1306 /** find second argument, modifies string */
1307 static int
find_arg2(RES * ssl,char * arg,char ** arg2)1308 find_arg2(RES* ssl, char* arg, char** arg2)
1309 {
1310 	char* as = strchr(arg, ' ');
1311 	char* at = strchr(arg, '\t');
1312 	if(as && at) {
1313 		if(at < as)
1314 			as = at;
1315 		as[0]=0;
1316 		*arg2 = skipwhite(as+1);
1317 	} else if(as) {
1318 		as[0]=0;
1319 		*arg2 = skipwhite(as+1);
1320 	} else if(at) {
1321 		at[0]=0;
1322 		*arg2 = skipwhite(at+1);
1323 	} else {
1324 		ssl_printf(ssl, "error could not find next argument "
1325 			"after %s\n", arg);
1326 		return 0;
1327 	}
1328 	return 1;
1329 }
1330 
1331 /** Add a new zone */
1332 static int
perform_zone_add(RES * ssl,struct local_zones * zones,char * arg)1333 perform_zone_add(RES* ssl, struct local_zones* zones, char* arg)
1334 {
1335 	uint8_t* nm;
1336 	int nmlabs;
1337 	size_t nmlen;
1338 	char* arg2;
1339 	enum localzone_type t;
1340 	struct local_zone* z;
1341 	if(!find_arg2(ssl, arg, &arg2))
1342 		return 0;
1343 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
1344 		return 0;
1345 	if(!local_zone_str2type(arg2, &t)) {
1346 		ssl_printf(ssl, "error not a zone type. %s\n", arg2);
1347 		free(nm);
1348 		return 0;
1349 	}
1350 	lock_rw_wrlock(&zones->lock);
1351 	if((z=local_zones_find(zones, nm, nmlen,
1352 		nmlabs, LDNS_RR_CLASS_IN))) {
1353 		/* already present in tree */
1354 		lock_rw_wrlock(&z->lock);
1355 		z->type = t; /* update type anyway */
1356 		lock_rw_unlock(&z->lock);
1357 		free(nm);
1358 		lock_rw_unlock(&zones->lock);
1359 		return 1;
1360 	}
1361 	if(!local_zones_add_zone(zones, nm, nmlen,
1362 		nmlabs, LDNS_RR_CLASS_IN, t)) {
1363 		lock_rw_unlock(&zones->lock);
1364 		ssl_printf(ssl, "error out of memory\n");
1365 		return 0;
1366 	}
1367 	lock_rw_unlock(&zones->lock);
1368 	return 1;
1369 }
1370 
1371 /** Do the local_zone command */
1372 static void
do_zone_add(RES * ssl,struct local_zones * zones,char * arg)1373 do_zone_add(RES* ssl, struct local_zones* zones, char* arg)
1374 {
1375 	if(!perform_zone_add(ssl, zones, arg))
1376 		return;
1377 	send_ok(ssl);
1378 }
1379 
1380 /** Do the local_zones command */
1381 static void
do_zones_add(struct daemon_remote * rc,RES * ssl,struct worker * worker)1382 do_zones_add(struct daemon_remote* rc, RES* ssl, struct worker* worker)
1383 {
1384 	char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_zone ";
1385 	int num = 0;
1386 	size_t cmd_len = strlen(buf);
1387 	while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
1388 		if(buf[0+cmd_len] == 0 ||
1389 			(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
1390 			break; /* zero byte line or end of transmission */
1391 #ifdef THREADS_DISABLED
1392 		/* distribute single item command */
1393 		if(rc) distribute_cmd(rc, ssl, buf);
1394 #else
1395 		(void)rc; /* unused */
1396 #endif
1397 		if(!perform_zone_add(ssl, worker->daemon->local_zones,
1398 			buf+cmd_len)) {
1399 			if(!ssl_printf(ssl, "error for input line: %s\n",
1400 				buf+cmd_len))
1401 				return;
1402 		}
1403 		else	num++;
1404 	}
1405 	(void)ssl_printf(ssl, "added %d zones\n", num);
1406 }
1407 
1408 /** Remove a zone */
1409 static int
perform_zone_remove(RES * ssl,struct local_zones * zones,char * arg)1410 perform_zone_remove(RES* ssl, struct local_zones* zones, char* arg)
1411 {
1412 	uint8_t* nm;
1413 	int nmlabs;
1414 	size_t nmlen;
1415 	struct local_zone* z;
1416 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
1417 		return 0;
1418 	lock_rw_wrlock(&zones->lock);
1419 	if((z=local_zones_find(zones, nm, nmlen,
1420 		nmlabs, LDNS_RR_CLASS_IN))) {
1421 		/* present in tree */
1422 		local_zones_del_zone(zones, z);
1423 	}
1424 	lock_rw_unlock(&zones->lock);
1425 	free(nm);
1426 	return 1;
1427 }
1428 
1429 /** Do the local_zone_remove command */
1430 static void
do_zone_remove(RES * ssl,struct local_zones * zones,char * arg)1431 do_zone_remove(RES* ssl, struct local_zones* zones, char* arg)
1432 {
1433 	if(!perform_zone_remove(ssl, zones, arg))
1434 		return;
1435 	send_ok(ssl);
1436 }
1437 
1438 /** Do the local_zones_remove command */
1439 static void
do_zones_remove(struct daemon_remote * rc,RES * ssl,struct worker * worker)1440 do_zones_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker)
1441 {
1442 	char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_zone_remove ";
1443 	int num = 0;
1444 	size_t cmd_len = strlen(buf);
1445 	while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
1446 		if(buf[0+cmd_len] == 0 ||
1447 			(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
1448 			break; /* zero byte line or end of transmission */
1449 #ifdef THREADS_DISABLED
1450 		/* distribute single item command */
1451 		if(rc) distribute_cmd(rc, ssl, buf);
1452 #else
1453 		(void)rc; /* unused */
1454 #endif
1455 		if(!perform_zone_remove(ssl, worker->daemon->local_zones,
1456 			buf+cmd_len)) {
1457 			if(!ssl_printf(ssl, "error for input line: %s\n",
1458 				buf+cmd_len))
1459 				return;
1460 		}
1461 		else	num++;
1462 	}
1463 	(void)ssl_printf(ssl, "removed %d zones\n", num);
1464 }
1465 
1466 /** check syntax of newly added RR */
1467 static int
check_RR_syntax(RES * ssl,char * str,int line)1468 check_RR_syntax(RES* ssl, char* str, int line)
1469 {
1470 	uint8_t rr[LDNS_RR_BUF_SIZE];
1471 	size_t len = sizeof(rr), dname_len = 0;
1472 	int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
1473 		NULL, 0, NULL, 0);
1474 	if(s != 0) {
1475 		char linestr[32];
1476 		if(line == 0)
1477 			linestr[0]=0;
1478 		else 	snprintf(linestr, sizeof(linestr), "line %d ", line);
1479 		if(!ssl_printf(ssl, "error parsing local-data at %sposition %d '%s': %s\n",
1480 			linestr, LDNS_WIREPARSE_OFFSET(s), str,
1481 			sldns_get_errorstr_parse(s)))
1482 			return 0;
1483 		return 0;
1484 	}
1485 	return 1;
1486 }
1487 
1488 /** Add new RR data */
1489 static int
perform_data_add(RES * ssl,struct local_zones * zones,char * arg,int line)1490 perform_data_add(RES* ssl, struct local_zones* zones, char* arg, int line)
1491 {
1492 	if(!check_RR_syntax(ssl, arg, line)) {
1493 		return 0;
1494 	}
1495 	if(!local_zones_add_RR(zones, arg)) {
1496 		ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
1497 		return 0;
1498 	}
1499 	return 1;
1500 }
1501 
1502 /** Do the local_data command */
1503 static void
do_data_add(RES * ssl,struct local_zones * zones,char * arg)1504 do_data_add(RES* ssl, struct local_zones* zones, char* arg)
1505 {
1506 	if(!perform_data_add(ssl, zones, arg, 0))
1507 		return;
1508 	send_ok(ssl);
1509 }
1510 
1511 /** Do the local_datas command */
1512 static void
do_datas_add(struct daemon_remote * rc,RES * ssl,struct worker * worker)1513 do_datas_add(struct daemon_remote* rc, RES* ssl, struct worker* worker)
1514 {
1515 	char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_data ";
1516 	int num = 0, line = 0;
1517 	size_t cmd_len = strlen(buf);
1518 	while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
1519 		if(buf[0+cmd_len] == 0 ||
1520 			(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
1521 			break; /* zero byte line or end of transmission */
1522 #ifdef THREADS_DISABLED
1523 		/* distribute single item command */
1524 		if(rc) distribute_cmd(rc, ssl, buf);
1525 #else
1526 		(void)rc; /* unused */
1527 #endif
1528 		line++;
1529 		if(perform_data_add(ssl, worker->daemon->local_zones,
1530 			buf+cmd_len, line))
1531 			num++;
1532 	}
1533 	(void)ssl_printf(ssl, "added %d datas\n", num);
1534 }
1535 
1536 static int
perform_data_remove_rr(RES * ssl,struct local_zones * local_zones,uint8_t * rr,size_t len,size_t dname_len,char * arg)1537 perform_data_remove_rr(RES* ssl, struct local_zones* local_zones,
1538 	uint8_t* rr, size_t len, size_t dname_len, char *arg)
1539 {
1540 	uint16_t rr_class, rr_type;
1541 	int labs;
1542 	struct local_zone* z;
1543 	struct local_data* ld;
1544 	uint8_t *rdata;
1545 	size_t rdata_len, index;
1546 	struct packed_rrset_data* d;
1547 	struct local_rrset* p;
1548 
1549 	rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len);
1550 	rdata_len = ((size_t)sldns_wirerr_get_rdatalen(rr, len, dname_len))+2;
1551 
1552 	labs = dname_count_labels(rr);
1553 
1554 	rr_class = sldns_wirerr_get_class(rr, len, dname_len);
1555 	rr_type = sldns_wirerr_get_type(rr, len, dname_len);
1556 
1557 	z = local_zones_lookup(local_zones, rr, dname_len,
1558 			labs, rr_class, rr_type, 1);
1559 	if (!z) {
1560 		ssl_printf(ssl, "error no zone for rr %s\n", arg);
1561 		return 0;
1562 	}
1563 
1564 	ld = local_zone_find_data(z, rr, dname_len, labs);
1565 	if (!ld) {
1566 		ssl_printf(ssl, "error no local data for rr %s\n", arg);
1567 		return 0;
1568 	}
1569 
1570 	p = ld->rrsets;
1571 	while (p && ntohs(p->rrset->rk.type) != rr_type) {
1572 		p = p->next;
1573 	}
1574 
1575 	if (!p) {
1576 		ssl_printf(ssl, "error no rrset for rr %s\n", arg);
1577 		return 0;
1578 	}
1579 
1580 	d = (struct packed_rrset_data*)p->rrset->entry.data;
1581 	if (!packed_rrset_find_rr(d, rdata, rdata_len, &index)) {
1582 		ssl_printf(ssl, "error rr %s not found in rrset\n", arg);
1583 		return 0;
1584 	}
1585 
1586 	if (!local_rrset_remove_rr(d, index)) {
1587 		ssl_printf(ssl, "error unable to delete rr %s\n", arg);
1588 		return 0;
1589 	}
1590 
1591 	return 1;
1592 }
1593 
1594 /** Remove RR data */
1595 static int
perform_data_remove(RES * ssl,struct local_zones * zones,char * arg)1596 perform_data_remove(RES* ssl, struct local_zones* zones, char* arg)
1597 {
1598 	uint8_t rr[LDNS_RR_BUF_SIZE], *nm;
1599 	size_t len = sizeof(rr);
1600 	int status, nmlabs;
1601 	size_t nmlen, dname_len;
1602 
1603 	/* try to parse as a rr first */
1604 	status = sldns_str2wire_rr_buf(arg, rr, &len, &dname_len, 3600,
1605 				NULL, 0, NULL, 0);
1606 
1607 	/* try to parse as a domain name second */
1608 	if (status != 0) {
1609 		if (parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) {
1610 			local_zones_del_data(zones, nm,
1611 				nmlen, nmlabs, LDNS_RR_CLASS_IN);
1612 			free(nm);
1613 			return 1;
1614 		}
1615 		ssl_printf(ssl, "error cannot parse rr %s at %d: %s\n", arg,
1616 			LDNS_WIREPARSE_OFFSET(status),
1617 			sldns_get_errorstr_parse(status));
1618 		return 0;
1619 	}
1620 
1621 	/* handle the rr case */
1622 	if (!perform_data_remove_rr(ssl, zones, rr, len, dname_len, arg))
1623 		return 0;
1624 
1625 	return 1;
1626 }
1627 
1628 /** Do the local_data_remove command */
1629 static void
do_data_remove(RES * ssl,struct local_zones * zones,char * arg)1630 do_data_remove(RES* ssl, struct local_zones* zones, char* arg)
1631 {
1632 	if(!perform_data_remove(ssl, zones, arg))
1633 		return;
1634 	send_ok(ssl);
1635 }
1636 
1637 /** Do the local_datas_remove command */
1638 static void
do_datas_remove(struct daemon_remote * rc,RES * ssl,struct worker * worker)1639 do_datas_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker)
1640 {
1641 	char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_data_remove ";
1642 	int num = 0;
1643 	size_t cmd_len = strlen(buf);
1644 	while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
1645 		if(buf[0+cmd_len] == 0 ||
1646 			(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
1647 			break; /* zero byte line or end of transmission */
1648 #ifdef THREADS_DISABLED
1649 		/* distribute single item command */
1650 		if(rc) distribute_cmd(rc, ssl, buf);
1651 #else
1652 		(void)rc; /* unused */
1653 #endif
1654 		if(!perform_data_remove(ssl, worker->daemon->local_zones,
1655 			buf+cmd_len)) {
1656 			if(!ssl_printf(ssl, "error for input line: %s\n",
1657 				buf+cmd_len))
1658 				return;
1659 		}
1660 		else	num++;
1661 	}
1662 	(void)ssl_printf(ssl, "removed %d datas\n", num);
1663 }
1664 
1665 /** Add a new zone to view */
1666 static void
do_view_zone_add(RES * ssl,struct worker * worker,char * arg)1667 do_view_zone_add(RES* ssl, struct worker* worker, char* arg)
1668 {
1669 	char* arg2;
1670 	struct view* v;
1671 	if(!find_arg2(ssl, arg, &arg2))
1672 		return;
1673 	v = views_find_view(worker->env.views, arg, 1 /* get write lock*/);
1674 	if(!v) {
1675 		ssl_printf(ssl,"no view with name: %s\n", arg);
1676 		return;
1677 	}
1678 	if(!v->local_zones) {
1679 		if(!(v->local_zones = local_zones_create())){
1680 			lock_rw_unlock(&v->lock);
1681 			ssl_printf(ssl,"error out of memory\n");
1682 			return;
1683 		}
1684 		if(!v->isfirst) {
1685 			/* Global local-zone is not used for this view,
1686 			 * therefore add defaults to this view-specific
1687 			 * local-zone. */
1688 			struct config_file lz_cfg;
1689 			memset(&lz_cfg, 0, sizeof(lz_cfg));
1690 			local_zone_enter_defaults(v->local_zones, &lz_cfg);
1691 		}
1692 	}
1693 	do_zone_add(ssl, v->local_zones, arg2);
1694 	lock_rw_unlock(&v->lock);
1695 }
1696 
1697 /** Remove a zone from view */
1698 static void
do_view_zone_remove(RES * ssl,struct worker * worker,char * arg)1699 do_view_zone_remove(RES* ssl, struct worker* worker, char* arg)
1700 {
1701 	char* arg2;
1702 	struct view* v;
1703 	if(!find_arg2(ssl, arg, &arg2))
1704 		return;
1705 	v = views_find_view(worker->env.views, arg, 1 /* get write lock*/);
1706 	if(!v) {
1707 		ssl_printf(ssl,"no view with name: %s\n", arg);
1708 		return;
1709 	}
1710 	if(!v->local_zones) {
1711 		lock_rw_unlock(&v->lock);
1712 		send_ok(ssl);
1713 		return;
1714 	}
1715 	do_zone_remove(ssl, v->local_zones, arg2);
1716 	lock_rw_unlock(&v->lock);
1717 }
1718 
1719 /** Add new RR data to view */
1720 static void
do_view_data_add(RES * ssl,struct worker * worker,char * arg)1721 do_view_data_add(RES* ssl, struct worker* worker, char* arg)
1722 {
1723 	char* arg2;
1724 	struct view* v;
1725 	if(!find_arg2(ssl, arg, &arg2))
1726 		return;
1727 	v = views_find_view(worker->env.views, arg, 1 /* get write lock*/);
1728 	if(!v) {
1729 		ssl_printf(ssl,"no view with name: %s\n", arg);
1730 		return;
1731 	}
1732 	if(!v->local_zones) {
1733 		if(!(v->local_zones = local_zones_create())){
1734 			lock_rw_unlock(&v->lock);
1735 			ssl_printf(ssl,"error out of memory\n");
1736 			return;
1737 		}
1738 		if(!v->isfirst) {
1739 			/* Global local-zone is not used for this view,
1740 			 * therefore add defaults to this view-specific
1741 			 * local-zone. */
1742 			struct config_file lz_cfg;
1743 			memset(&lz_cfg, 0, sizeof(lz_cfg));
1744 			local_zone_enter_defaults(v->local_zones, &lz_cfg);
1745 		}
1746 	}
1747 	do_data_add(ssl, v->local_zones, arg2);
1748 	lock_rw_unlock(&v->lock);
1749 }
1750 
1751 /** Add new RR data from stdin to view */
1752 static void
do_view_datas_add(struct daemon_remote * rc,RES * ssl,struct worker * worker,char * arg)1753 do_view_datas_add(struct daemon_remote* rc, RES* ssl, struct worker* worker,
1754 	char* arg)
1755 {
1756 	struct view* v;
1757 	char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "view_local_data ";
1758 	size_t cmd_len;
1759 	int num = 0, line = 0;
1760 	v = views_find_view(worker->env.views, arg, 1 /* get write lock*/);
1761 	if(!v) {
1762 		ssl_printf(ssl,"no view with name: %s\n", arg);
1763 		return;
1764 	}
1765 	if(!v->local_zones) {
1766 		if(!(v->local_zones = local_zones_create())){
1767 			lock_rw_unlock(&v->lock);
1768 			ssl_printf(ssl,"error out of memory\n");
1769 			return;
1770 		}
1771 		if(!v->isfirst) {
1772 			/* Global local-zone is not used for this view,
1773 			 * therefore add defaults to this view-specific
1774 			 * local-zone. */
1775 			struct config_file lz_cfg;
1776 			memset(&lz_cfg, 0, sizeof(lz_cfg));
1777 			local_zone_enter_defaults(v->local_zones, &lz_cfg);
1778 		}
1779 	}
1780 	/* put the view name in the command buf */
1781 	(void)snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s ", arg);
1782 	cmd_len = strlen(buf);
1783 	while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
1784 		if(buf[0+cmd_len] == 0 ||
1785 			(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
1786 			break; /* zero byte line or end of transmission */
1787 #ifdef THREADS_DISABLED
1788 		/* distribute single item command */
1789 		if(rc) distribute_cmd(rc, ssl, buf);
1790 #else
1791 		(void)rc; /* unused */
1792 #endif
1793 		line++;
1794 		if(perform_data_add(ssl, v->local_zones, buf+cmd_len, line))
1795 			num++;
1796 	}
1797 	lock_rw_unlock(&v->lock);
1798 	(void)ssl_printf(ssl, "added %d datas\n", num);
1799 }
1800 
1801 /** Remove RR data from view */
1802 static void
do_view_data_remove(RES * ssl,struct worker * worker,char * arg)1803 do_view_data_remove(RES* ssl, struct worker* worker, char* arg)
1804 {
1805 	char* arg2;
1806 	struct view* v;
1807 	if(!find_arg2(ssl, arg, &arg2))
1808 		return;
1809 	v = views_find_view(worker->env.views, arg, 1 /* get write lock*/);
1810 	if(!v) {
1811 		ssl_printf(ssl,"no view with name: %s\n", arg);
1812 		return;
1813 	}
1814 	if(!v->local_zones) {
1815 		lock_rw_unlock(&v->lock);
1816 		send_ok(ssl);
1817 		return;
1818 	}
1819 	do_data_remove(ssl, v->local_zones, arg2);
1820 	lock_rw_unlock(&v->lock);
1821 }
1822 
1823 /** Remove RR data from stdin from view */
1824 static void
do_view_datas_remove(struct daemon_remote * rc,RES * ssl,struct worker * worker,char * arg)1825 do_view_datas_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker,
1826 	char* arg)
1827 {
1828 	struct view* v;
1829 	char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "view_local_data_remove ";
1830 	int num = 0;
1831 	size_t cmd_len;
1832 	v = views_find_view(worker->env.views, arg, 1 /* get write lock*/);
1833 	if(!v) {
1834 		ssl_printf(ssl,"no view with name: %s\n", arg);
1835 		return;
1836 	}
1837 	if(!v->local_zones){
1838 		lock_rw_unlock(&v->lock);
1839 		ssl_printf(ssl, "removed 0 datas\n");
1840 		return;
1841 	}
1842 	/* put the view name in the command buf */
1843 	(void)snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s ", arg);
1844 	cmd_len = strlen(buf);
1845 	while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
1846 		if(buf[0+cmd_len] == 0 ||
1847 			(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
1848 			break; /* zero byte line or end of transmission */
1849 #ifdef THREADS_DISABLED
1850 		/* distribute single item command */
1851 		if(rc) distribute_cmd(rc, ssl, buf);
1852 #else
1853 		(void)rc; /* unused */
1854 #endif
1855 		if(!perform_data_remove(ssl, v->local_zones, buf+cmd_len)) {
1856 			if(!ssl_printf(ssl, "error for input line: %s\n",
1857 				buf+cmd_len))
1858 				return;
1859 		}
1860 		else	num++;
1861 	}
1862 	lock_rw_unlock(&v->lock);
1863 	(void)ssl_printf(ssl, "removed %d datas\n", num);
1864 }
1865 
1866 /** information for the domain search */
1867 struct cache_lookup_info {
1868 	/** The connection to print on. */
1869 	RES* ssl;
1870 	/** The worker. */
1871 	struct worker* worker;
1872 	/** The domain, in wireformat. */
1873 	uint8_t* nm;
1874 	/** The length of nm. */
1875 	size_t nmlen;
1876 };
1877 
1878 #ifdef CLIENT_SUBNET
1879 static void addrtree_traverse_visit_node(struct addrnode* n, addrkey_t* addr,
1880 	size_t addr_size, int is_ipv6, time_t now, struct query_info* q,
1881 	void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
1882 		size_t, int, addrlen_t, int, time_t, void*), void* arg);
1883 
1884 /** Lookup in subnet addrtree */
1885 static void
cache_lookup_subnet_addrnode(struct query_info * q,struct reply_info * d,addrkey_t * addr,size_t addr_size,int is_ipv6,addrlen_t scope,int only_match_scope_zero,time_t ttl,void * arg)1886 cache_lookup_subnet_addrnode(struct query_info* q, struct reply_info* d,
1887 	addrkey_t* addr, size_t addr_size, int is_ipv6, addrlen_t scope,
1888 	int only_match_scope_zero, time_t ttl, void* arg)
1889 {
1890 	size_t i;
1891 	char s[65535], tp[32], cl[32], rc[32], fg[32], astr[64];
1892 	struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
1893 	if(is_ipv6) {
1894 		if(addr_size < 16 || inet_ntop(AF_INET6, addr, astr,
1895 			sizeof(astr)) == NULL)
1896 			snprintf(astr, sizeof(astr), "(inet6ntoperror)");
1897 	} else {
1898 		if(addr_size < 4 || inet_ntop(AF_INET, addr, astr,
1899 			sizeof(astr)) == NULL)
1900 			snprintf(astr, sizeof(astr), "(inetntoperror)");
1901 	}
1902 	sldns_wire2str_dname_buf(q->qname, q->qname_len, s, sizeof(s));
1903 	sldns_wire2str_type_buf(q->qtype, tp, sizeof(tp));
1904 	sldns_wire2str_class_buf(q->qclass, cl, sizeof(cl));
1905 	sldns_wire2str_rcode_buf(FLAGS_GET_RCODE(d->flags),
1906 		rc, sizeof(rc));
1907 	snprintf(fg, sizeof(fg), "%s%s%s%s%s%s%s%s",
1908 		((d->flags&BIT_QR)?" QR":""),
1909 		((d->flags&BIT_AA)?" AA":""),
1910 		((d->flags&BIT_TC)?" TC":""),
1911 		((d->flags&BIT_RD)?" RD":""),
1912 		((d->flags&BIT_RA)?" RA":""),
1913 		((d->flags&BIT_Z)?" Z":""),
1914 		((d->flags&BIT_AD)?" AD":""),
1915 		((d->flags&BIT_CD)?" CD":""));
1916 	if(!rrset_array_lock(d->ref, d->rrset_count,
1917 		*inf->worker->env.now)) {
1918 		/* rrsets have timed out or do not exist */
1919 		return;
1920 	}
1921 	if(!ssl_printf(inf->ssl, "subnet %s/%d%s %s %s %s " ARG_LL "d\n", astr,
1922 		(int)scope, (only_match_scope_zero?" scope_zero":""),
1923 		s, cl, tp, (long long)(ttl-*inf->worker->env.now))) {
1924 		rrset_array_unlock(d->ref, d->rrset_count);
1925 		return;
1926 	}
1927 	ssl_printf(inf->ssl,
1928 		"subnet msg %s %s %s%s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
1929 		s, cl, tp, fg, rc,
1930 		(int)d->flags, (int)d->qdcount,
1931 		(long long)(d->ttl-*inf->worker->env.now),
1932 		(int)d->security,
1933 		(unsigned)d->an_numrrsets,
1934 		(unsigned)d->ns_numrrsets,
1935 		(unsigned)d->ar_numrrsets,
1936 		(int)d->reason_bogus,
1937 		d->reason_bogus_str?d->reason_bogus_str:"");
1938 	for(i=0; i<d->rrset_count; i++) {
1939 		struct ub_packed_rrset_key* rk = d->rrsets[i];
1940 		struct packed_rrset_data* rd = (struct packed_rrset_data*)rk->entry.data;
1941 		size_t j;
1942 		for(j=0; j<rd->count + rd->rrsig_count; j++) {
1943 			if(!packed_rr_to_string(rk, j,
1944 				*inf->worker->env.now, s, sizeof(s))) {
1945 				ssl_printf(inf->ssl, "BADRR\n");
1946 			} else {
1947 				ssl_printf(inf->ssl, "%s", s);
1948 			}
1949 		}
1950 	}
1951 	rrset_array_unlock(d->ref, d->rrset_count);
1952 	ssl_printf(inf->ssl, "\n");
1953 }
1954 
1955 /** Visit an edge in subnet addrtree traverse */
1956 static void
addrtree_traverse_visit_edge(struct addredge * edge,addrkey_t * addr,size_t addr_size,int is_ipv6,time_t now,struct query_info * q,void (* func)(struct query_info *,struct reply_info *,addrkey_t *,size_t,int,addrlen_t,int,time_t,void *),void * arg)1957 addrtree_traverse_visit_edge(struct addredge* edge, addrkey_t* addr,
1958 	size_t addr_size, int is_ipv6, time_t now, struct query_info* q,
1959 	void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
1960 		size_t, int, addrlen_t, int, time_t, void*), void* arg)
1961 {
1962 	size_t n;
1963 	addrlen_t addrlen;
1964 	if(!edge || !edge->node)
1965 		return;
1966 	addrlen = edge->len;
1967 	/* ceil() */
1968 	n = (size_t)((addrlen / KEYWIDTH) + ((addrlen % KEYWIDTH != 0)?1:0));
1969 	if(n > addr_size)
1970 		n = addr_size;
1971 	memset(addr, 0, addr_size);
1972 	memcpy(addr, edge->str, n);
1973 	addrtree_traverse_visit_node(edge->node, addr, addr_size, is_ipv6,
1974 		now, q, func, arg);
1975 }
1976 
1977 /** Visit a node in subnet addrtree traverse */
1978 static void
addrtree_traverse_visit_node(struct addrnode * n,addrkey_t * addr,size_t addr_size,int is_ipv6,time_t now,struct query_info * q,void (* func)(struct query_info *,struct reply_info *,addrkey_t *,size_t,int,addrlen_t,int,time_t,void *),void * arg)1979 addrtree_traverse_visit_node(struct addrnode* n, addrkey_t* addr,
1980 	size_t addr_size, int is_ipv6, time_t now, struct query_info* q,
1981 	void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
1982 		size_t, int, addrlen_t, int, time_t, void*), void* arg)
1983 {
1984 	/* If this node has data, and not expired. */
1985 	if(n->elem && n->ttl >= now) {
1986 		func(q, (struct reply_info*)n->elem, addr, addr_size, is_ipv6,
1987 			n->scope, n->only_match_scope_zero, n->ttl, arg);
1988 	}
1989 	/* Traverse edges. */
1990 	addrtree_traverse_visit_edge(n->edge[0], addr, addr_size, is_ipv6,
1991 		now, q, func, arg);
1992 	addrtree_traverse_visit_edge(n->edge[1], addr, addr_size, is_ipv6,
1993 		now, q, func, arg);
1994 }
1995 
1996 /** Traverse subnet addrtree */
1997 static void
addrtree_traverse(struct addrtree * tree,int is_ipv6,time_t now,struct query_info * q,void (* func)(struct query_info *,struct reply_info *,addrkey_t *,size_t,int,addrlen_t,int,time_t,void *),void * arg)1998 addrtree_traverse(struct addrtree* tree, int is_ipv6, time_t now,
1999 	struct query_info* q,
2000 	void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
2001 		size_t, int, addrlen_t, int, time_t, void*), void* arg)
2002 {
2003 	uint8_t addr[16]; /* Large enough for IPv4 and IPv6. */
2004 	memset(addr, 0, sizeof(addr));
2005 	addrtree_traverse_visit_node(tree->root, (addrkey_t*)addr,
2006 		sizeof(addr), is_ipv6, now, q, func, arg);
2007 }
2008 
2009 /** Lookup cache_lookup for subnet content. */
2010 static void
cache_lookup_subnet_msg(struct lruhash_entry * e,void * arg)2011 cache_lookup_subnet_msg(struct lruhash_entry* e, void* arg)
2012 {
2013 	struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
2014 	struct msgreply_entry *k = (struct msgreply_entry*)e->key;
2015 	struct subnet_msg_cache_data* d =
2016 		(struct subnet_msg_cache_data*)e->data;
2017 	if(!dname_subdomain_c(k->key.qname, inf->nm))
2018 		return;
2019 
2020 	if(d->tree4) {
2021 		addrtree_traverse(d->tree4, 0, *inf->worker->env.now, &k->key,
2022 			&cache_lookup_subnet_addrnode, inf);
2023 	}
2024 	if(d->tree6) {
2025 		addrtree_traverse(d->tree6, 1, *inf->worker->env.now, &k->key,
2026 			&cache_lookup_subnet_addrnode, inf);
2027 	}
2028 }
2029 #endif /* CLIENT_SUBNET */
2030 
2031 static void
cache_lookup_rrset(struct lruhash_entry * e,void * arg)2032 cache_lookup_rrset(struct lruhash_entry* e, void* arg)
2033 {
2034 	struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
2035 	struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key;
2036 	struct packed_rrset_data* d = (struct packed_rrset_data*)e->data;
2037 	if(*inf->worker->env.now < d->ttl &&
2038 		k->id != 0 && /* not deleted */
2039 		dname_subdomain_c(k->rk.dname, inf->nm)) {
2040 		size_t i;
2041 		for(i=0; i<d->count + d->rrsig_count; i++) {
2042 			char s[65535];
2043 			if(!packed_rr_to_string(k, i, *inf->worker->env.now,
2044 				s, sizeof(s))) {
2045 				ssl_printf(inf->ssl, "BADRR\n");
2046 				return;
2047 			}
2048 			ssl_printf(inf->ssl, "%s", s);
2049 		}
2050 		ssl_printf(inf->ssl, "\n");
2051 	}
2052 }
2053 
2054 static void
cache_lookup_msg(struct lruhash_entry * e,void * arg)2055 cache_lookup_msg(struct lruhash_entry* e, void* arg)
2056 {
2057 	struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
2058 	struct msgreply_entry* k = (struct msgreply_entry*)e->key;
2059 	struct reply_info* d = (struct reply_info*)e->data;
2060 	if(*inf->worker->env.now < d->ttl &&
2061 		dname_subdomain_c(k->key.qname, inf->nm)) {
2062 		size_t i;
2063 		char s[65535], tp[32], cl[32], rc[32], fg[32];
2064 		sldns_wire2str_dname_buf(k->key.qname, k->key.qname_len,
2065 			s, sizeof(s));
2066 		sldns_wire2str_type_buf(k->key.qtype, tp, sizeof(tp));
2067 		sldns_wire2str_class_buf(k->key.qclass, cl, sizeof(cl));
2068 		sldns_wire2str_rcode_buf(FLAGS_GET_RCODE(d->flags),
2069 			rc, sizeof(rc));
2070 		snprintf(fg, sizeof(fg), "%s%s%s%s%s%s%s%s",
2071 			((d->flags&BIT_QR)?" QR":""),
2072 			((d->flags&BIT_AA)?" AA":""),
2073 			((d->flags&BIT_TC)?" TC":""),
2074 			((d->flags&BIT_RD)?" RD":""),
2075 			((d->flags&BIT_RA)?" RA":""),
2076 			((d->flags&BIT_Z)?" Z":""),
2077 			((d->flags&BIT_AD)?" AD":""),
2078 			((d->flags&BIT_CD)?" CD":""));
2079 		if(!rrset_array_lock(d->ref, d->rrset_count,
2080 			*inf->worker->env.now)) {
2081 			/* rrsets have timed out or do not exist */
2082 			return;
2083 		}
2084 		ssl_printf(inf->ssl,
2085 			"msg %s %s %s%s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
2086 			s, cl, tp, fg, rc,
2087 			(int)d->flags, (int)d->qdcount,
2088 			(long long)(d->ttl-*inf->worker->env.now),
2089 			(int)d->security,
2090 			(unsigned)d->an_numrrsets,
2091 			(unsigned)d->ns_numrrsets,
2092 			(unsigned)d->ar_numrrsets,
2093 			(int)d->reason_bogus,
2094 			d->reason_bogus_str?d->reason_bogus_str:"");
2095 		for(i=0; i<d->rrset_count; i++) {
2096 			struct ub_packed_rrset_key* rk = d->rrsets[i];
2097 			struct packed_rrset_data* rd = (struct packed_rrset_data*)rk->entry.data;
2098 			size_t j;
2099 			for(j=0; j<rd->count + rd->rrsig_count; j++) {
2100 				if(!packed_rr_to_string(rk, j,
2101 					*inf->worker->env.now, s, sizeof(s))) {
2102 					rrset_array_unlock(d->ref, d->rrset_count);
2103 					ssl_printf(inf->ssl, "BADRR\n");
2104 					return;
2105 				}
2106 				ssl_printf(inf->ssl, "%s", s);
2107 			}
2108 		}
2109 		rrset_array_unlock(d->ref, d->rrset_count);
2110 		ssl_printf(inf->ssl, "\n");
2111 	}
2112 }
2113 
2114 /** perform cache search for domain */
2115 static void
do_cache_lookup_domain(RES * ssl,struct worker * worker,uint8_t * nm,size_t nmlen)2116 do_cache_lookup_domain(RES* ssl, struct worker* worker, uint8_t* nm,
2117 	size_t nmlen)
2118 {
2119 #ifdef CLIENT_SUBNET
2120 	int m;
2121 	struct subnet_env* sn_env = NULL;
2122 #endif /* CLIENT_SUBNET */
2123 	struct cache_lookup_info inf;
2124 	inf.ssl = ssl;
2125 	inf.worker = worker;
2126 	inf.nm = nm;
2127 	inf.nmlen = nmlen;
2128 
2129 #ifdef CLIENT_SUBNET
2130 	m = modstack_find(worker->env.modstack, "subnetcache");
2131 	if(m != -1) sn_env = (struct subnet_env*)worker->env.modinfo[m];
2132 	if(sn_env) {
2133 		lock_rw_rdlock(&sn_env->biglock);
2134 		slabhash_traverse(sn_env->subnet_msg_cache, 0,
2135 			&cache_lookup_subnet_msg, &inf);
2136 		lock_rw_unlock(&sn_env->biglock);
2137 	}
2138 #endif /* CLIENT_SUBNET */
2139 
2140 	slabhash_traverse(&worker->env.rrset_cache->table, 0,
2141 		&cache_lookup_rrset, &inf);
2142 	slabhash_traverse(worker->env.msg_cache, 0, &cache_lookup_msg, &inf);
2143 }
2144 
2145 /** cache lookup of domain */
2146 static void
do_cache_lookup(RES * ssl,struct worker * worker,char * arg)2147 do_cache_lookup(RES* ssl, struct worker* worker, char* arg)
2148 {
2149 	uint8_t nm[LDNS_MAX_DOMAINLEN+1];
2150 	size_t nmlen;
2151 	int status;
2152 	char* s = arg, *next = NULL;
2153 	int allow_long = 0;
2154 
2155 	if(arg[0] == '+' && arg[1] == 't' && (arg[2]==' ' || arg[2]=='\t')) {
2156 		allow_long = 1;
2157 		s = arg+2;
2158 	}
2159 
2160 	/* Find the commandline arguments of domains. */
2161 	while(s && *s != 0) {
2162 		s = skipwhite(s);
2163 		if(*s == 0)
2164 			break;
2165 		if(strchr(s, ' ') || strchr(s, '\t')) {
2166 			char* sp = strchr(s, ' ');
2167 			if(strchr(s, '\t') != 0 && strchr(s, '\t') < sp)
2168 				sp = strchr(s, '\t');
2169 			*sp = 0;
2170 			next = sp+1;
2171 		} else {
2172 			next = NULL;
2173 		}
2174 
2175 		nmlen = sizeof(nm);
2176 		status = sldns_str2wire_dname_buf(s, nm, &nmlen);
2177 		if(status != 0) {
2178 			ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", s,
2179 				LDNS_WIREPARSE_OFFSET(status),
2180 				sldns_get_errorstr_parse(status));
2181 			return;
2182 		}
2183 		if(!allow_long && dname_count_labels(nm) < 3) {
2184 			ssl_printf(ssl, "error name too short: '%s'. Need example.com. or longer, short names take very long, use +t to allow them.\n", s);
2185 			return;
2186 		}
2187 
2188 		do_cache_lookup_domain(ssl, worker, nm, nmlen);
2189 
2190 		s = next;
2191 	}
2192 }
2193 
2194 /** cache lookup of nameservers */
2195 static void
do_lookup(RES * ssl,struct worker * worker,char * arg)2196 do_lookup(RES* ssl, struct worker* worker, char* arg)
2197 {
2198 	uint8_t* nm;
2199 	int nmlabs;
2200 	size_t nmlen;
2201 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
2202 		return;
2203 	(void)print_deleg_lookup(ssl, worker, nm, nmlen, nmlabs);
2204 	free(nm);
2205 }
2206 
2207 /** flush something from rrset and msg caches */
2208 static void
do_cache_remove(struct worker * worker,uint8_t * nm,size_t nmlen,uint16_t t,uint16_t c,int remcachedb)2209 do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
2210 	uint16_t t, uint16_t c, int remcachedb)
2211 {
2212 	hashvalue_type h;
2213 	struct query_info k;
2214 	rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c, 0);
2215 	if(t == LDNS_RR_TYPE_SOA)
2216 		rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c,
2217 			PACKED_RRSET_SOA_NEG);
2218 	k.qname = nm;
2219 	k.qname_len = nmlen;
2220 	k.qtype = t;
2221 	k.qclass = c;
2222 	k.local_alias = NULL;
2223 	h = query_info_hash(&k, 0);
2224 	slabhash_remove(worker->env.msg_cache, h, &k);
2225 	if(t == LDNS_RR_TYPE_AAAA) {
2226 		/* for AAAA also flush dns64 bit_cd packet */
2227 		h = query_info_hash(&k, BIT_CD);
2228 		slabhash_remove(worker->env.msg_cache, h, &k);
2229 	}
2230 #ifdef USE_CACHEDB
2231 	if(remcachedb && worker->env.cachedb_enabled)
2232 		cachedb_msg_remove_qinfo(&worker->env, &k);
2233 #else
2234 	(void)remcachedb;
2235 #endif
2236 }
2237 
2238 /** parse '+c' option, modifies string to return remainder. */
2239 static int
parse_remcachedb(RES * ssl,char ** arg,int * pc)2240 parse_remcachedb(RES* ssl, char** arg, int* pc)
2241 {
2242 	*arg = skipwhite(*arg);
2243 	if((*arg)[0] == '+' && (*arg)[1] == 'c') {
2244 		char* arg2;
2245 		*pc = 1;
2246 		if(!find_arg2(ssl, *arg, &arg2))
2247 			return 0;
2248 		*arg = arg2;
2249 		return 1;
2250 	}
2251 	/* The option was not found, no problem */
2252 	return 1;
2253 }
2254 
2255 /** flush a type */
2256 static void
do_flush_type(RES * ssl,struct worker * worker,char * arg)2257 do_flush_type(RES* ssl, struct worker* worker, char* arg)
2258 {
2259 	uint8_t* nm;
2260 	int nmlabs;
2261 	size_t nmlen;
2262 	char* arg2;
2263 	uint16_t t;
2264 	int pc = 0; /* '+c' option */
2265 	if(!parse_remcachedb(ssl, &arg, &pc))
2266 		return;
2267 	if(!find_arg2(ssl, arg, &arg2))
2268 		return;
2269 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
2270 		return;
2271 	t = sldns_get_rr_type_by_name(arg2);
2272 	if(t == 0 && strcmp(arg2, "TYPE0") != 0) {
2273 		(void)ssl_printf(ssl, "error parsing RRset type: '%s'\n", arg2);
2274 		free(nm);
2275 		return;
2276 	}
2277 	do_cache_remove(worker, nm, nmlen, t, LDNS_RR_CLASS_IN, pc);
2278 
2279 	free(nm);
2280 	send_ok(ssl);
2281 }
2282 
2283 /** flush statistics */
2284 static void
do_flush_stats(RES * ssl,struct worker * worker)2285 do_flush_stats(RES* ssl, struct worker* worker)
2286 {
2287 	worker_stats_clear(worker);
2288 	send_ok(ssl);
2289 }
2290 
2291 /**
2292  * Local info for deletion functions
2293  */
2294 struct del_info {
2295 	/** worker */
2296 	struct worker* worker;
2297 	/** name to delete */
2298 	uint8_t* name;
2299 	/** length */
2300 	size_t len;
2301 	/** labels */
2302 	int labs;
2303 	/** time to invalidate to */
2304 	time_t expired;
2305 	/** number of rrsets removed */
2306 	size_t num_rrsets;
2307 	/** number of msgs removed */
2308 	size_t num_msgs;
2309 	/** number of key entries removed */
2310 	size_t num_keys;
2311 	/** length of addr */
2312 	socklen_t addrlen;
2313 	/** socket address for host deletion */
2314 	struct sockaddr_storage addr;
2315 	/** if cachedb information should be flushed too */
2316 	int remcachedb;
2317 };
2318 
2319 /** callback to delete hosts in infra cache */
2320 static void
infra_del_host(struct lruhash_entry * e,void * arg)2321 infra_del_host(struct lruhash_entry* e, void* arg)
2322 {
2323 	/* entry is locked */
2324 	struct del_info* inf = (struct del_info*)arg;
2325 	struct infra_key* k = (struct infra_key*)e->key;
2326 	if(sockaddr_cmp(&inf->addr, inf->addrlen, &k->addr, k->addrlen) == 0) {
2327 		struct infra_data* d = (struct infra_data*)e->data;
2328 		d->probedelay = 0;
2329 		d->timeout_A = 0;
2330 		d->timeout_AAAA = 0;
2331 		d->timeout_other = 0;
2332 		rtt_init(&d->rtt);
2333 		if(d->ttl > inf->expired) {
2334 			d->ttl = inf->expired;
2335 			inf->num_keys++;
2336 		}
2337 	}
2338 }
2339 
2340 /** flush infra cache */
2341 static void
do_flush_infra(RES * ssl,struct worker * worker,char * arg)2342 do_flush_infra(RES* ssl, struct worker* worker, char* arg)
2343 {
2344 	struct sockaddr_storage addr;
2345 	socklen_t len;
2346 	struct del_info inf;
2347 	if(strcmp(arg, "all") == 0) {
2348 		slabhash_clear(worker->env.infra_cache->hosts);
2349 		send_ok(ssl);
2350 		return;
2351 	}
2352 	if(!ipstrtoaddr(arg, UNBOUND_DNS_PORT, &addr, &len)) {
2353 		(void)ssl_printf(ssl, "error parsing ip addr: '%s'\n", arg);
2354 		return;
2355 	}
2356 	/* delete all entries from cache */
2357 	/* what we do is to set them all expired */
2358 	inf.worker = worker;
2359 	inf.name = 0;
2360 	inf.len = 0;
2361 	inf.labs = 0;
2362 	inf.expired = *worker->env.now;
2363 	inf.expired -= 3; /* handle 3 seconds skew between threads */
2364 	inf.num_rrsets = 0;
2365 	inf.num_msgs = 0;
2366 	inf.num_keys = 0;
2367 	inf.addrlen = len;
2368 	inf.remcachedb = 0;
2369 	memmove(&inf.addr, &addr, len);
2370 	slabhash_traverse(worker->env.infra_cache->hosts, 1, &infra_del_host,
2371 		&inf);
2372 	send_ok(ssl);
2373 }
2374 
2375 /** flush requestlist */
2376 static void
do_flush_requestlist(RES * ssl,struct worker * worker)2377 do_flush_requestlist(RES* ssl, struct worker* worker)
2378 {
2379 	mesh_delete_all(worker->env.mesh);
2380 	send_ok(ssl);
2381 }
2382 
2383 /** callback to delete rrsets in a zone */
2384 static void
zone_del_rrset(struct lruhash_entry * e,void * arg)2385 zone_del_rrset(struct lruhash_entry* e, void* arg)
2386 {
2387 	/* entry is locked */
2388 	struct del_info* inf = (struct del_info*)arg;
2389 	struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key;
2390 	if(dname_subdomain_c(k->rk.dname, inf->name)) {
2391 		struct packed_rrset_data* d =
2392 			(struct packed_rrset_data*)e->data;
2393 		if(d->ttl > inf->expired) {
2394 			d->ttl = inf->expired;
2395 			if(d->ttl_add > inf->expired)
2396 				d->ttl_add = inf->expired; /* for 0TTL rrsets,
2397 					means that d->ttl_add <= d->ttl */
2398 			inf->num_rrsets++;
2399 		}
2400 	}
2401 }
2402 
2403 /** callback to delete messages in a zone */
2404 static void
zone_del_msg(struct lruhash_entry * e,void * arg)2405 zone_del_msg(struct lruhash_entry* e, void* arg)
2406 {
2407 	/* entry is locked */
2408 	struct del_info* inf = (struct del_info*)arg;
2409 	struct msgreply_entry* k = (struct msgreply_entry*)e->key;
2410 	if(dname_subdomain_c(k->key.qname, inf->name)) {
2411 		struct reply_info* d = (struct reply_info*)e->data;
2412 		if(d->ttl > inf->expired) {
2413 			d->ttl = inf->expired;
2414 			d->prefetch_ttl = inf->expired;
2415 			d->serve_expired_ttl = inf->expired;
2416 			inf->num_msgs++;
2417 		}
2418 #ifdef USE_CACHEDB
2419 		if(inf->remcachedb && inf->worker->env.cachedb_enabled)
2420 			cachedb_msg_remove_qinfo(&inf->worker->env, &k->key);
2421 #endif
2422 	}
2423 }
2424 
2425 /** callback to delete keys in zone */
2426 static void
zone_del_kcache(struct lruhash_entry * e,void * arg)2427 zone_del_kcache(struct lruhash_entry* e, void* arg)
2428 {
2429 	/* entry is locked */
2430 	struct del_info* inf = (struct del_info*)arg;
2431 	struct key_entry_key* k = (struct key_entry_key*)e->key;
2432 	if(dname_subdomain_c(k->name, inf->name)) {
2433 		struct key_entry_data* d = (struct key_entry_data*)e->data;
2434 		if(d->ttl > inf->expired) {
2435 			d->ttl = inf->expired;
2436 			inf->num_keys++;
2437 		}
2438 	}
2439 }
2440 
2441 /** remove all rrsets and keys from zone from cache */
2442 static void
do_flush_zone(RES * ssl,struct worker * worker,char * arg)2443 do_flush_zone(RES* ssl, struct worker* worker, char* arg)
2444 {
2445 	uint8_t* nm;
2446 	int nmlabs;
2447 	size_t nmlen;
2448 	struct del_info inf;
2449 	int pc = 0; /* '+c' option */
2450 	if(!parse_remcachedb(ssl, &arg, &pc))
2451 		return;
2452 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
2453 		return;
2454 	/* delete all RRs and key entries from zone */
2455 	/* what we do is to set them all expired */
2456 	inf.worker = worker;
2457 	inf.name = nm;
2458 	inf.len = nmlen;
2459 	inf.labs = nmlabs;
2460 	inf.expired = *worker->env.now;
2461 	inf.expired -= 3; /* handle 3 seconds skew between threads */
2462 	inf.num_rrsets = 0;
2463 	inf.num_msgs = 0;
2464 	inf.num_keys = 0;
2465 	inf.remcachedb = pc;
2466 	slabhash_traverse(&worker->env.rrset_cache->table, 1,
2467 		&zone_del_rrset, &inf);
2468 
2469 	slabhash_traverse(worker->env.msg_cache, 1, &zone_del_msg, &inf);
2470 
2471 	/* and validator cache */
2472 	if(worker->env.key_cache) {
2473 		slabhash_traverse(worker->env.key_cache->slab, 1,
2474 			&zone_del_kcache, &inf);
2475 	}
2476 
2477 	free(nm);
2478 
2479 	(void)ssl_printf(ssl, "ok removed %lu rrsets, %lu messages "
2480 		"and %lu key entries\n", (unsigned long)inf.num_rrsets,
2481 		(unsigned long)inf.num_msgs, (unsigned long)inf.num_keys);
2482 }
2483 
2484 /** callback to delete bogus rrsets */
2485 static void
bogus_del_rrset(struct lruhash_entry * e,void * arg)2486 bogus_del_rrset(struct lruhash_entry* e, void* arg)
2487 {
2488 	/* entry is locked */
2489 	struct del_info* inf = (struct del_info*)arg;
2490 	struct packed_rrset_data* d = (struct packed_rrset_data*)e->data;
2491 	if(d->security == sec_status_bogus && d->ttl > inf->expired) {
2492 		d->ttl = inf->expired;
2493 		inf->num_rrsets++;
2494 	}
2495 }
2496 
2497 /** callback to delete bogus messages */
2498 static void
bogus_del_msg(struct lruhash_entry * e,void * arg)2499 bogus_del_msg(struct lruhash_entry* e, void* arg)
2500 {
2501 	/* entry is locked */
2502 	struct del_info* inf = (struct del_info*)arg;
2503 	struct reply_info* d = (struct reply_info*)e->data;
2504 	if(d->security == sec_status_bogus && d->ttl > inf->expired) {
2505 		d->ttl = inf->expired;
2506 		d->prefetch_ttl = inf->expired;
2507 		d->serve_expired_ttl = inf->expired;
2508 		inf->num_msgs++;
2509 #ifdef USE_CACHEDB
2510 		if(inf->remcachedb && inf->worker->env.cachedb_enabled)
2511 			cachedb_msg_remove_qinfo(&inf->worker->env,
2512 				&((struct msgreply_entry*)e->key)->key);
2513 #endif
2514 	}
2515 }
2516 
2517 /** callback to delete bogus keys */
2518 static void
bogus_del_kcache(struct lruhash_entry * e,void * arg)2519 bogus_del_kcache(struct lruhash_entry* e, void* arg)
2520 {
2521 	/* entry is locked */
2522 	struct del_info* inf = (struct del_info*)arg;
2523 	struct key_entry_data* d = (struct key_entry_data*)e->data;
2524 	if(d->isbad && d->ttl > inf->expired) {
2525 		d->ttl = inf->expired;
2526 		inf->num_keys++;
2527 	}
2528 }
2529 
2530 /** remove all bogus rrsets, msgs and keys from cache */
2531 static void
do_flush_bogus(RES * ssl,struct worker * worker,char * arg)2532 do_flush_bogus(RES* ssl, struct worker* worker, char* arg)
2533 {
2534 	struct del_info inf;
2535 	int pc = 0; /* '+c' option */
2536 	if(!parse_remcachedb(ssl, &arg, &pc))
2537 		return;
2538 	/* what we do is to set them all expired */
2539 	inf.worker = worker;
2540 	inf.expired = *worker->env.now;
2541 	inf.expired -= 3; /* handle 3 seconds skew between threads */
2542 	inf.num_rrsets = 0;
2543 	inf.num_msgs = 0;
2544 	inf.num_keys = 0;
2545 	inf.remcachedb = pc;
2546 	slabhash_traverse(&worker->env.rrset_cache->table, 1,
2547 		&bogus_del_rrset, &inf);
2548 
2549 	slabhash_traverse(worker->env.msg_cache, 1, &bogus_del_msg, &inf);
2550 
2551 	/* and validator cache */
2552 	if(worker->env.key_cache) {
2553 		slabhash_traverse(worker->env.key_cache->slab, 1,
2554 			&bogus_del_kcache, &inf);
2555 	}
2556 
2557 	(void)ssl_printf(ssl, "ok removed %lu rrsets, %lu messages "
2558 		"and %lu key entries\n", (unsigned long)inf.num_rrsets,
2559 		(unsigned long)inf.num_msgs, (unsigned long)inf.num_keys);
2560 }
2561 
2562 /** callback to delete negative and servfail rrsets */
2563 static void
negative_del_rrset(struct lruhash_entry * e,void * arg)2564 negative_del_rrset(struct lruhash_entry* e, void* arg)
2565 {
2566 	/* entry is locked */
2567 	struct del_info* inf = (struct del_info*)arg;
2568 	struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key;
2569 	struct packed_rrset_data* d = (struct packed_rrset_data*)e->data;
2570 	/* delete the parentside negative cache rrsets,
2571 	 * these are nameserver rrsets that failed lookup, rdata empty */
2572 	if((k->rk.flags & PACKED_RRSET_PARENT_SIDE) && d->count == 1 &&
2573 		d->rrsig_count == 0 && d->rr_len[0] == 0 &&
2574 		d->ttl > inf->expired) {
2575 		d->ttl = inf->expired;
2576 		inf->num_rrsets++;
2577 	}
2578 }
2579 
2580 /** callback to delete negative and servfail messages */
2581 static void
negative_del_msg(struct lruhash_entry * e,void * arg)2582 negative_del_msg(struct lruhash_entry* e, void* arg)
2583 {
2584 	/* entry is locked */
2585 	struct del_info* inf = (struct del_info*)arg;
2586 	struct reply_info* d = (struct reply_info*)e->data;
2587 	/* rcode not NOERROR: NXDOMAIN, SERVFAIL, ..: an nxdomain or error
2588 	 * or NOERROR rcode with ANCOUNT==0: a NODATA answer */
2589 	if((FLAGS_GET_RCODE(d->flags) != 0 || d->an_numrrsets == 0) &&
2590 		d->ttl > inf->expired) {
2591 		d->ttl = inf->expired;
2592 		d->prefetch_ttl = inf->expired;
2593 		d->serve_expired_ttl = inf->expired;
2594 		inf->num_msgs++;
2595 #ifdef USE_CACHEDB
2596 		if(inf->remcachedb && inf->worker->env.cachedb_enabled)
2597 			cachedb_msg_remove_qinfo(&inf->worker->env,
2598 				&((struct msgreply_entry*)e->key)->key);
2599 #endif
2600 	}
2601 }
2602 
2603 /** callback to delete negative key entries */
2604 static void
negative_del_kcache(struct lruhash_entry * e,void * arg)2605 negative_del_kcache(struct lruhash_entry* e, void* arg)
2606 {
2607 	/* entry is locked */
2608 	struct del_info* inf = (struct del_info*)arg;
2609 	struct key_entry_data* d = (struct key_entry_data*)e->data;
2610 	/* could be bad because of lookup failure on the DS, DNSKEY, which
2611 	 * was nxdomain or servfail, and thus a result of negative lookups */
2612 	if(d->isbad && d->ttl > inf->expired) {
2613 		d->ttl = inf->expired;
2614 		inf->num_keys++;
2615 	}
2616 }
2617 
2618 /** remove all negative(NODATA,NXDOMAIN), and servfail messages from cache */
2619 static void
do_flush_negative(RES * ssl,struct worker * worker,char * arg)2620 do_flush_negative(RES* ssl, struct worker* worker, char* arg)
2621 {
2622 	struct del_info inf;
2623 	int pc = 0; /* '+c' option */
2624 	if(!parse_remcachedb(ssl, &arg, &pc))
2625 		return;
2626 	/* what we do is to set them all expired */
2627 	inf.worker = worker;
2628 	inf.expired = *worker->env.now;
2629 	inf.expired -= 3; /* handle 3 seconds skew between threads */
2630 	inf.num_rrsets = 0;
2631 	inf.num_msgs = 0;
2632 	inf.num_keys = 0;
2633 	inf.remcachedb = pc;
2634 	slabhash_traverse(&worker->env.rrset_cache->table, 1,
2635 		&negative_del_rrset, &inf);
2636 
2637 	slabhash_traverse(worker->env.msg_cache, 1, &negative_del_msg, &inf);
2638 
2639 	/* and validator cache */
2640 	if(worker->env.key_cache) {
2641 		slabhash_traverse(worker->env.key_cache->slab, 1,
2642 			&negative_del_kcache, &inf);
2643 	}
2644 
2645 	(void)ssl_printf(ssl, "ok removed %lu rrsets, %lu messages "
2646 		"and %lu key entries\n", (unsigned long)inf.num_rrsets,
2647 		(unsigned long)inf.num_msgs, (unsigned long)inf.num_keys);
2648 }
2649 
2650 /** remove name rrset from cache */
2651 static void
do_flush_name(RES * ssl,struct worker * w,char * arg)2652 do_flush_name(RES* ssl, struct worker* w, char* arg)
2653 {
2654 	uint8_t* nm;
2655 	int nmlabs;
2656 	size_t nmlen;
2657 	int pc = 0; /* '+c' option */
2658 	if(!parse_remcachedb(ssl, &arg, &pc))
2659 		return;
2660 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
2661 		return;
2662 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, pc);
2663 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN, pc);
2664 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, pc);
2665 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, pc);
2666 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_CNAME, LDNS_RR_CLASS_IN, pc);
2667 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_DNAME, LDNS_RR_CLASS_IN, pc);
2668 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_MX, LDNS_RR_CLASS_IN, pc);
2669 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_PTR, LDNS_RR_CLASS_IN, pc);
2670 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SRV, LDNS_RR_CLASS_IN, pc);
2671 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NAPTR, LDNS_RR_CLASS_IN, pc);
2672 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SVCB, LDNS_RR_CLASS_IN, pc);
2673 	do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_HTTPS, LDNS_RR_CLASS_IN, pc);
2674 
2675 	free(nm);
2676 	send_ok(ssl);
2677 }
2678 
2679 /** printout a delegation point info */
2680 static int
ssl_print_name_dp(RES * ssl,const char * str,uint8_t * nm,uint16_t dclass,struct delegpt * dp)2681 ssl_print_name_dp(RES* ssl, const char* str, uint8_t* nm, uint16_t dclass,
2682 	struct delegpt* dp)
2683 {
2684 	char buf[LDNS_MAX_DOMAINLEN];
2685 	struct delegpt_ns* ns;
2686 	struct delegpt_addr* a;
2687 	int f = 0;
2688 	if(str) { /* print header for forward, stub */
2689 		char* c = sldns_wire2str_class(dclass);
2690 		dname_str(nm, buf);
2691 		if(!ssl_printf(ssl, "%s %s %s ", buf, (c?c:"CLASS??"), str)) {
2692 			free(c);
2693 			return 0;
2694 		}
2695 		free(c);
2696 	}
2697 	for(ns = dp->nslist; ns; ns = ns->next) {
2698 		dname_str(ns->name, buf);
2699 		if(!ssl_printf(ssl, "%s%s", (f?" ":""), buf))
2700 			return 0;
2701 		f = 1;
2702 	}
2703 	for(a = dp->target_list; a; a = a->next_target) {
2704 		addr_to_str(&a->addr, a->addrlen, buf, sizeof(buf));
2705 		if(!ssl_printf(ssl, "%s%s", (f?" ":""), buf))
2706 			return 0;
2707 		f = 1;
2708 	}
2709 	return ssl_printf(ssl, "\n");
2710 }
2711 
2712 
2713 /** print root forwards */
2714 static int
print_root_fwds(RES * ssl,struct iter_forwards * fwds,uint8_t * root)2715 print_root_fwds(RES* ssl, struct iter_forwards* fwds, uint8_t* root)
2716 {
2717 	struct delegpt* dp;
2718 	int nolock = 0;
2719 	dp = forwards_lookup(fwds, root, LDNS_RR_CLASS_IN, nolock);
2720 	if(!dp) {
2721 		return ssl_printf(ssl, "off (using root hints)\n");
2722 	}
2723 	/* if dp is returned it must be the root */
2724 	log_assert(query_dname_compare(dp->name, root)==0);
2725 	if(!ssl_print_name_dp(ssl, NULL, root, LDNS_RR_CLASS_IN, dp)) {
2726 		lock_rw_unlock(&fwds->lock);
2727 		return 0;
2728 	}
2729 	lock_rw_unlock(&fwds->lock);
2730 	return 1;
2731 }
2732 
2733 /** parse args into delegpt */
2734 static struct delegpt*
parse_delegpt(RES * ssl,char * args,uint8_t * nm)2735 parse_delegpt(RES* ssl, char* args, uint8_t* nm)
2736 {
2737 	/* parse args and add in */
2738 	char* p = args;
2739 	char* todo;
2740 	struct delegpt* dp = delegpt_create_mlc(nm);
2741 	struct sockaddr_storage addr;
2742 	socklen_t addrlen;
2743 	char* auth_name;
2744 	if(!dp) {
2745 		(void)ssl_printf(ssl, "error out of memory\n");
2746 		return NULL;
2747 	}
2748 	while(p) {
2749 		todo = p;
2750 		p = strchr(p, ' '); /* find next spot, if any */
2751 		if(p) {
2752 			*p++ = 0;	/* end this spot */
2753 			p = skipwhite(p); /* position at next spot */
2754 		}
2755 		/* parse address */
2756 		if(!authextstrtoaddr(todo, &addr, &addrlen, &auth_name)) {
2757 			uint8_t* dname= NULL;
2758 			int port;
2759 			dname = authextstrtodname(todo, &port, &auth_name);
2760 			if(!dname) {
2761 				(void)ssl_printf(ssl, "error cannot parse"
2762 					" '%s'\n", todo);
2763 				delegpt_free_mlc(dp);
2764 				return NULL;
2765 			}
2766 #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
2767 			if(auth_name)
2768 				log_err("no name verification functionality in "
2769 				"ssl library, ignored name for %s", todo);
2770 #endif
2771 			if(!delegpt_add_ns_mlc(dp, dname, 0, auth_name, port)) {
2772 				(void)ssl_printf(ssl, "error out of memory\n");
2773 				free(dname);
2774 				delegpt_free_mlc(dp);
2775 				return NULL;
2776 			}
2777 		} else {
2778 #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
2779 			if(auth_name)
2780 				log_err("no name verification functionality in "
2781 				"ssl library, ignored name for %s", todo);
2782 #endif
2783 			/* add address */
2784 			if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
2785 				auth_name, -1)) {
2786 				(void)ssl_printf(ssl, "error out of memory\n");
2787 				delegpt_free_mlc(dp);
2788 				return NULL;
2789 			}
2790 		}
2791 	}
2792 	dp->has_parent_side_NS = 1;
2793 	return dp;
2794 }
2795 
2796 /** do the forward command */
2797 static void
do_forward(RES * ssl,struct worker * worker,char * args)2798 do_forward(RES* ssl, struct worker* worker, char* args)
2799 {
2800 	struct iter_forwards* fwd = worker->env.fwds;
2801 	uint8_t* root = (uint8_t*)"\000";
2802 	int nolock = 0;
2803 	if(!fwd) {
2804 		(void)ssl_printf(ssl, "error: structure not allocated\n");
2805 		return;
2806 	}
2807 	if(args == NULL || args[0] == 0) {
2808 		(void)print_root_fwds(ssl, fwd, root);
2809 		return;
2810 	}
2811 	/* set root forwards for this thread. since we are in remote control
2812 	 * the actual mesh is not running, so we can freely edit it. */
2813 	/* delete all the existing queries first */
2814 	mesh_delete_all(worker->env.mesh);
2815 	if(strcmp(args, "off") == 0) {
2816 		forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, root, nolock);
2817 	} else {
2818 		struct delegpt* dp;
2819 		if(!(dp = parse_delegpt(ssl, args, root)))
2820 			return;
2821 		if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp, nolock)) {
2822 			(void)ssl_printf(ssl, "error out of memory\n");
2823 			return;
2824 		}
2825 	}
2826 	send_ok(ssl);
2827 }
2828 
2829 static int
parse_fs_args(RES * ssl,char * args,uint8_t ** nm,struct delegpt ** dp,int * insecure,int * prime,int * tls)2830 parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp,
2831 	int* insecure, int* prime, int* tls)
2832 {
2833 	char* zonename;
2834 	char* rest;
2835 	size_t nmlen;
2836 	int nmlabs;
2837 	/* parse all -x args */
2838 	while(args[0] == '+') {
2839 		if(!find_arg2(ssl, args, &rest))
2840 			return 0;
2841 		while(*(++args) != 0) {
2842 			if(*args == 'i' && insecure)
2843 				*insecure = 1;
2844 			else if(*args == 'p' && prime)
2845 				*prime = 1;
2846 			else if(*args == 't' && tls)
2847 				*tls = 1;
2848 			else {
2849 				(void)ssl_printf(ssl, "error: unknown option %s\n", args);
2850 				return 0;
2851 			}
2852 		}
2853 		args = rest;
2854 	}
2855 	/* parse name */
2856 	if(dp) {
2857 		if(!find_arg2(ssl, args, &rest))
2858 			return 0;
2859 		zonename = args;
2860 		args = rest;
2861 	} else	zonename = args;
2862 	if(!parse_arg_name(ssl, zonename, nm, &nmlen, &nmlabs))
2863 		return 0;
2864 
2865 	/* parse dp */
2866 	if(dp) {
2867 		if(!(*dp = parse_delegpt(ssl, args, *nm))) {
2868 			free(*nm);
2869 			return 0;
2870 		}
2871 	}
2872 	return 1;
2873 }
2874 
2875 /** do the forward_add command */
2876 static void
do_forward_add(RES * ssl,struct worker * worker,char * args)2877 do_forward_add(RES* ssl, struct worker* worker, char* args)
2878 {
2879 	struct iter_forwards* fwd = worker->env.fwds;
2880 	int insecure = 0, tls = 0;
2881 	uint8_t* nm = NULL;
2882 	struct delegpt* dp = NULL;
2883 	int nolock = 1;
2884 	if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, NULL, &tls))
2885 		return;
2886 	if(tls)
2887 		dp->ssl_upstream = 1;
2888 	/* prelock forwarders for atomic operation with anchors */
2889 	lock_rw_wrlock(&fwd->lock);
2890 	if(insecure && worker->env.anchors) {
2891 		if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
2892 			nm)) {
2893 			lock_rw_unlock(&fwd->lock);
2894 			(void)ssl_printf(ssl, "error out of memory\n");
2895 			delegpt_free_mlc(dp);
2896 			free(nm);
2897 			return;
2898 		}
2899 	}
2900 	if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp, nolock)) {
2901 		lock_rw_unlock(&fwd->lock);
2902 		(void)ssl_printf(ssl, "error out of memory\n");
2903 		free(nm);
2904 		return;
2905 	}
2906 	lock_rw_unlock(&fwd->lock);
2907 	free(nm);
2908 	send_ok(ssl);
2909 }
2910 
2911 /** do the forward_remove command */
2912 static void
do_forward_remove(RES * ssl,struct worker * worker,char * args)2913 do_forward_remove(RES* ssl, struct worker* worker, char* args)
2914 {
2915 	struct iter_forwards* fwd = worker->env.fwds;
2916 	int insecure = 0;
2917 	uint8_t* nm = NULL;
2918 	int nolock = 1;
2919 	if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL, NULL))
2920 		return;
2921 	/* prelock forwarders for atomic operation with anchors */
2922 	lock_rw_wrlock(&fwd->lock);
2923 	if(insecure && worker->env.anchors)
2924 		anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
2925 			nm);
2926 	forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, nm, nolock);
2927 	lock_rw_unlock(&fwd->lock);
2928 	free(nm);
2929 	send_ok(ssl);
2930 }
2931 
2932 /** do the stub_add command */
2933 static void
do_stub_add(RES * ssl,struct worker * worker,char * args)2934 do_stub_add(RES* ssl, struct worker* worker, char* args)
2935 {
2936 	struct iter_forwards* fwd = worker->env.fwds;
2937 	int insecure = 0, prime = 0, tls = 0;
2938 	uint8_t* nm = NULL;
2939 	struct delegpt* dp = NULL;
2940 	int nolock = 1;
2941 	if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, &prime, &tls))
2942 		return;
2943 	if(tls)
2944 		dp->ssl_upstream = 1;
2945 	/* prelock forwarders and hints for atomic operation with anchors */
2946 	lock_rw_wrlock(&fwd->lock);
2947 	lock_rw_wrlock(&worker->env.hints->lock);
2948 	if(insecure && worker->env.anchors) {
2949 		if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
2950 			nm)) {
2951 			lock_rw_unlock(&fwd->lock);
2952 			lock_rw_unlock(&worker->env.hints->lock);
2953 			(void)ssl_printf(ssl, "error out of memory\n");
2954 			delegpt_free_mlc(dp);
2955 			free(nm);
2956 			return;
2957 		}
2958 	}
2959 	if(!forwards_add_stub_hole(fwd, LDNS_RR_CLASS_IN, nm, nolock)) {
2960 		if(insecure && worker->env.anchors)
2961 			anchors_delete_insecure(worker->env.anchors,
2962 				LDNS_RR_CLASS_IN, nm);
2963 		lock_rw_unlock(&fwd->lock);
2964 		lock_rw_unlock(&worker->env.hints->lock);
2965 		(void)ssl_printf(ssl, "error out of memory\n");
2966 		delegpt_free_mlc(dp);
2967 		free(nm);
2968 		return;
2969 	}
2970 	if(!hints_add_stub(worker->env.hints, LDNS_RR_CLASS_IN, dp, !prime,
2971 		nolock)) {
2972 		(void)ssl_printf(ssl, "error out of memory\n");
2973 		forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm, nolock);
2974 		if(insecure && worker->env.anchors)
2975 			anchors_delete_insecure(worker->env.anchors,
2976 				LDNS_RR_CLASS_IN, nm);
2977 		lock_rw_unlock(&fwd->lock);
2978 		lock_rw_unlock(&worker->env.hints->lock);
2979 		free(nm);
2980 		return;
2981 	}
2982 	lock_rw_unlock(&fwd->lock);
2983 	lock_rw_unlock(&worker->env.hints->lock);
2984 	free(nm);
2985 	send_ok(ssl);
2986 }
2987 
2988 /** do the stub_remove command */
2989 static void
do_stub_remove(RES * ssl,struct worker * worker,char * args)2990 do_stub_remove(RES* ssl, struct worker* worker, char* args)
2991 {
2992 	struct iter_forwards* fwd = worker->env.fwds;
2993 	int insecure = 0;
2994 	uint8_t* nm = NULL;
2995 	int nolock = 1;
2996 	if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL, NULL))
2997 		return;
2998 	/* prelock forwarders and hints for atomic operation with anchors */
2999 	lock_rw_wrlock(&fwd->lock);
3000 	lock_rw_wrlock(&worker->env.hints->lock);
3001 	if(insecure && worker->env.anchors)
3002 		anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
3003 			nm);
3004 	forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm, nolock);
3005 	hints_delete_stub(worker->env.hints, LDNS_RR_CLASS_IN, nm, nolock);
3006 	lock_rw_unlock(&fwd->lock);
3007 	lock_rw_unlock(&worker->env.hints->lock);
3008 	free(nm);
3009 	send_ok(ssl);
3010 }
3011 
3012 /** do the insecure_add command */
3013 static void
do_insecure_add(RES * ssl,struct worker * worker,char * arg)3014 do_insecure_add(RES* ssl, struct worker* worker, char* arg)
3015 {
3016 	size_t nmlen;
3017 	int nmlabs;
3018 	uint8_t* nm = NULL;
3019 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
3020 		return;
3021 	if(worker->env.anchors) {
3022 		if(!anchors_add_insecure(worker->env.anchors,
3023 			LDNS_RR_CLASS_IN, nm)) {
3024 			(void)ssl_printf(ssl, "error out of memory\n");
3025 			free(nm);
3026 			return;
3027 		}
3028 	}
3029 	free(nm);
3030 	send_ok(ssl);
3031 }
3032 
3033 /** do the insecure_remove command */
3034 static void
do_insecure_remove(RES * ssl,struct worker * worker,char * arg)3035 do_insecure_remove(RES* ssl, struct worker* worker, char* arg)
3036 {
3037 	size_t nmlen;
3038 	int nmlabs;
3039 	uint8_t* nm = NULL;
3040 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
3041 		return;
3042 	if(worker->env.anchors)
3043 		anchors_delete_insecure(worker->env.anchors,
3044 			LDNS_RR_CLASS_IN, nm);
3045 	free(nm);
3046 	send_ok(ssl);
3047 }
3048 
3049 static void
do_insecure_list(RES * ssl,struct worker * worker)3050 do_insecure_list(RES* ssl, struct worker* worker)
3051 {
3052 	char buf[LDNS_MAX_DOMAINLEN];
3053 	struct trust_anchor* a;
3054 	if(worker->env.anchors) {
3055 		RBTREE_FOR(a, struct trust_anchor*, worker->env.anchors->tree) {
3056 			if(a->numDS == 0 && a->numDNSKEY == 0) {
3057 				dname_str(a->name, buf);
3058 				ssl_printf(ssl, "%s\n", buf);
3059 			}
3060 		}
3061 	}
3062 }
3063 
3064 /** do the status command */
3065 static void
do_status(RES * ssl,struct worker * worker)3066 do_status(RES* ssl, struct worker* worker)
3067 {
3068 	int i;
3069 	time_t uptime;
3070 	if(!ssl_printf(ssl, "version: %s\n", PACKAGE_VERSION))
3071 		return;
3072 	if(!ssl_printf(ssl, "verbosity: %d\n", verbosity))
3073 		return;
3074 	if(!ssl_printf(ssl, "threads: %d\n", worker->daemon->num))
3075 		return;
3076 	if(!ssl_printf(ssl, "modules: %d [", worker->daemon->mods.num))
3077 		return;
3078 	for(i=0; i<worker->daemon->mods.num; i++) {
3079 		if(!ssl_printf(ssl, " %s", worker->daemon->mods.mod[i]->name))
3080 			return;
3081 	}
3082 	if(!ssl_printf(ssl, " ]\n"))
3083 		return;
3084 	uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec;
3085 	if(!ssl_printf(ssl, "uptime: " ARG_LL "d seconds\n", (long long)uptime))
3086 		return;
3087 	if(!ssl_printf(ssl, "options:%s%s%s%s\n" ,
3088 		(worker->daemon->reuseport?" reuseport":""),
3089 		(worker->daemon->rc->accept_list?" control":""),
3090 		(worker->daemon->rc->accept_list && worker->daemon->rc->use_cert?"(ssl)":""),
3091 		(worker->daemon->rc->accept_list && worker->daemon->cfg->control_ifs.first && worker->daemon->cfg->control_ifs.first->str && worker->daemon->cfg->control_ifs.first->str[0] == '/'?"(namedpipe)":"")
3092 		))
3093 		return;
3094 	if(!ssl_printf(ssl, "unbound (pid %d) is running...\n",
3095 		(int)getpid()))
3096 		return;
3097 }
3098 
3099 /** get age for the mesh state */
3100 static void
get_mesh_age(struct mesh_state * m,char * buf,size_t len,struct module_env * env)3101 get_mesh_age(struct mesh_state* m, char* buf, size_t len,
3102 	struct module_env* env)
3103 {
3104 	if(m->reply_list) {
3105 		struct timeval d;
3106 		struct mesh_reply* r = m->reply_list;
3107 		/* last reply is the oldest */
3108 		while(r && r->next)
3109 			r = r->next;
3110 		timeval_subtract(&d, env->now_tv, &r->start_time);
3111 		snprintf(buf, len, ARG_LL "d.%6.6d",
3112 			(long long)d.tv_sec, (int)d.tv_usec);
3113 	} else {
3114 		snprintf(buf, len, "-");
3115 	}
3116 }
3117 
3118 /** get status of a mesh state */
3119 static void
get_mesh_status(struct mesh_area * mesh,struct mesh_state * m,char * buf,size_t len)3120 get_mesh_status(struct mesh_area* mesh, struct mesh_state* m,
3121 	char* buf, size_t len)
3122 {
3123 	enum module_ext_state s = m->s.ext_state[m->s.curmod];
3124 	const char *modname = mesh->mods.mod[m->s.curmod]->name;
3125 	size_t l;
3126 	if(strcmp(modname, "iterator") == 0 && s == module_wait_reply &&
3127 		m->s.minfo[m->s.curmod]) {
3128 		/* break into iterator to find out who its waiting for */
3129 		struct iter_qstate* qstate = (struct iter_qstate*)
3130 			m->s.minfo[m->s.curmod];
3131 		struct outbound_list* ol = &qstate->outlist;
3132 		struct outbound_entry* e;
3133 		snprintf(buf, len, "%s wait for", modname);
3134 		l = strlen(buf);
3135 		buf += l; len -= l;
3136 		if(ol->first == NULL)
3137 			snprintf(buf, len, " (empty_list)");
3138 		for(e = ol->first; e; e = e->next) {
3139 			snprintf(buf, len, " ");
3140 			l = strlen(buf);
3141 			buf += l; len -= l;
3142 			addr_to_str(&e->qsent->addr, e->qsent->addrlen,
3143 				buf, len);
3144 			l = strlen(buf);
3145 			buf += l; len -= l;
3146 		}
3147 	} else if(s == module_wait_subquery) {
3148 		/* look in subs from mesh state to see what */
3149 		char nm[LDNS_MAX_DOMAINLEN];
3150 		struct mesh_state_ref* sub;
3151 		snprintf(buf, len, "%s wants", modname);
3152 		l = strlen(buf);
3153 		buf += l; len -= l;
3154 		if(m->sub_set.count == 0)
3155 			snprintf(buf, len, " (empty_list)");
3156 		RBTREE_FOR(sub, struct mesh_state_ref*, &m->sub_set) {
3157 			char* t = sldns_wire2str_type(sub->s->s.qinfo.qtype);
3158 			char* c = sldns_wire2str_class(sub->s->s.qinfo.qclass);
3159 			dname_str(sub->s->s.qinfo.qname, nm);
3160 			snprintf(buf, len, " %s %s %s", (t?t:"TYPE??"),
3161 				(c?c:"CLASS??"), nm);
3162 			l = strlen(buf);
3163 			buf += l; len -= l;
3164 			free(t);
3165 			free(c);
3166 		}
3167 	} else {
3168 		snprintf(buf, len, "%s is %s", modname, strextstate(s));
3169 	}
3170 }
3171 
3172 /** do the dump_requestlist command */
3173 static void
do_dump_requestlist(RES * ssl,struct worker * worker)3174 do_dump_requestlist(RES* ssl, struct worker* worker)
3175 {
3176 	struct mesh_area* mesh;
3177 	struct mesh_state* m;
3178 	int num = 0;
3179 	char buf[LDNS_MAX_DOMAINLEN];
3180 	char timebuf[32];
3181 	char statbuf[10240];
3182 	if(!ssl_printf(ssl, "thread #%d\n", worker->thread_num))
3183 		return;
3184 	if(!ssl_printf(ssl, "#   type cl name    seconds    module status\n"))
3185 		return;
3186 	/* show worker mesh contents */
3187 	mesh = worker->env.mesh;
3188 	if(!mesh) return;
3189 	RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
3190 		char* t = sldns_wire2str_type(m->s.qinfo.qtype);
3191 		char* c = sldns_wire2str_class(m->s.qinfo.qclass);
3192 		dname_str(m->s.qinfo.qname, buf);
3193 		get_mesh_age(m, timebuf, sizeof(timebuf), &worker->env);
3194 		get_mesh_status(mesh, m, statbuf, sizeof(statbuf));
3195 		if(!ssl_printf(ssl, "%3d %4s %2s %s %s %s\n",
3196 			num, (t?t:"TYPE??"), (c?c:"CLASS??"), buf, timebuf,
3197 			statbuf)) {
3198 			free(t);
3199 			free(c);
3200 			return;
3201 		}
3202 		num++;
3203 		free(t);
3204 		free(c);
3205 	}
3206 }
3207 
3208 /** structure for argument data for dump infra host */
3209 struct infra_arg {
3210 	/** the infra cache */
3211 	struct infra_cache* infra;
3212 	/** the SSL connection */
3213 	RES* ssl;
3214 	/** the time now */
3215 	time_t now;
3216 	/** ssl failure? stop writing and skip the rest.  If the tcp
3217 	 * connection is broken, and writes fail, we then stop writing. */
3218 	int ssl_failed;
3219 };
3220 
3221 /** callback for every host element in the infra cache */
3222 static void
dump_infra_host(struct lruhash_entry * e,void * arg)3223 dump_infra_host(struct lruhash_entry* e, void* arg)
3224 {
3225 	struct infra_arg* a = (struct infra_arg*)arg;
3226 	struct infra_key* k = (struct infra_key*)e->key;
3227 	struct infra_data* d = (struct infra_data*)e->data;
3228 	char ip_str[1024];
3229 	char name[LDNS_MAX_DOMAINLEN];
3230 	int port;
3231 	if(a->ssl_failed)
3232 		return;
3233 	addr_to_str(&k->addr, k->addrlen, ip_str, sizeof(ip_str));
3234 	dname_str(k->zonename, name);
3235 	port = (int)ntohs(((struct sockaddr_in*)&k->addr)->sin_port);
3236 	if(port != UNBOUND_DNS_PORT) {
3237 		snprintf(ip_str+strlen(ip_str), sizeof(ip_str)-strlen(ip_str),
3238 			"@%d", port);
3239 	}
3240 	/* skip expired stuff (only backed off) */
3241 	if(d->ttl < a->now) {
3242 		if(d->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
3243 			if(!ssl_printf(a->ssl, "%s %s expired rto %d\n", ip_str,
3244 				name, d->rtt.rto))  {
3245 				a->ssl_failed = 1;
3246 				return;
3247 			}
3248 		}
3249 		return;
3250 	}
3251 	if(!ssl_printf(a->ssl, "%s %s ttl %lu ping %d var %d rtt %d rto %d "
3252 		"tA %d tAAAA %d tother %d "
3253 		"ednsknown %d edns %d delay %d lame dnssec %d rec %d A %d "
3254 		"other %d\n", ip_str, name, (unsigned long)(d->ttl - a->now),
3255 		d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto,
3256 		d->timeout_A, d->timeout_AAAA, d->timeout_other,
3257 		(int)d->edns_lame_known, (int)d->edns_version,
3258 		(int)(a->now<d->probedelay?(d->probedelay - a->now):0),
3259 		(int)d->isdnsseclame, (int)d->rec_lame, (int)d->lame_type_A,
3260 		(int)d->lame_other)) {
3261 		a->ssl_failed = 1;
3262 		return;
3263 	}
3264 }
3265 
3266 /** do the dump_infra command */
3267 static void
do_dump_infra(RES * ssl,struct worker * worker)3268 do_dump_infra(RES* ssl, struct worker* worker)
3269 {
3270 	struct infra_arg arg;
3271 	arg.infra = worker->env.infra_cache;
3272 	arg.ssl = ssl;
3273 	arg.now = *worker->env.now;
3274 	arg.ssl_failed = 0;
3275 	slabhash_traverse(arg.infra->hosts, 0, &dump_infra_host, (void*)&arg);
3276 }
3277 
3278 /** do the log_reopen command */
3279 static void
do_log_reopen(RES * ssl,struct worker * worker)3280 do_log_reopen(RES* ssl, struct worker* worker)
3281 {
3282 	struct config_file* cfg = worker->env.cfg;
3283 	send_ok(ssl);
3284 	log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
3285 }
3286 
3287 /** do the auth_zone_reload command */
3288 static void
do_auth_zone_reload(RES * ssl,struct worker * worker,char * arg)3289 do_auth_zone_reload(RES* ssl, struct worker* worker, char* arg)
3290 {
3291 	size_t nmlen;
3292 	int nmlabs;
3293 	uint8_t* nm = NULL;
3294 	struct auth_zones* az = worker->env.auth_zones;
3295 	struct auth_zone* z = NULL;
3296 	struct auth_xfer* xfr = NULL;
3297 	char* reason = NULL;
3298 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
3299 		return;
3300 	if(az) {
3301 		lock_rw_rdlock(&az->lock);
3302 		z = auth_zone_find(az, nm, nmlen, LDNS_RR_CLASS_IN);
3303 		if(z) {
3304 			lock_rw_wrlock(&z->lock);
3305 		}
3306 		xfr = auth_xfer_find(az, nm, nmlen, LDNS_RR_CLASS_IN);
3307 		if(xfr) {
3308 			lock_basic_lock(&xfr->lock);
3309 		}
3310 		lock_rw_unlock(&az->lock);
3311 	}
3312 	free(nm);
3313 	if(!z) {
3314 		if(xfr) {
3315 			lock_basic_unlock(&xfr->lock);
3316 		}
3317 		(void)ssl_printf(ssl, "error no auth-zone %s\n", arg);
3318 		return;
3319 	}
3320 	if(!auth_zone_read_zonefile(z, worker->env.cfg)) {
3321 		/* The old tree was already cleared. Do not answer from the
3322 		 * failed load. */
3323 		z->zone_expired = 1;
3324 		auth_zone_clear_data(z);
3325 		lock_rw_unlock(&z->lock);
3326 		if(xfr) {
3327 			lock_basic_unlock(&xfr->lock);
3328 		}
3329 		(void)ssl_printf(ssl, "error failed to read %s\n", arg);
3330 		return;
3331 	}
3332 
3333 	z->zone_expired = 0;
3334 	if(xfr) {
3335 		xfr->zone_expired = 0;
3336 		xfr->num_ixfrs = 0;
3337 		if(!xfr_find_soa(z, xfr)) {
3338 			if(z->data.count == 0) {
3339 				lock_rw_unlock(&z->lock);
3340 				lock_basic_unlock(&xfr->lock);
3341 				(void)ssl_printf(ssl, "zone %s has no contents\n", arg);
3342 				return;
3343 			}
3344 			lock_rw_unlock(&z->lock);
3345 			lock_basic_unlock(&xfr->lock);
3346 			(void)ssl_printf(ssl, "error: no SOA in zone after read %s\n", arg);
3347 			return;
3348 		}
3349 		if(xfr->have_zone) {
3350 			xfr->lease_time = *worker->env.now;
3351 			xfr->soa_zone_acquired = *worker->env.now;
3352 		}
3353 		lock_basic_unlock(&xfr->lock);
3354 	}
3355 	z->soa_zone_acquired = *worker->env.now;
3356 
3357 	auth_zone_verify_zonemd(z, &worker->env, &worker->env.mesh->mods,
3358 		&reason, 0, 0);
3359 	if(reason && z->zone_expired) {
3360 		lock_rw_unlock(&z->lock);
3361 		(void)ssl_printf(ssl, "error zonemd for %s failed: %s\n",
3362 			arg, reason);
3363 		free(reason);
3364 		return;
3365 	} else if(reason && strcmp(reason, "ZONEMD verification successful")
3366 		==0) {
3367 		(void)ssl_printf(ssl, "%s: %s\n", arg, reason);
3368 	}
3369 	lock_rw_unlock(&z->lock);
3370 	free(reason);
3371 	send_ok(ssl);
3372 }
3373 
3374 /** do the auth_zone_transfer command */
3375 static void
do_auth_zone_transfer(RES * ssl,struct worker * worker,char * arg)3376 do_auth_zone_transfer(RES* ssl, struct worker* worker, char* arg)
3377 {
3378 	size_t nmlen;
3379 	int nmlabs;
3380 	uint8_t* nm = NULL;
3381 	struct auth_zones* az = worker->env.auth_zones;
3382 	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
3383 		return;
3384 	if(!az || !auth_zones_startprobesequence(az, &worker->env, nm, nmlen,
3385 		LDNS_RR_CLASS_IN)) {
3386 		(void)ssl_printf(ssl, "error zone xfr task not found %s\n", arg);
3387 		free(nm);
3388 		return;
3389 	}
3390 	free(nm);
3391 	send_ok(ssl);
3392 }
3393 
3394 /** do the set_option command */
3395 static void
do_set_option(RES * ssl,struct worker * worker,char * arg)3396 do_set_option(RES* ssl, struct worker* worker, char* arg)
3397 {
3398 	char* arg2;
3399 	if(!find_arg2(ssl, arg, &arg2))
3400 		return;
3401 	if(!config_set_option(worker->env.cfg, arg, arg2)) {
3402 		(void)ssl_printf(ssl, "error setting option\n");
3403 		return;
3404 	}
3405 	/* effectuate some arguments */
3406 	if(strcmp(arg, "val-override-date:") == 0) {
3407 		int m = modstack_find(&worker->env.mesh->mods, "validator");
3408 		struct val_env* val_env = NULL;
3409 		if(m != -1) val_env = (struct val_env*)worker->env.modinfo[m];
3410 		if(val_env)
3411 			val_env->date_override = worker->env.cfg->val_date_override;
3412 	}
3413 	send_ok(ssl);
3414 }
3415 
3416 /* routine to printout option values over SSL */
remote_get_opt_ssl(char * line,void * arg)3417 void remote_get_opt_ssl(char* line, void* arg)
3418 {
3419 	RES* ssl = (RES*)arg;
3420 	(void)ssl_printf(ssl, "%s\n", line);
3421 }
3422 
3423 /** do the get_option command */
3424 static void
do_get_option(RES * ssl,struct worker * worker,char * arg)3425 do_get_option(RES* ssl, struct worker* worker, char* arg)
3426 {
3427 	int r;
3428 	r = config_get_option(worker->env.cfg, arg, remote_get_opt_ssl, ssl);
3429 	if(!r) {
3430 		(void)ssl_printf(ssl, "error unknown option\n");
3431 		return;
3432 	}
3433 }
3434 
3435 /** do the list_forwards command */
3436 static void
do_list_forwards(RES * ssl,struct worker * worker)3437 do_list_forwards(RES* ssl, struct worker* worker)
3438 {
3439 	/* since its a per-worker structure no locks needed */
3440 	struct iter_forwards* fwds = worker->env.fwds;
3441 	struct iter_forward_zone* z;
3442 	struct trust_anchor* a;
3443 	int insecure;
3444 	lock_rw_rdlock(&fwds->lock);
3445 	RBTREE_FOR(z, struct iter_forward_zone*, fwds->tree) {
3446 		if(!z->dp) continue; /* skip empty marker for stub */
3447 
3448 		/* see if it is insecure */
3449 		insecure = 0;
3450 		if(worker->env.anchors &&
3451 			(a=anchor_find(worker->env.anchors, z->name,
3452 			z->namelabs, z->namelen,  z->dclass))) {
3453 			if(!a->keylist && !a->numDS && !a->numDNSKEY)
3454 				insecure = 1;
3455 			lock_basic_unlock(&a->lock);
3456 		}
3457 
3458 		if(!ssl_print_name_dp(ssl, (insecure?"forward +i":"forward"),
3459 			z->name, z->dclass, z->dp)) {
3460 			lock_rw_unlock(&fwds->lock);
3461 			return;
3462 		}
3463 	}
3464 	lock_rw_unlock(&fwds->lock);
3465 }
3466 
3467 /** do the list_stubs command */
3468 static void
do_list_stubs(RES * ssl,struct worker * worker)3469 do_list_stubs(RES* ssl, struct worker* worker)
3470 {
3471 	struct iter_hints_stub* z;
3472 	struct trust_anchor* a;
3473 	int insecure;
3474 	char str[32];
3475 	lock_rw_rdlock(&worker->env.hints->lock);
3476 	RBTREE_FOR(z, struct iter_hints_stub*, &worker->env.hints->tree) {
3477 
3478 		/* see if it is insecure */
3479 		insecure = 0;
3480 		if(worker->env.anchors &&
3481 			(a=anchor_find(worker->env.anchors, z->node.name,
3482 			z->node.labs, z->node.len,  z->node.dclass))) {
3483 			if(!a->keylist && !a->numDS && !a->numDNSKEY)
3484 				insecure = 1;
3485 			lock_basic_unlock(&a->lock);
3486 		}
3487 
3488 		snprintf(str, sizeof(str), "stub %sprime%s",
3489 			(z->noprime?"no":""), (insecure?" +i":""));
3490 		if(!ssl_print_name_dp(ssl, str, z->node.name,
3491 			z->node.dclass, z->dp)) {
3492 			lock_rw_unlock(&worker->env.hints->lock);
3493 			return;
3494 		}
3495 	}
3496 	lock_rw_unlock(&worker->env.hints->lock);
3497 }
3498 
3499 /** do the list_auth_zones command */
3500 static void
do_list_auth_zones(RES * ssl,struct auth_zones * az)3501 do_list_auth_zones(RES* ssl, struct auth_zones* az)
3502 {
3503 	struct auth_zone* z;
3504 	char buf[LDNS_MAX_DOMAINLEN], buf2[256], buf3[256];
3505 	lock_rw_rdlock(&az->lock);
3506 	RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
3507 		lock_rw_rdlock(&z->lock);
3508 		dname_str(z->name, buf);
3509 		if(z->zone_expired)
3510 			snprintf(buf2, sizeof(buf2), "expired");
3511 		else {
3512 			uint32_t serial = 0;
3513 			if(auth_zone_get_serial(z, &serial)) {
3514 				snprintf(buf2, sizeof(buf2), "serial %u",
3515 					(unsigned)serial);
3516 				if(z->soa_zone_acquired != 0) {
3517 #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R)
3518 					char tmbuf[32];
3519 					struct tm tm;
3520 					struct tm *tm_p;
3521 					tm_p = localtime_r(
3522 						&z->soa_zone_acquired, &tm);
3523 					if(!strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%dT%H:%M:%S", tm_p))
3524 						snprintf(tmbuf, sizeof(tmbuf), "strftime-err-%u", (unsigned)z->soa_zone_acquired);
3525 					snprintf(buf3, sizeof(buf3),
3526 						"\t since %u %s",
3527 						(unsigned)z->soa_zone_acquired,
3528 						tmbuf);
3529 #else
3530 					snprintf(buf3, sizeof(buf3),
3531 						"\t since %u",
3532 						(unsigned)z->soa_zone_acquired);
3533 #endif
3534 				} else {
3535 					buf3[0]=0;
3536 				}
3537 			} else	{
3538 				snprintf(buf2, sizeof(buf2), "no serial");
3539 				buf3[0]=0;
3540 			}
3541 		}
3542 		lock_rw_unlock(&z->lock);
3543 		if(!ssl_printf(ssl, "%s\t%s%s\n", buf, buf2, buf3)) {
3544 			/* failure to print */
3545 			lock_rw_unlock(&az->lock);
3546 			return;
3547 		}
3548 	}
3549 	lock_rw_unlock(&az->lock);
3550 }
3551 
3552 /** do the list_local_zones command */
3553 static void
do_list_local_zones(RES * ssl,struct local_zones * zones)3554 do_list_local_zones(RES* ssl, struct local_zones* zones)
3555 {
3556 	struct local_zone* z;
3557 	char buf[LDNS_MAX_DOMAINLEN];
3558 	lock_rw_rdlock(&zones->lock);
3559 	RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
3560 		lock_rw_rdlock(&z->lock);
3561 		dname_str(z->name, buf);
3562 		if(!ssl_printf(ssl, "%s %s\n", buf,
3563 			local_zone_type2str(z->type))) {
3564 			/* failure to print */
3565 			lock_rw_unlock(&z->lock);
3566 			lock_rw_unlock(&zones->lock);
3567 			return;
3568 		}
3569 		lock_rw_unlock(&z->lock);
3570 	}
3571 	lock_rw_unlock(&zones->lock);
3572 }
3573 
3574 /** do the list_local_data command */
3575 static void
do_list_local_data(RES * ssl,struct worker * worker,struct local_zones * zones)3576 do_list_local_data(RES* ssl, struct worker* worker, struct local_zones* zones)
3577 {
3578 	struct local_zone* z;
3579 	struct local_data* d;
3580 	struct local_rrset* p;
3581 	char* s = (char*)sldns_buffer_begin(worker->env.scratch_buffer);
3582 	size_t slen = sldns_buffer_capacity(worker->env.scratch_buffer);
3583 	lock_rw_rdlock(&zones->lock);
3584 	RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
3585 		lock_rw_rdlock(&z->lock);
3586 		RBTREE_FOR(d, struct local_data*, &z->data) {
3587 			for(p = d->rrsets; p; p = p->next) {
3588 				struct packed_rrset_data* d =
3589 					(struct packed_rrset_data*)p->rrset->entry.data;
3590 				size_t i;
3591 				for(i=0; i<d->count + d->rrsig_count; i++) {
3592 					if(!packed_rr_to_string(p->rrset, i,
3593 						0, s, slen)) {
3594 						if(!ssl_printf(ssl, "BADRR\n")) {
3595 							lock_rw_unlock(&z->lock);
3596 							lock_rw_unlock(&zones->lock);
3597 							return;
3598 						}
3599 					}
3600 				        if(!ssl_printf(ssl, "%s\n", s)) {
3601 						lock_rw_unlock(&z->lock);
3602 						lock_rw_unlock(&zones->lock);
3603 						return;
3604 					}
3605 				}
3606 			}
3607 		}
3608 		lock_rw_unlock(&z->lock);
3609 	}
3610 	lock_rw_unlock(&zones->lock);
3611 }
3612 
3613 /** do the view_list_local_zones command */
3614 static void
do_view_list_local_zones(RES * ssl,struct worker * worker,char * arg)3615 do_view_list_local_zones(RES* ssl, struct worker* worker, char* arg)
3616 {
3617 	struct view* v = views_find_view(worker->env.views,
3618 		arg, 0 /* get read lock*/);
3619 	if(!v) {
3620 		ssl_printf(ssl,"no view with name: %s\n", arg);
3621 		return;
3622 	}
3623 	if(v->local_zones) {
3624 		do_list_local_zones(ssl, v->local_zones);
3625 	}
3626 	lock_rw_unlock(&v->lock);
3627 }
3628 
3629 /** do the view_list_local_data command */
3630 static void
do_view_list_local_data(RES * ssl,struct worker * worker,char * arg)3631 do_view_list_local_data(RES* ssl, struct worker* worker, char* arg)
3632 {
3633 	struct view* v = views_find_view(worker->env.views,
3634 		arg, 0 /* get read lock*/);
3635 	if(!v) {
3636 		ssl_printf(ssl,"no view with name: %s\n", arg);
3637 		return;
3638 	}
3639 	if(v->local_zones) {
3640 		do_list_local_data(ssl, worker, v->local_zones);
3641 	}
3642 	lock_rw_unlock(&v->lock);
3643 }
3644 
3645 /** struct for user arg ratelimit list */
3646 struct ratelimit_list_arg {
3647 	/** the infra cache */
3648 	struct infra_cache* infra;
3649 	/** the SSL to print to */
3650 	RES* ssl;
3651 	/** all or only ratelimited */
3652 	int all;
3653 	/** current time */
3654 	time_t now;
3655 	/** if backoff is enabled */
3656 	int backoff;
3657 };
3658 
3659 #define ip_ratelimit_list_arg ratelimit_list_arg
3660 
3661 /** list items in the ratelimit table */
3662 static void
rate_list(struct lruhash_entry * e,void * arg)3663 rate_list(struct lruhash_entry* e, void* arg)
3664 {
3665 	struct ratelimit_list_arg* a = (struct ratelimit_list_arg*)arg;
3666 	struct rate_key* k = (struct rate_key*)e->key;
3667 	struct rate_data* d = (struct rate_data*)e->data;
3668 	char buf[LDNS_MAX_DOMAINLEN];
3669 	int lim = infra_find_ratelimit(a->infra, k->name, k->namelen);
3670 	int max = infra_rate_max(d, a->now, a->backoff);
3671 	if(a->all == 0) {
3672 		if(max < lim)
3673 			return;
3674 	}
3675 	dname_str(k->name, buf);
3676 	ssl_printf(a->ssl, "%s %d limit %d\n", buf, max, lim);
3677 }
3678 
3679 /** list items in the ip_ratelimit table */
3680 static void
ip_rate_list(struct lruhash_entry * e,void * arg)3681 ip_rate_list(struct lruhash_entry* e, void* arg)
3682 {
3683 	char ip[128];
3684 	struct ip_ratelimit_list_arg* a = (struct ip_ratelimit_list_arg*)arg;
3685 	struct ip_rate_key* k = (struct ip_rate_key*)e->key;
3686 	struct ip_rate_data* d = (struct ip_rate_data*)e->data;
3687 	int lim = infra_ip_ratelimit;
3688 	int max = infra_rate_max(d, a->now, a->backoff);
3689 	if(a->all == 0) {
3690 		if(max < lim)
3691 			return;
3692 	}
3693 	addr_to_str(&k->addr, k->addrlen, ip, sizeof(ip));
3694 	ssl_printf(a->ssl, "%s %d limit %d\n", ip, max, lim);
3695 }
3696 
3697 /** do the ratelimit_list command */
3698 static void
do_ratelimit_list(RES * ssl,struct worker * worker,char * arg)3699 do_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
3700 {
3701 	struct ratelimit_list_arg a;
3702 	a.all = 0;
3703 	a.infra = worker->env.infra_cache;
3704 	a.now = *worker->env.now;
3705 	a.ssl = ssl;
3706 	a.backoff = worker->env.cfg->ratelimit_backoff;
3707 	arg = skipwhite(arg);
3708 	if(strcmp(arg, "+a") == 0)
3709 		a.all = 1;
3710 	if(a.infra->domain_rates==NULL ||
3711 		(a.all == 0 && infra_dp_ratelimit == 0))
3712 		return;
3713 	slabhash_traverse(a.infra->domain_rates, 0, rate_list, &a);
3714 }
3715 
3716 /** do the ip_ratelimit_list command */
3717 static void
do_ip_ratelimit_list(RES * ssl,struct worker * worker,char * arg)3718 do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
3719 {
3720 	struct ip_ratelimit_list_arg a;
3721 	a.all = 0;
3722 	a.infra = worker->env.infra_cache;
3723 	a.now = *worker->env.now;
3724 	a.ssl = ssl;
3725 	a.backoff = worker->env.cfg->ip_ratelimit_backoff;
3726 	arg = skipwhite(arg);
3727 	if(strcmp(arg, "+a") == 0)
3728 		a.all = 1;
3729 	if(a.infra->client_ip_rates==NULL ||
3730 		(a.all == 0 && infra_ip_ratelimit == 0))
3731 		return;
3732 	slabhash_traverse(a.infra->client_ip_rates, 0, ip_rate_list, &a);
3733 }
3734 
3735 /** do the rpz_enable/disable command */
3736 static void
do_rpz_enable_disable(RES * ssl,struct worker * worker,char * arg,int enable)3737 do_rpz_enable_disable(RES* ssl, struct worker* worker, char* arg, int enable) {
3738     size_t nmlen;
3739     int nmlabs;
3740     uint8_t *nm = NULL;
3741     struct auth_zones *az = worker->env.auth_zones;
3742     struct auth_zone *z = NULL;
3743     if (!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
3744         return;
3745     if (az) {
3746         lock_rw_rdlock(&az->lock);
3747         z = auth_zone_find(az, nm, nmlen, LDNS_RR_CLASS_IN);
3748         if (z) {
3749             lock_rw_wrlock(&z->lock);
3750         }
3751         lock_rw_unlock(&az->lock);
3752     }
3753     free(nm);
3754     if (!z) {
3755         (void) ssl_printf(ssl, "error no auth-zone %s\n", arg);
3756         return;
3757     }
3758     if (!z->rpz) {
3759         (void) ssl_printf(ssl, "error auth-zone %s not RPZ\n", arg);
3760         lock_rw_unlock(&z->lock);
3761         return;
3762     }
3763     if (enable) {
3764         rpz_enable(z->rpz);
3765     } else {
3766         rpz_disable(z->rpz);
3767     }
3768     lock_rw_unlock(&z->lock);
3769     send_ok(ssl);
3770 }
3771 
3772 /** do the rpz_enable command */
3773 static void
do_rpz_enable(RES * ssl,struct worker * worker,char * arg)3774 do_rpz_enable(RES* ssl, struct worker* worker, char* arg)
3775 {
3776     do_rpz_enable_disable(ssl, worker, arg, 1);
3777 }
3778 
3779 /** do the rpz_disable command */
3780 static void
do_rpz_disable(RES * ssl,struct worker * worker,char * arg)3781 do_rpz_disable(RES* ssl, struct worker* worker, char* arg)
3782 {
3783     do_rpz_enable_disable(ssl, worker, arg, 0);
3784 }
3785 
3786 /** Write the cookie secrets to file, returns `0` on failure.
3787  * Caller has to hold the lock. */
3788 static int
cookie_secret_file_dump(RES * ssl,struct worker * worker)3789 cookie_secret_file_dump(RES* ssl, struct worker* worker) {
3790 	char const* secret_file = worker->env.cfg->cookie_secret_file;
3791 	struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
3792 	char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
3793 	FILE* f;
3794 	size_t i;
3795 	if(secret_file == NULL || secret_file[0]==0) {
3796 		(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
3797 		return 0;
3798 	}
3799 	log_assert( secret_file != NULL );
3800 
3801 	/* open write only and truncate */
3802 	if((f = fopen(secret_file, "w")) == NULL ) {
3803 		(void)ssl_printf(ssl, "unable to open cookie secret file %s: %s",
3804 		                 secret_file, strerror(errno));
3805 		return 0;
3806 	}
3807 	if(cookie_secrets == NULL) {
3808 		/* nothing to write */
3809 		fclose(f);
3810 		return 1;
3811 	}
3812 
3813 	for(i = 0; i < cookie_secrets->cookie_count; i++) {
3814 		struct cookie_secret const* cs = &cookie_secrets->
3815 			cookie_secrets[i];
3816 		ssize_t const len = hex_ntop(cs->cookie_secret,
3817 			UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
3818 			sizeof(secret_hex));
3819 		(void)len; /* silence unused variable warning with -DNDEBUG */
3820 		log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
3821 		secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
3822 		fprintf(f, "%s\n", secret_hex);
3823 	}
3824 	explicit_bzero(secret_hex, sizeof(secret_hex));
3825 	fclose(f);
3826 	return 1;
3827 }
3828 
3829 /** Activate cookie secret */
3830 static void
do_activate_cookie_secret(RES * ssl,struct worker * worker)3831 do_activate_cookie_secret(RES* ssl, struct worker* worker) {
3832 	char const* secret_file = worker->env.cfg->cookie_secret_file;
3833 	struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
3834 
3835 	if(secret_file == NULL || secret_file[0] == 0) {
3836 		(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
3837 		return;
3838 	}
3839 	if(cookie_secrets == NULL) {
3840 		(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
3841 		return;
3842 	}
3843 	lock_basic_lock(&cookie_secrets->lock);
3844 
3845 	if(cookie_secrets->cookie_count <= 1 ) {
3846 		lock_basic_unlock(&cookie_secrets->lock);
3847 		(void)ssl_printf(ssl, "error: no staging cookie secret to activate\n");
3848 		return;
3849 	}
3850 	/* Only the worker 0 writes to file, the others update state. */
3851 	if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
3852 		lock_basic_unlock(&cookie_secrets->lock);
3853 		(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
3854 				secret_file);
3855 		return;
3856 	}
3857 	activate_cookie_secret(cookie_secrets);
3858 	if(worker->thread_num == 0)
3859 		(void)cookie_secret_file_dump(ssl, worker);
3860 	lock_basic_unlock(&cookie_secrets->lock);
3861 	send_ok(ssl);
3862 }
3863 
3864 /** Drop cookie secret */
3865 static void
do_drop_cookie_secret(RES * ssl,struct worker * worker)3866 do_drop_cookie_secret(RES* ssl, struct worker* worker) {
3867 	char const* secret_file = worker->env.cfg->cookie_secret_file;
3868 	struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
3869 
3870 	if(secret_file == NULL || secret_file[0] == 0) {
3871 		(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
3872 		return;
3873 	}
3874 	if(cookie_secrets == NULL) {
3875 		(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
3876 		return;
3877 	}
3878 	lock_basic_lock(&cookie_secrets->lock);
3879 
3880 	if(cookie_secrets->cookie_count <= 1 ) {
3881 		lock_basic_unlock(&cookie_secrets->lock);
3882 		(void)ssl_printf(ssl, "error: can not drop the currently active cookie secret\n");
3883 		return;
3884 	}
3885 	/* Only the worker 0 writes to file, the others update state. */
3886 	if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
3887 		lock_basic_unlock(&cookie_secrets->lock);
3888 		(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
3889 				secret_file);
3890 		return;
3891 	}
3892 	drop_cookie_secret(cookie_secrets);
3893 	if(worker->thread_num == 0)
3894 		(void)cookie_secret_file_dump(ssl, worker);
3895 	lock_basic_unlock(&cookie_secrets->lock);
3896 	send_ok(ssl);
3897 }
3898 
3899 /** Add cookie secret */
3900 static void
do_add_cookie_secret(RES * ssl,struct worker * worker,char * arg)3901 do_add_cookie_secret(RES* ssl, struct worker* worker, char* arg) {
3902 	uint8_t secret[UNBOUND_COOKIE_SECRET_SIZE];
3903 	char const* secret_file = worker->env.cfg->cookie_secret_file;
3904 	struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
3905 
3906 	if(secret_file == NULL || secret_file[0] == 0) {
3907 		(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
3908 		return;
3909 	}
3910 	if(cookie_secrets == NULL) {
3911 		worker->daemon->cookie_secrets = cookie_secrets_create();
3912 		if(!worker->daemon->cookie_secrets) {
3913 			(void)ssl_printf(ssl, "error: out of memory");
3914 			return;
3915 		}
3916 		cookie_secrets = worker->daemon->cookie_secrets;
3917 	}
3918 	lock_basic_lock(&cookie_secrets->lock);
3919 
3920 	if(*arg == '\0') {
3921 		lock_basic_unlock(&cookie_secrets->lock);
3922 		(void)ssl_printf(ssl, "error: missing argument (cookie_secret)\n");
3923 		return;
3924 	}
3925 	if(strlen(arg) != 32) {
3926 		lock_basic_unlock(&cookie_secrets->lock);
3927 		explicit_bzero(arg, strlen(arg));
3928 		(void)ssl_printf(ssl, "invalid cookie secret: invalid argument length\n");
3929 		(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
3930 		return;
3931 	}
3932 	if(hex_pton(arg, secret, UNBOUND_COOKIE_SECRET_SIZE) !=
3933 		UNBOUND_COOKIE_SECRET_SIZE ) {
3934 		lock_basic_unlock(&cookie_secrets->lock);
3935 		explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
3936 		explicit_bzero(arg, strlen(arg));
3937 		(void)ssl_printf(ssl, "invalid cookie secret: parse error\n");
3938 		(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
3939 		return;
3940 	}
3941 	/* Only the worker 0 writes to file, the others update state. */
3942 	if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
3943 		lock_basic_unlock(&cookie_secrets->lock);
3944 		explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
3945 		explicit_bzero(arg, strlen(arg));
3946 		(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
3947 				secret_file);
3948 		return;
3949 	}
3950 	add_cookie_secret(cookie_secrets, secret, UNBOUND_COOKIE_SECRET_SIZE);
3951 	explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
3952 	if(worker->thread_num == 0)
3953 		(void)cookie_secret_file_dump(ssl, worker);
3954 	lock_basic_unlock(&cookie_secrets->lock);
3955 	explicit_bzero(arg, strlen(arg));
3956 	send_ok(ssl);
3957 }
3958 
3959 /** Print cookie secrets */
3960 static void
do_print_cookie_secrets(RES * ssl,struct worker * worker)3961 do_print_cookie_secrets(RES* ssl, struct worker* worker) {
3962 	struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
3963 	char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
3964 	int i;
3965 
3966 	if(!cookie_secrets)
3967 		return; /* Output is empty. */
3968 	lock_basic_lock(&cookie_secrets->lock);
3969 	for(i = 0; (size_t)i < cookie_secrets->cookie_count; i++) {
3970 		struct cookie_secret const* cs = &cookie_secrets->
3971 			cookie_secrets[i];
3972 		ssize_t const len = hex_ntop(cs->cookie_secret,
3973 			UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
3974 			sizeof(secret_hex));
3975 		(void)len; /* silence unused variable warning with -DNDEBUG */
3976 		log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
3977 		secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
3978 		if (i == 0)
3979 			(void)ssl_printf(ssl, "active : %s\n",  secret_hex);
3980 		else if (cookie_secrets->cookie_count == 2)
3981 			(void)ssl_printf(ssl, "staging: %s\n",  secret_hex);
3982 		else
3983 			(void)ssl_printf(ssl, "staging[%d]: %s\n", i,
3984 				secret_hex);
3985 	}
3986 	lock_basic_unlock(&cookie_secrets->lock);
3987 	explicit_bzero(secret_hex, sizeof(secret_hex));
3988 }
3989 
3990 /** check that there is no argument after a command that takes no arguments. */
3991 static int
cmd_no_args(RES * ssl,char * cmd,char * p)3992 cmd_no_args(RES* ssl, char* cmd, char* p)
3993 {
3994 	if(p && *p != 0) {
3995 		/* cmd contains the command that is called at the start,
3996 		 * with space or tab after it. */
3997 		char* c = cmd;
3998 		if(strchr(c, ' ') && strchr(c, '\t')) {
3999 			if(strchr(c, ' ') < strchr(c, '\t'))
4000 				*strchr(c, ' ')=0;
4001 			else	*strchr(c, '\t')=0;
4002 		} else if(strchr(c, ' ')) {
4003 			*strchr(c, ' ')=0;
4004 		} else if(strchr(c, '\t')) {
4005 			*strchr(c, '\t')=0;
4006 		}
4007 		(void)ssl_printf(ssl, "error command %s takes no arguments,"
4008 			" have '%s'\n", c, p);
4009 		return 1;
4010 	}
4011 	return 0;
4012 }
4013 
4014 /** check for name with end-of-string, space or tab after it */
4015 static int
cmdcmp(char * p,const char * cmd,size_t len)4016 cmdcmp(char* p, const char* cmd, size_t len)
4017 {
4018 	return strncmp(p,cmd,len)==0 && (p[len]==0||p[len]==' '||p[len]=='\t');
4019 }
4020 
4021 /** execute a remote control command */
4022 static void
execute_cmd(struct daemon_remote * rc,struct rc_state * s,RES * ssl,char * cmd,struct worker * worker)4023 execute_cmd(struct daemon_remote* rc, struct rc_state* s, RES* ssl, char* cmd,
4024 	struct worker* worker)
4025 {
4026 	char* p = skipwhite(cmd);
4027 	/* compare command */
4028 	if(cmdcmp(p, "stop", 4)) {
4029 		if(cmd_no_args(ssl, p, skipwhite(p+4)))
4030 			return;
4031 		do_stop(ssl, worker);
4032 		return;
4033 	} else if(cmdcmp(p, "reload_keep_cache", 17)) {
4034 		if(cmd_no_args(ssl, p, skipwhite(p+17)))
4035 			return;
4036 		do_reload(ssl, worker, 1);
4037 		return;
4038 	} else if(cmdcmp(p, "reload", 6)) {
4039 		if(cmd_no_args(ssl, p, skipwhite(p+6)))
4040 			return;
4041 		do_reload(ssl, worker, 0);
4042 		return;
4043 	} else if(cmdcmp(p, "fast_reload", 11)) {
4044 		do_fast_reload(ssl, worker, s, skipwhite(p+11));
4045 		return;
4046 	} else if(cmdcmp(p, "stats_noreset", 13)) {
4047 		if(cmd_no_args(ssl, p, skipwhite(p+13)))
4048 			return;
4049 		do_stats(ssl, worker, 0);
4050 		return;
4051 	} else if(cmdcmp(p, "stats", 5)) {
4052 		if(cmd_no_args(ssl, p, skipwhite(p+5)))
4053 			return;
4054 		do_stats(ssl, worker, 1);
4055 		return;
4056 	} else if(cmdcmp(p, "status", 6)) {
4057 		if(cmd_no_args(ssl, p, skipwhite(p+6)))
4058 			return;
4059 		do_status(ssl, worker);
4060 		return;
4061 	} else if(cmdcmp(p, "dump_cache", 10)) {
4062 		if(cmd_no_args(ssl, p, skipwhite(p+10)))
4063 			return;
4064 #ifdef THREADS_DISABLED
4065 		if(worker->daemon->num > 1) {
4066 			(void)ssl_printf(ssl, "dump_cache/load_cache is not "
4067 				"supported in multi-process operation\n");
4068 			return;
4069 		}
4070 #endif
4071 		(void)dump_cache(ssl, worker);
4072 		return;
4073 	} else if(cmdcmp(p, "load_cache", 10)) {
4074 		if(cmd_no_args(ssl, p, skipwhite(p+10)))
4075 			return;
4076 #ifdef THREADS_DISABLED
4077 		if(worker->daemon->num > 1) {
4078 			/* The warning can't be printed when stdin is sending
4079 			 * data; just return */
4080 			return;
4081 		}
4082 #endif
4083 		if(load_cache(ssl, worker)) send_ok(ssl);
4084 		return;
4085 	} else if(cmdcmp(p, "list_forwards", 13)) {
4086 		if(cmd_no_args(ssl, p, skipwhite(p+13)))
4087 			return;
4088 		do_list_forwards(ssl, worker);
4089 		return;
4090 	} else if(cmdcmp(p, "list_stubs", 10)) {
4091 		if(cmd_no_args(ssl, p, skipwhite(p+10)))
4092 			return;
4093 		do_list_stubs(ssl, worker);
4094 		return;
4095 	} else if(cmdcmp(p, "list_insecure", 13)) {
4096 		if(cmd_no_args(ssl, p, skipwhite(p+13)))
4097 			return;
4098 		do_insecure_list(ssl, worker);
4099 		return;
4100 	} else if(cmdcmp(p, "list_local_zones", 16)) {
4101 		if(cmd_no_args(ssl, p, skipwhite(p+16)))
4102 			return;
4103 		do_list_local_zones(ssl, worker->daemon->local_zones);
4104 		return;
4105 	} else if(cmdcmp(p, "list_local_data", 15)) {
4106 		if(cmd_no_args(ssl, p, skipwhite(p+15)))
4107 			return;
4108 		do_list_local_data(ssl, worker, worker->daemon->local_zones);
4109 		return;
4110 	} else if(cmdcmp(p, "view_list_local_zones", 21)) {
4111 		do_view_list_local_zones(ssl, worker, skipwhite(p+21));
4112 		return;
4113 	} else if(cmdcmp(p, "view_list_local_data", 20)) {
4114 		do_view_list_local_data(ssl, worker, skipwhite(p+20));
4115 		return;
4116 	} else if(cmdcmp(p, "ratelimit_list", 14)) {
4117 		do_ratelimit_list(ssl, worker, p+14);
4118 		return;
4119 	} else if(cmdcmp(p, "ip_ratelimit_list", 17)) {
4120 		do_ip_ratelimit_list(ssl, worker, p+17);
4121 		return;
4122 	} else if(cmdcmp(p, "list_auth_zones", 15)) {
4123 		if(cmd_no_args(ssl, p, skipwhite(p+15)))
4124 			return;
4125 		do_list_auth_zones(ssl, worker->env.auth_zones);
4126 		return;
4127 	} else if(cmdcmp(p, "auth_zone_reload", 16)) {
4128 		do_auth_zone_reload(ssl, worker, skipwhite(p+16));
4129 		return;
4130 	} else if(cmdcmp(p, "auth_zone_transfer", 18)) {
4131 		do_auth_zone_transfer(ssl, worker, skipwhite(p+18));
4132 		return;
4133 	} else if(cmdcmp(p, "insecure_add", 12)) {
4134 		/* must always distribute this cmd */
4135 		if(rc) distribute_cmd(rc, ssl, cmd);
4136 		do_insecure_add(ssl, worker, skipwhite(p+12));
4137 		return;
4138 	} else if(cmdcmp(p, "insecure_remove", 15)) {
4139 		/* must always distribute this cmd */
4140 		if(rc) distribute_cmd(rc, ssl, cmd);
4141 		do_insecure_remove(ssl, worker, skipwhite(p+15));
4142 		return;
4143 	} else if(cmdcmp(p, "flush_stats", 11)) {
4144 		/* must always distribute this cmd */
4145 		if(cmd_no_args(ssl, p, skipwhite(p+11)))
4146 			return;
4147 		if(rc) distribute_cmd(rc, ssl, cmd);
4148 		do_flush_stats(ssl, worker);
4149 		return;
4150 	} else if(cmdcmp(p, "flush_requestlist", 17)) {
4151 		/* must always distribute this cmd */
4152 		if(cmd_no_args(ssl, p, skipwhite(p+17)))
4153 			return;
4154 		if(rc) distribute_cmd(rc, ssl, cmd);
4155 		do_flush_requestlist(ssl, worker);
4156 		return;
4157 	} else if(cmdcmp(p, "cache_lookup", 12)) {
4158 		do_cache_lookup(ssl, worker, skipwhite(p+12));
4159 		return;
4160 	} else if(cmdcmp(p, "lookup", 6)) {
4161 		do_lookup(ssl, worker, skipwhite(p+6));
4162 		return;
4163 	/* The following are commands that read stdin.
4164 	 * Each line needs to be distributed if THREADS_DISABLED.
4165 	 */
4166 	} else if(cmdcmp(p, "local_zones_remove", 18)) {
4167 		if(cmd_no_args(ssl, p, skipwhite(p+18)))
4168 			return;
4169 		do_zones_remove(rc, ssl, worker);
4170 		return;
4171 	} else if(cmdcmp(p, "local_zones", 11)) {
4172 		if(cmd_no_args(ssl, p, skipwhite(p+11)))
4173 			return;
4174 		do_zones_add(rc, ssl, worker);
4175 		return;
4176 	} else if(cmdcmp(p, "local_datas_remove", 18)) {
4177 		if(cmd_no_args(ssl, p, skipwhite(p+18)))
4178 			return;
4179 		do_datas_remove(rc, ssl, worker);
4180 		return;
4181 	} else if(cmdcmp(p, "local_datas", 11)) {
4182 		if(cmd_no_args(ssl, p, skipwhite(p+11)))
4183 			return;
4184 		do_datas_add(rc, ssl, worker);
4185 		return;
4186 	} else if(cmdcmp(p, "view_local_datas_remove", 23)){
4187 		do_view_datas_remove(rc, ssl, worker, skipwhite(p+23));
4188 		return;
4189 	} else if(cmdcmp(p, "view_local_datas", 16)) {
4190 		do_view_datas_add(rc, ssl, worker, skipwhite(p+16));
4191 		return;
4192 	} else if(cmdcmp(p, "print_cookie_secrets", 20)) {
4193 		if(cmd_no_args(ssl, p, skipwhite(p+20)))
4194 			return;
4195 		do_print_cookie_secrets(ssl, worker);
4196 		return;
4197 	}
4198 
4199 #ifdef THREADS_DISABLED
4200 	/* other processes must execute the command as well */
4201 	/* commands that should not be distributed, returned above. */
4202 	if(rc) { /* only if this thread is the master (rc) thread */
4203 		/* done before the code below, which may split the string */
4204 		distribute_cmd(rc, ssl, cmd);
4205 	}
4206 #endif
4207 	if(cmdcmp(p, "verbosity", 9)) {
4208 		do_verbosity(ssl, skipwhite(p+9));
4209 	} else if(cmdcmp(p, "local_zone_remove", 17)) {
4210 		do_zone_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
4211 	} else if(cmdcmp(p, "local_zone", 10)) {
4212 		do_zone_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
4213 	} else if(cmdcmp(p, "local_data_remove", 17)) {
4214 		do_data_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
4215 	} else if(cmdcmp(p, "local_data", 10)) {
4216 		do_data_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
4217 	} else if(cmdcmp(p, "forward_add", 11)) {
4218 		do_forward_add(ssl, worker, skipwhite(p+11));
4219 	} else if(cmdcmp(p, "forward_remove", 14)) {
4220 		do_forward_remove(ssl, worker, skipwhite(p+14));
4221 	} else if(cmdcmp(p, "forward", 7)) {
4222 		do_forward(ssl, worker, skipwhite(p+7));
4223 	} else if(cmdcmp(p, "stub_add", 8)) {
4224 		do_stub_add(ssl, worker, skipwhite(p+8));
4225 	} else if(cmdcmp(p, "stub_remove", 11)) {
4226 		do_stub_remove(ssl, worker, skipwhite(p+11));
4227 	} else if(cmdcmp(p, "view_local_zone_remove", 22)) {
4228 		do_view_zone_remove(ssl, worker, skipwhite(p+22));
4229 	} else if(cmdcmp(p, "view_local_zone", 15)) {
4230 		do_view_zone_add(ssl, worker, skipwhite(p+15));
4231 	} else if(cmdcmp(p, "view_local_data_remove", 22)) {
4232 		do_view_data_remove(ssl, worker, skipwhite(p+22));
4233 	} else if(cmdcmp(p, "view_local_data", 15)) {
4234 		do_view_data_add(ssl, worker, skipwhite(p+15));
4235 	} else if(cmdcmp(p, "flush_zone", 10)) {
4236 		do_flush_zone(ssl, worker, skipwhite(p+10));
4237 	} else if(cmdcmp(p, "flush_type", 10)) {
4238 		do_flush_type(ssl, worker, skipwhite(p+10));
4239 	} else if(cmdcmp(p, "flush_infra", 11)) {
4240 		do_flush_infra(ssl, worker, skipwhite(p+11));
4241 	} else if(cmdcmp(p, "flush", 5)) {
4242 		do_flush_name(ssl, worker, skipwhite(p+5));
4243 	} else if(cmdcmp(p, "dump_requestlist", 16)) {
4244 		if(cmd_no_args(ssl, p, skipwhite(p+16)))
4245 			return;
4246 		do_dump_requestlist(ssl, worker);
4247 	} else if(cmdcmp(p, "dump_infra", 10)) {
4248 		if(cmd_no_args(ssl, p, skipwhite(p+10)))
4249 			return;
4250 		do_dump_infra(ssl, worker);
4251 	} else if(cmdcmp(p, "log_reopen", 10)) {
4252 		if(cmd_no_args(ssl, p, skipwhite(p+10)))
4253 			return;
4254 		do_log_reopen(ssl, worker);
4255 	} else if(cmdcmp(p, "set_option", 10)) {
4256 		do_set_option(ssl, worker, skipwhite(p+10));
4257 	} else if(cmdcmp(p, "get_option", 10)) {
4258 		do_get_option(ssl, worker, skipwhite(p+10));
4259 	} else if(cmdcmp(p, "flush_bogus", 11)) {
4260 		do_flush_bogus(ssl, worker, skipwhite(p+11));
4261 	} else if(cmdcmp(p, "flush_negative", 14)) {
4262 		do_flush_negative(ssl, worker, skipwhite(p+14));
4263 	} else if(cmdcmp(p, "rpz_enable", 10)) {
4264 		do_rpz_enable(ssl, worker, skipwhite(p+10));
4265 	} else if(cmdcmp(p, "rpz_disable", 11)) {
4266 		do_rpz_disable(ssl, worker, skipwhite(p+11));
4267 	} else if(cmdcmp(p, "add_cookie_secret", 17)) {
4268 		do_add_cookie_secret(ssl, worker, skipwhite(p+17));
4269 	} else if(cmdcmp(p, "drop_cookie_secret", 18)) {
4270 		if(cmd_no_args(ssl, p, skipwhite(p+18)))
4271 			return;
4272 		do_drop_cookie_secret(ssl, worker);
4273 	} else if(cmdcmp(p, "activate_cookie_secret", 22)) {
4274 		if(cmd_no_args(ssl, p, skipwhite(p+22)))
4275 			return;
4276 		do_activate_cookie_secret(ssl, worker);
4277 	} else {
4278 		(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
4279 	}
4280 }
4281 
4282 void
daemon_remote_exec(struct worker * worker)4283 daemon_remote_exec(struct worker* worker)
4284 {
4285 	/* read the cmd string */
4286 	uint8_t* msg = NULL;
4287 	uint32_t len = 0;
4288 	if(!tube_read_msg(worker->cmd, &msg, &len, 0)) {
4289 		log_err("daemon_remote_exec: tube_read_msg failed");
4290 		return;
4291 	}
4292 	verbose(VERB_ALGO, "remote exec distributed: %s", (char*)msg);
4293 	execute_cmd(NULL, NULL, NULL, (char*)msg, worker);
4294 	free(msg);
4295 }
4296 
4297 /** handle remote control request */
4298 static void
handle_req(struct daemon_remote * rc,struct rc_state * s,RES * res)4299 handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
4300 {
4301 	int r;
4302 	char pre[10];
4303 	char magic[7];
4304 	char buf[MAX_CMD_STRLINE];
4305 #ifdef USE_WINSOCK
4306 	/* makes it possible to set the socket blocking again. */
4307 	/* basically removes it from winsock_event ... */
4308 	WSAEventSelect(s->c->fd, NULL, 0);
4309 #endif
4310 	fd_set_block(s->c->fd);
4311 
4312 	/* try to read magic UBCT[version]_space_ string */
4313 	if(res->ssl) {
4314 		ERR_clear_error();
4315 		if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) {
4316 			int r2;
4317 			if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN)
4318 				return;
4319 			log_crypto_err_io("could not SSL_read", r2);
4320 			return;
4321 		}
4322 	} else {
4323 		while(1) {
4324 			ssize_t rr = recv(res->fd, magic, sizeof(magic)-1, 0);
4325 			if(rr <= 0) {
4326 				if(rr == 0) return;
4327 				if(errno == EINTR || errno == EAGAIN)
4328 					continue;
4329 				log_err("could not recv: %s", sock_strerror(errno));
4330 				return;
4331 			}
4332 			r = (int)rr;
4333 			break;
4334 		}
4335 	}
4336 	magic[6] = 0;
4337 	if( r != 6 || strncmp(magic, "UBCT", 4) != 0) {
4338 		verbose(VERB_QUERY, "control connection has bad magic string");
4339 		/* probably wrong tool connected, ignore it completely */
4340 		return;
4341 	}
4342 
4343 	/* read the command line */
4344 	if(!ssl_read_line(res, buf, sizeof(buf))) {
4345 		return;
4346 	}
4347 	snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
4348 	if(strcmp(magic, pre) != 0) {
4349 		verbose(VERB_QUERY, "control connection had bad "
4350 			"version %s, cmd: %s", magic, buf);
4351 		ssl_printf(res, "error version mismatch\n");
4352 		return;
4353 	}
4354 	verbose(VERB_DETAIL, "control cmd: %s", buf);
4355 
4356 	/* figure out what to do */
4357 	execute_cmd(rc, s, res, buf, rc->worker);
4358 }
4359 
4360 /** handle SSL_do_handshake changes to the file descriptor to wait for later */
4361 static int
remote_handshake_later(struct daemon_remote * rc,struct rc_state * s,struct comm_point * c,int r,int r2)4362 remote_handshake_later(struct daemon_remote* rc, struct rc_state* s,
4363 	struct comm_point* c, int r, int r2)
4364 {
4365 	if(r2 == SSL_ERROR_WANT_READ) {
4366 		if(s->shake_state == rc_hs_read) {
4367 			/* try again later */
4368 			return 0;
4369 		}
4370 		s->shake_state = rc_hs_read;
4371 		comm_point_listen_for_rw(c, 1, 0);
4372 		return 0;
4373 	} else if(r2 == SSL_ERROR_WANT_WRITE) {
4374 		if(s->shake_state == rc_hs_write) {
4375 			/* try again later */
4376 			return 0;
4377 		}
4378 		s->shake_state = rc_hs_write;
4379 		comm_point_listen_for_rw(c, 0, 1);
4380 		return 0;
4381 	} else {
4382 		if(r == 0)
4383 			log_err("remote control connection closed prematurely");
4384 		log_addr(VERB_OPS, "failed connection from",
4385 			&s->c->repinfo.remote_addr, s->c->repinfo.remote_addrlen);
4386 		log_crypto_err_io("remote control failed ssl", r2);
4387 		clean_point(rc, s);
4388 	}
4389 	return 0;
4390 }
4391 
remote_control_callback(struct comm_point * c,void * arg,int err,struct comm_reply * ATTR_UNUSED (rep))4392 int remote_control_callback(struct comm_point* c, void* arg, int err,
4393 	struct comm_reply* ATTR_UNUSED(rep))
4394 {
4395 	RES res;
4396 	struct rc_state* s = (struct rc_state*)arg;
4397 	struct daemon_remote* rc = s->rc;
4398 	int r;
4399 	if(err != NETEVENT_NOERROR) {
4400 		if(err==NETEVENT_TIMEOUT)
4401 			log_err("remote control timed out");
4402 		clean_point(rc, s);
4403 		return 0;
4404 	}
4405 	if(s->ssl) {
4406 		/* (continue to) setup the SSL connection */
4407 		ERR_clear_error();
4408 		r = SSL_do_handshake(s->ssl);
4409 		if(r != 1) {
4410 			int r2 = SSL_get_error(s->ssl, r);
4411 			return remote_handshake_later(rc, s, c, r, r2);
4412 		}
4413 		s->shake_state = rc_none;
4414 	}
4415 
4416 	/* once handshake has completed, check authentication */
4417 	if (!rc->use_cert) {
4418 		verbose(VERB_ALGO, "unauthenticated remote control connection");
4419 	} else if(SSL_get_verify_result(s->ssl) == X509_V_OK) {
4420 #ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
4421 		X509* x = SSL_get1_peer_certificate(s->ssl);
4422 #else
4423 		X509* x = SSL_get_peer_certificate(s->ssl);
4424 #endif
4425 		if(!x) {
4426 			verbose(VERB_DETAIL, "remote control connection "
4427 				"provided no client certificate");
4428 			clean_point(rc, s);
4429 			return 0;
4430 		}
4431 		verbose(VERB_ALGO, "remote control connection authenticated");
4432 		X509_free(x);
4433 	} else {
4434 		verbose(VERB_DETAIL, "remote control connection failed to "
4435 			"authenticate with client certificate");
4436 		clean_point(rc, s);
4437 		return 0;
4438 	}
4439 
4440 	/* if OK start to actually handle the request */
4441 	res.ssl = s->ssl;
4442 	res.fd = c->fd;
4443 	handle_req(rc, s, &res);
4444 
4445 	verbose(VERB_ALGO, "remote control operation completed");
4446 	clean_point(rc, s);
4447 	return 0;
4448 }
4449 
4450 /**
4451  * This routine polls a socket for readiness.
4452  * @param fd: file descriptor, -1 uses no fd for a timer only.
4453  * @param timeout: time in msec to wait. 0 means nonblocking test,
4454  * 	-1 waits blocking for events.
4455  * @param pollin: check for input event.
4456  * @param pollout: check for output event.
4457  * @param event: output variable, set to true if the event happens.
4458  * 	It is false if there was an error or timeout.
4459  * @return false is system call failure, also logged.
4460  */
4461 static int
sock_poll_timeout(int fd,int timeout,int pollin,int pollout,int * event)4462 sock_poll_timeout(int fd, int timeout, int pollin, int pollout, int* event)
4463 {
4464 	int loopcount = 0;
4465 	/* Loop if the system call returns an errno to do so, like EINTR. */
4466 	log_assert(pollin || pollout);
4467 	while(1) {
4468 		struct pollfd p, *fds;
4469 		int nfds, ret;
4470 		if(++loopcount > IPC_LOOP_MAX) {
4471 			log_err("sock_poll_timeout: loop");
4472 			if(event)
4473 				*event = 0;
4474 			return 0;
4475 		}
4476 		if(fd == -1) {
4477 			fds = NULL;
4478 			nfds = 0;
4479 		} else {
4480 			fds = &p;
4481 			nfds = 1;
4482 			memset(&p, 0, sizeof(p));
4483 			p.fd = fd;
4484 #ifndef USE_WINSOCK
4485 			p.events = POLLERR
4486 				| POLLHUP
4487 				;
4488 #endif
4489 			if(pollin)
4490 				p.events |= POLLIN;
4491 			if(pollout)
4492 				p.events |= POLLOUT;
4493 		}
4494 #ifndef USE_WINSOCK
4495 		ret = poll(fds, nfds, timeout);
4496 #else
4497 		if(fds == NULL) {
4498 			Sleep(timeout);
4499 			ret = 0;
4500 		} else {
4501 			ret = WSAPoll(fds, nfds, timeout);
4502 		}
4503 #endif
4504 		if(ret == -1) {
4505 #ifndef USE_WINSOCK
4506 			if(
4507 				errno == EINTR || errno == EAGAIN
4508 #  ifdef EWOULDBLOCK
4509 				|| errno == EWOULDBLOCK
4510 #  endif
4511 			) continue; /* Try again. */
4512 #endif
4513 			/* For WSAPoll we only get errors here:
4514 			 * o WSAENETDOWN
4515 			 * o WSAEFAULT
4516 			 * o WSAEINVAL
4517 			 * o WSAENOBUFS
4518 			 */
4519 			log_err("poll: %s", sock_strerror(errno));
4520 			if(event)
4521 				*event = 0;
4522 			return 0;
4523 		} else if(ret == 0) {
4524 			/* Timeout */
4525 			if(event)
4526 				*event = 0;
4527 			return 1;
4528 		}
4529 		break;
4530 	}
4531 	if(event)
4532 		*event = 1;
4533 	return 1;
4534 }
4535 
4536 /** fast reload convert fast reload notification status to string */
4537 static const char*
fr_notification_to_string(enum fast_reload_notification status)4538 fr_notification_to_string(enum fast_reload_notification status)
4539 {
4540 	switch(status) {
4541 	case fast_reload_notification_none:
4542 		return "none";
4543 	case fast_reload_notification_done:
4544 		return "done";
4545 	case fast_reload_notification_done_error:
4546 		return "done_error";
4547 	case fast_reload_notification_exit:
4548 		return "exit";
4549 	case fast_reload_notification_exited:
4550 		return "exited";
4551 	case fast_reload_notification_printout:
4552 		return "printout";
4553 	case fast_reload_notification_reload_stop:
4554 		return "reload_stop";
4555 	case fast_reload_notification_reload_ack:
4556 		return "reload_ack";
4557 	case fast_reload_notification_reload_nopause_poll:
4558 		return "reload_nopause_poll";
4559 	case fast_reload_notification_reload_start:
4560 		return "reload_start";
4561 	default:
4562 		break;
4563 	}
4564 	return "unknown";
4565 }
4566 
4567 #ifndef THREADS_DISABLED
4568 /** fast reload, poll for notification incoming. True if quit */
4569 static int
fr_poll_for_quit(struct fast_reload_thread * fr)4570 fr_poll_for_quit(struct fast_reload_thread* fr)
4571 {
4572 	int inevent, loopexit = 0, bcount = 0;
4573 	uint32_t cmd;
4574 	ssize_t ret;
4575 
4576 	if(fr->need_to_quit)
4577 		return 1;
4578 	/* Is there data? */
4579 	if(!sock_poll_timeout(fr->commpair[1], 0, 1, 0, &inevent)) {
4580 		log_err("fr_poll_for_quit: poll failed");
4581 		return 0;
4582 	}
4583 	if(!inevent)
4584 		return 0;
4585 
4586 	/* Read the data */
4587 	while(1) {
4588 		if(++loopexit > IPC_LOOP_MAX) {
4589 			log_err("fr_poll_for_quit: recv loops %s",
4590 				sock_strerror(errno));
4591 			return 0;
4592 		}
4593 		ret = recv(fr->commpair[1], ((char*)&cmd)+bcount,
4594 			sizeof(cmd)-bcount, 0);
4595 		if(ret == -1) {
4596 			if(
4597 #ifndef USE_WINSOCK
4598 				errno == EINTR || errno == EAGAIN
4599 #  ifdef EWOULDBLOCK
4600 				|| errno == EWOULDBLOCK
4601 #  endif
4602 #else
4603 				WSAGetLastError() == WSAEINTR ||
4604 				WSAGetLastError() == WSAEINPROGRESS ||
4605 				WSAGetLastError() == WSAEWOULDBLOCK
4606 #endif
4607 				)
4608 				continue; /* Try again. */
4609 			log_err("fr_poll_for_quit: recv: %s",
4610 				sock_strerror(errno));
4611 			return 0;
4612 		} else if(ret+(ssize_t)bcount != sizeof(cmd)) {
4613 			bcount += ret;
4614 			if((size_t)bcount < sizeof(cmd))
4615 				continue;
4616 		}
4617 		break;
4618 	}
4619 	if(cmd == fast_reload_notification_exit) {
4620 		fr->need_to_quit = 1;
4621 		verbose(VERB_ALGO, "fast reload: exit notification received");
4622 		return 1;
4623 	}
4624 	log_err("fr_poll_for_quit: unknown notification status received: %d %s",
4625 		cmd, fr_notification_to_string(cmd));
4626 	return 0;
4627 }
4628 
4629 /** fast reload thread. Send notification from the fast reload thread */
4630 static void
fr_send_notification(struct fast_reload_thread * fr,enum fast_reload_notification status)4631 fr_send_notification(struct fast_reload_thread* fr,
4632 	enum fast_reload_notification status)
4633 {
4634 	int outevent, loopexit = 0, bcount = 0;
4635 	uint32_t cmd;
4636 	ssize_t ret;
4637 	verbose(VERB_ALGO, "fast reload: send notification %s",
4638 		fr_notification_to_string(status));
4639 	/* Make a blocking attempt to send. But meanwhile stay responsive,
4640 	 * once in a while for quit commands. In case the server has to quit. */
4641 	/* see if there is incoming quit signals */
4642 	if(fr_poll_for_quit(fr))
4643 		return;
4644 	cmd = status;
4645 	while(1) {
4646 		if(++loopexit > IPC_LOOP_MAX) {
4647 			log_err("fast reload: could not send notification");
4648 			return;
4649 		}
4650 		/* wait for socket to become writable */
4651 		if(!sock_poll_timeout(fr->commpair[1], IPC_NOTIFICATION_WAIT,
4652 			0, 1, &outevent)) {
4653 			log_err("fast reload: poll failed");
4654 			return;
4655 		}
4656 		if(fr_poll_for_quit(fr))
4657 			return;
4658 		if(!outevent)
4659 			continue;
4660 		ret = send(fr->commpair[1], ((char*)&cmd)+bcount,
4661 			sizeof(cmd)-bcount, 0);
4662 		if(ret == -1) {
4663 			if(
4664 #ifndef USE_WINSOCK
4665 				errno == EINTR || errno == EAGAIN
4666 #  ifdef EWOULDBLOCK
4667 				|| errno == EWOULDBLOCK
4668 #  endif
4669 #else
4670 				WSAGetLastError() == WSAEINTR ||
4671 				WSAGetLastError() == WSAEINPROGRESS ||
4672 				WSAGetLastError() == WSAEWOULDBLOCK
4673 #endif
4674 				)
4675 				continue; /* Try again. */
4676 			log_err("fast reload send notification: send: %s",
4677 				sock_strerror(errno));
4678 			return;
4679 		} else if(ret+(ssize_t)bcount != sizeof(cmd)) {
4680 			bcount += ret;
4681 			if((size_t)bcount < sizeof(cmd))
4682 				continue;
4683 		}
4684 		break;
4685 	}
4686 }
4687 
4688 /** fast reload thread queue up text string for output */
4689 static int
fr_output_text(struct fast_reload_thread * fr,const char * msg)4690 fr_output_text(struct fast_reload_thread* fr, const char* msg)
4691 {
4692 	char* item = strdup(msg);
4693 	if(!item) {
4694 		log_err("fast reload output text: strdup out of memory");
4695 		return 0;
4696 	}
4697 	lock_basic_lock(&fr->fr_output_lock);
4698 	if(!cfg_strlist_append(fr->fr_output, item)) {
4699 		lock_basic_unlock(&fr->fr_output_lock);
4700 		/* The item is freed by cfg_strlist_append on failure. */
4701 		log_err("fast reload output text: append out of memory");
4702 		return 0;
4703 	}
4704 	lock_basic_unlock(&fr->fr_output_lock);
4705 	return 1;
4706 }
4707 
4708 /** fast reload thread output vmsg function */
4709 static int
fr_output_vmsg(struct fast_reload_thread * fr,const char * format,va_list args)4710 fr_output_vmsg(struct fast_reload_thread* fr, const char* format, va_list args)
4711 {
4712 	char msg[1024];
4713 	vsnprintf(msg, sizeof(msg), format, args);
4714 	return fr_output_text(fr, msg);
4715 }
4716 
4717 /** fast reload thread printout function, with printf arguments */
4718 static int fr_output_printf(struct fast_reload_thread* fr,
4719 	const char* format, ...) ATTR_FORMAT(printf, 2, 3);
4720 
4721 /** fast reload thread printout function, prints to list and signals
4722  * the remote control thread to move that to get written to the socket
4723  * of the remote control connection. */
4724 static int
fr_output_printf(struct fast_reload_thread * fr,const char * format,...)4725 fr_output_printf(struct fast_reload_thread* fr, const char* format, ...)
4726 {
4727 	va_list args;
4728 	int ret;
4729 	va_start(args, format);
4730 	ret = fr_output_vmsg(fr, format, args);
4731 	va_end(args);
4732 	return ret;
4733 }
4734 
4735 /** fast reload thread, init time counters */
4736 static void
fr_init_time(struct timeval * time_start,struct timeval * time_read,struct timeval * time_construct,struct timeval * time_reload,struct timeval * time_end)4737 fr_init_time(struct timeval* time_start, struct timeval* time_read,
4738 	struct timeval* time_construct, struct timeval* time_reload,
4739 	struct timeval* time_end)
4740 {
4741 	memset(time_start, 0, sizeof(*time_start));
4742 	memset(time_read, 0, sizeof(*time_read));
4743 	memset(time_construct, 0, sizeof(*time_construct));
4744 	memset(time_reload, 0, sizeof(*time_reload));
4745 	memset(time_end, 0, sizeof(*time_end));
4746 	if(gettimeofday(time_start, NULL) < 0)
4747 		log_err("gettimeofday: %s", strerror(errno));
4748 }
4749 
4750 /**
4751  * Structure with constructed elements for use during fast reload.
4752  * At the start it contains the tree items for the new config.
4753  * After the tree items are swapped into the server, the old elements
4754  * are kept in here. They can then be deleted.
4755  */
4756 struct fast_reload_construct {
4757 	/** ssl context for listening to dnstcp over ssl */
4758 	void* listen_dot_sslctx;
4759 	/** ssl context for connecting to dnstcp over ssl */
4760 	void* connect_dot_sslctx;
4761 	/** ssl context for listening to DoH */
4762 	void* listen_doh_sslctx;
4763 	/** ssl context for listening to quic */
4764 	void* listen_quic_sslctx;
4765 	/** the file name that the ssl context is made with, private key. */
4766 	char* ssl_service_key;
4767 	/** the file name that the ssl context is made with, certificate. */
4768 	char* ssl_service_pem;
4769 	/** modification time for ssl_service_key, in sec and ns. Like
4770 	 * in a struct timespec, but without that for portability. */
4771 	time_t mtime_ssl_service_key;
4772 	long mtime_ns_ssl_service_key;
4773 	/** modification time for ssl_service_pem, in sec and ns. Like
4774 	 * in a struct timespec, but without that for portability. */
4775 	time_t mtime_ssl_service_pem;
4776 	long mtime_ns_ssl_service_pem;
4777 	/** construct for views */
4778 	struct views* views;
4779 	/** construct for auth zones */
4780 	struct auth_zones* auth_zones;
4781 	/** construct for forwards */
4782 	struct iter_forwards* fwds;
4783 	/** construct for stubs */
4784 	struct iter_hints* hints;
4785 	/** construct for respip_set */
4786 	struct respip_set* respip_set;
4787 	/** construct for access control */
4788 	struct acl_list* acl;
4789 	/** construct for access control interface */
4790 	struct acl_list* acl_interface;
4791 	/** construct for tcp connection limit */
4792 	struct tcl_list* tcl;
4793 	/** construct for local zones */
4794 	struct local_zones* local_zones;
4795 	/** if there is response ip configuration in use */
4796 	int use_response_ip;
4797 	/** if there is an rpz zone */
4798 	int use_rpz;
4799 	/** construct for edns strings */
4800 	struct edns_strings* edns_strings;
4801 	/** construct for trust anchors */
4802 	struct val_anchors* anchors;
4803 	/** construct for nsec3 key size */
4804 	size_t* nsec3_keysize;
4805 	/** construct for nsec3 max iter */
4806 	size_t* nsec3_maxiter;
4807 	/** construct for nsec3 keyiter count */
4808 	int nsec3_keyiter_count;
4809 	/** construct for target fetch policy */
4810 	int* target_fetch_policy;
4811 	/** construct for max dependency depth */
4812 	int max_dependency_depth;
4813 	/** construct for donotquery addresses */
4814 	struct iter_donotq* donotq;
4815 	/** construct for private addresses and domains */
4816 	struct iter_priv* priv;
4817 	/** construct whitelist for capsforid names */
4818 	struct rbtree_type* caps_white;
4819 	/** construct for nat64 */
4820 	struct iter_nat64 nat64;
4821 	/** construct for wait_limits_netblock */
4822 	struct rbtree_type wait_limits_netblock;
4823 	/** construct for wait_limits_cookie_netblock */
4824 	struct rbtree_type wait_limits_cookie_netblock;
4825 	/** construct for domain limits */
4826 	struct rbtree_type domain_limits;
4827 	/** storage for the old configuration elements. The outer struct
4828 	 * is allocated with malloc here, the items are from config. */
4829 	struct config_file* oldcfg;
4830 };
4831 
4832 /** fast reload thread, read config */
4833 static int
fr_read_config(struct fast_reload_thread * fr,struct config_file ** newcfg)4834 fr_read_config(struct fast_reload_thread* fr, struct config_file** newcfg)
4835 {
4836 	/* Create new config structure. */
4837 	*newcfg = config_create();
4838 	if(!*newcfg) {
4839 		if(!fr_output_printf(fr, "config_create failed: out of memory\n"))
4840 			return 0;
4841 		fr_send_notification(fr, fast_reload_notification_printout);
4842 		return 0;
4843 	}
4844 	if(fr_poll_for_quit(fr))
4845 		return 1;
4846 
4847 	/* Read new config from file */
4848 	if(!config_read(*newcfg, fr->worker->daemon->cfgfile,
4849 		fr->worker->daemon->chroot)) {
4850 		config_delete(*newcfg);
4851 		if(!fr_output_printf(fr, "config_read %s%s%s%s failed: %s\n",
4852 			(fr->worker->daemon->chroot?"<chroot:":""),
4853 			(fr->worker->daemon->chroot?fr->worker->daemon->chroot:""),
4854 			(fr->worker->daemon->chroot?"> ":""),
4855 			fr->worker->daemon->cfgfile, strerror(errno)))
4856 			return 0;
4857 		fr_send_notification(fr, fast_reload_notification_printout);
4858 		return 0;
4859 	}
4860 	if(fr_poll_for_quit(fr))
4861 		return 1;
4862 	if(fr->fr_verb >= 1) {
4863 		if(!fr_output_printf(fr, "done read config file %s%s%s%s\n",
4864 			(fr->worker->daemon->chroot?"<chroot:":""),
4865 			(fr->worker->daemon->chroot?fr->worker->daemon->chroot:""),
4866 			(fr->worker->daemon->chroot?"> ":""),
4867 			fr->worker->daemon->cfgfile))
4868 			return 0;
4869 		fr_send_notification(fr, fast_reload_notification_printout);
4870 	}
4871 
4872 	return 1;
4873 }
4874 
4875 /** Check if two taglists are equal. */
4876 static int
taglist_equal(char ** tagname_a,int num_tags_a,char ** tagname_b,int num_tags_b)4877 taglist_equal(char** tagname_a, int num_tags_a, char** tagname_b,
4878 	int num_tags_b)
4879 {
4880 	int i;
4881 	if(num_tags_a != num_tags_b)
4882 		return 0;
4883 	for(i=0; i<num_tags_a; i++) {
4884 		if(strcmp(tagname_a[i], tagname_b[i]) != 0)
4885 			return 0;
4886 	}
4887 	return 1;
4888 }
4889 
4890 /** Check the change from a to b is only new entries at the end. */
4891 static int
taglist_change_at_end(char ** tagname_a,int num_tags_a,char ** tagname_b,int num_tags_b)4892 taglist_change_at_end(char** tagname_a, int num_tags_a, char** tagname_b,
4893 	int num_tags_b)
4894 {
4895 	if(num_tags_a < 0 || num_tags_b < 0)
4896 		return 0;
4897 	if(num_tags_a >= num_tags_b)
4898 		return 0;
4899 	/* So, b is longer than a. Check if the initial start of the two
4900 	 * taglists is the same. */
4901 	if(!taglist_equal(tagname_a, num_tags_a, tagname_b, num_tags_a))
4902 		return 0;
4903 	return 1;
4904 }
4905 
4906 /** fast reload thread, check tag defines. */
4907 static int
fr_check_tag_defines(struct fast_reload_thread * fr,struct config_file * newcfg)4908 fr_check_tag_defines(struct fast_reload_thread* fr, struct config_file* newcfg)
4909 {
4910 	/* The tags are kept in a bitlist for items. Some of them are stored
4911 	 * in query info. If the tags change, then the old values are
4912 	 * inaccurate. The solution is to then flush the query list.
4913 	 * Unless the change only involves adding new tags at the end, that
4914 	 * needs no changes. */
4915 	if(!taglist_equal(fr->worker->daemon->cfg->tagname,
4916 			fr->worker->daemon->cfg->num_tags, newcfg->tagname,
4917 			newcfg->num_tags) &&
4918 		!taglist_change_at_end(fr->worker->daemon->cfg->tagname,
4919 			fr->worker->daemon->cfg->num_tags, newcfg->tagname,
4920 			newcfg->num_tags)) {
4921 		/* The tags have changed too much, the define-tag config. */
4922 		if(fr->fr_drop_mesh)
4923 			return 1; /* already dropping queries */
4924 		fr->fr_drop_mesh = 1;
4925 		fr->worker->daemon->fast_reload_drop_mesh = fr->fr_drop_mesh;
4926 		if(!fr_output_printf(fr, "tags have changed, with "
4927 			"'define-tag', and the queries have to be dropped "
4928 			"for consistency, setting '+d'\n"))
4929 			return 0;
4930 		fr_send_notification(fr, fast_reload_notification_printout);
4931 	}
4932 	return 1;
4933 }
4934 
4935 /** fast reload thread, add incompatible option to the explanatory string */
4936 static void
fr_add_incompatible_option(const char * desc,char * str,size_t len)4937 fr_add_incompatible_option(const char* desc, char* str, size_t len)
4938 {
4939 	size_t slen = strlen(str);
4940 	size_t desclen = strlen(desc);
4941 	if(slen == 0) {
4942 		snprintf(str, len, "%s", desc);
4943 		return;
4944 	}
4945 	if(len - slen < desclen+2)
4946 		return; /* It does not fit */
4947 	snprintf(str+slen, len-slen, " %s", desc);
4948 }
4949 
4950 /** fast reload thread, check if config item has changed; thus incompatible */
4951 #define FR_CHECK_CHANGED_CFG(desc, var, str)				\
4952 do {									\
4953 	if(cfg->var != newcfg->var) {					\
4954 		fr_add_incompatible_option(desc, str, sizeof(str));	\
4955 	}								\
4956 } while(0);
4957 
4958 /** fast reload thread, check if config string has changed, checks NULLs. */
4959 #define FR_CHECK_CHANGED_CFG_STR(desc, var, str)			\
4960 do {									\
4961 	if((!cfg->var && newcfg->var) ||				\
4962 		(cfg->var && !newcfg->var) ||				\
4963 		(cfg->var && newcfg->var				\
4964 		&& strcmp(cfg->var, newcfg->var) != 0)) {		\
4965 		fr_add_incompatible_option(desc, str, sizeof(str));	\
4966 	}								\
4967 } while(0);
4968 
4969 /** fast reload thread, check if config strlist has changed. */
4970 #define FR_CHECK_CHANGED_CFG_STRLIST(desc, var, str) do {		\
4971 	fr_check_changed_cfg_strlist(cfg->var, newcfg->var, desc, str,	\
4972 		sizeof(str));						\
4973 	} while(0);
4974 static void
fr_check_changed_cfg_strlist(struct config_strlist * cmp1,struct config_strlist * cmp2,const char * desc,char * str,size_t len)4975 fr_check_changed_cfg_strlist(struct config_strlist* cmp1,
4976 	struct config_strlist* cmp2, const char* desc, char* str, size_t len)
4977 {
4978 	struct config_strlist* p1 = cmp1, *p2 = cmp2;
4979 	while(p1 && p2) {
4980 		if((!p1->str && p2->str) ||
4981 			(p1->str && !p2->str) ||
4982 			(p1->str && p2->str && strcmp(p1->str, p2->str) != 0)) {
4983 			/* The strlist is different. */
4984 			fr_add_incompatible_option(desc, str, len);
4985 			return;
4986 		}
4987 		p1 = p1->next;
4988 		p2 = p2->next;
4989 	}
4990 	if((!p1 && p2) || (p1 && !p2)) {
4991 		fr_add_incompatible_option(desc, str, len);
4992 	}
4993 }
4994 
4995 /** fast reload thread, check if config str2list has changed. */
4996 #define FR_CHECK_CHANGED_CFG_STR2LIST(desc, var, buff) do {		\
4997 	fr_check_changed_cfg_str2list(cfg->var, newcfg->var, desc, buff,\
4998 		sizeof(buff));						\
4999 	} while(0);
5000 static void
fr_check_changed_cfg_str2list(struct config_str2list * cmp1,struct config_str2list * cmp2,const char * desc,char * str,size_t len)5001 fr_check_changed_cfg_str2list(struct config_str2list* cmp1,
5002 	struct config_str2list* cmp2, const char* desc, char* str, size_t len)
5003 {
5004 	struct config_str2list* p1 = cmp1, *p2 = cmp2;
5005 	while(p1 && p2) {
5006 		if((!p1->str && p2->str) ||
5007 			(p1->str && !p2->str) ||
5008 			(p1->str && p2->str && strcmp(p1->str, p2->str) != 0)) {
5009 			/* The str2list is different. */
5010 			fr_add_incompatible_option(desc, str, len);
5011 			return;
5012 		}
5013 		if((!p1->str2 && p2->str2) ||
5014 			(p1->str2 && !p2->str2) ||
5015 			(p1->str2 && p2->str2 &&
5016 			strcmp(p1->str2, p2->str2) != 0)) {
5017 			/* The str2list is different. */
5018 			fr_add_incompatible_option(desc, str, len);
5019 			return;
5020 		}
5021 		p1 = p1->next;
5022 		p2 = p2->next;
5023 	}
5024 	if((!p1 && p2) || (p1 && !p2)) {
5025 		fr_add_incompatible_option(desc, str, len);
5026 	}
5027 }
5028 
5029 /** fast reload thread, check if config str3list has changed. */
5030 #define FR_CHECK_CHANGED_CFG_STR3LIST(desc, var, buff) do {		\
5031 	fr_check_changed_cfg_str3list(cfg->var, newcfg->var, desc, buff,\
5032 		sizeof(buff));						\
5033 	} while(0);
5034 static void
fr_check_changed_cfg_str3list(struct config_str3list * cmp1,struct config_str3list * cmp2,const char * desc,char * str,size_t len)5035 fr_check_changed_cfg_str3list(struct config_str3list* cmp1,
5036 	struct config_str3list* cmp2, const char* desc, char* str, size_t len)
5037 {
5038 	struct config_str3list* p1 = cmp1, *p2 = cmp2;
5039 	while(p1 && p2) {
5040 		if((!p1->str && p2->str) ||
5041 			(p1->str && !p2->str) ||
5042 			(p1->str && p2->str && strcmp(p1->str, p2->str) != 0)) {
5043 			/* The str3list is different. */
5044 			fr_add_incompatible_option(desc, str, len);
5045 			return;
5046 		}
5047 		if((!p1->str2 && p2->str2) ||
5048 			(p1->str2 && !p2->str2) ||
5049 			(p1->str2 && p2->str2 &&
5050 			strcmp(p1->str2, p2->str2) != 0)) {
5051 			/* The str3list is different. */
5052 			fr_add_incompatible_option(desc, str, len);
5053 			return;
5054 		}
5055 		if((!p1->str3 && p2->str3) ||
5056 			(p1->str3 && !p2->str3) ||
5057 			(p1->str3 && p2->str3 &&
5058 			strcmp(p1->str3, p2->str3) != 0)) {
5059 			/* The str3list is different. */
5060 			fr_add_incompatible_option(desc, str, len);
5061 			return;
5062 		}
5063 		p1 = p1->next;
5064 		p2 = p2->next;
5065 	}
5066 	if((!p1 && p2) || (p1 && !p2)) {
5067 		fr_add_incompatible_option(desc, str, len);
5068 	}
5069 }
5070 
5071 /** fast reload thread, check tag datas. */
5072 static int
fr_check_tag_datas(struct fast_reload_thread * fr,struct config_file * newcfg)5073 fr_check_tag_datas(struct fast_reload_thread* fr, struct config_file* newcfg)
5074 {
5075 	char changed_str[1024];
5076 	struct config_file* cfg = fr->worker->env.cfg;
5077 	changed_str[0]=0;
5078 
5079 	/* Check for tag_datas in acl_addr. */
5080 	FR_CHECK_CHANGED_CFG_STR3LIST("interface-tag-data", interface_tag_datas, changed_str);
5081 	FR_CHECK_CHANGED_CFG_STR3LIST("access-control-tag-data", acl_tag_datas, changed_str);
5082 
5083 	if(changed_str[0] != 0) {
5084 		if(fr->fr_drop_mesh)
5085 			return 1; /* already dropping queries */
5086 		fr->fr_drop_mesh = 1;
5087 		fr->worker->daemon->fast_reload_drop_mesh = fr->fr_drop_mesh;
5088 		if(!fr_output_printf(fr, "recursion referenced data has changed, with: '%s"
5089 			"', and the queries have to be dropped"
5090 			", setting '+d'\n", changed_str))
5091 			return 0;
5092 		fr_send_notification(fr, fast_reload_notification_printout);
5093 	}
5094 	return 1;
5095 }
5096 
5097 /** fast reload thread, check compatible config items */
5098 static int
fr_check_compat_cfg(struct fast_reload_thread * fr,struct config_file * newcfg)5099 fr_check_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg)
5100 {
5101 	int i;
5102 	char changed_str[1024];
5103 	struct config_file* cfg = fr->worker->env.cfg;
5104 	changed_str[0]=0;
5105 
5106 	/* Find incompatible options, and if so, print an error. */
5107 	FR_CHECK_CHANGED_CFG("num-threads", num_threads, changed_str);
5108 	FR_CHECK_CHANGED_CFG("do-ip4", do_ip4, changed_str);
5109 	FR_CHECK_CHANGED_CFG("do-ip6", do_ip6, changed_str);
5110 	FR_CHECK_CHANGED_CFG("do-udp", do_udp, changed_str);
5111 	FR_CHECK_CHANGED_CFG("do-tcp", do_tcp, changed_str);
5112 	FR_CHECK_CHANGED_CFG("port", port, changed_str);
5113 	/* But cfg->outgoing_num_ports has been changed at startup,
5114 	 * possibly to reduce it, so do not check it here. */
5115 	FR_CHECK_CHANGED_CFG("outgoing-num-tcp", outgoing_num_tcp, changed_str);
5116 	FR_CHECK_CHANGED_CFG("incoming-num-tcp", incoming_num_tcp, changed_str);
5117 	FR_CHECK_CHANGED_CFG("outgoing-interface", num_out_ifs, changed_str);
5118 	if(cfg->num_out_ifs == newcfg->num_out_ifs) {
5119 		for(i=0; i<cfg->num_out_ifs; i++)
5120 			FR_CHECK_CHANGED_CFG_STR("outgoing-interface",
5121 				out_ifs[i], changed_str);
5122 	}
5123 	FR_CHECK_CHANGED_CFG("interface", num_ifs, changed_str);
5124 	if(cfg->num_ifs == newcfg->num_ifs) {
5125 		for(i=0; i<cfg->num_ifs; i++)
5126 			FR_CHECK_CHANGED_CFG_STR("interface",
5127 				ifs[i], changed_str);
5128 	}
5129 	FR_CHECK_CHANGED_CFG("interface-automatic", if_automatic, changed_str);
5130 	FR_CHECK_CHANGED_CFG("so-rcvbuf", so_rcvbuf, changed_str);
5131 	FR_CHECK_CHANGED_CFG("so-sndbuf", so_sndbuf, changed_str);
5132 	FR_CHECK_CHANGED_CFG("so-reuseport", so_reuseport, changed_str);
5133 	FR_CHECK_CHANGED_CFG("ip-transparent", ip_transparent, changed_str);
5134 	FR_CHECK_CHANGED_CFG("ip-freebind", ip_freebind, changed_str);
5135 	FR_CHECK_CHANGED_CFG("udp-connect", udp_connect, changed_str);
5136 	FR_CHECK_CHANGED_CFG("msg-buffer-size", msg_buffer_size, changed_str);
5137 	FR_CHECK_CHANGED_CFG("edns-tcp-keepalive", do_tcp_keepalive, changed_str);
5138 	FR_CHECK_CHANGED_CFG("edns-tcp-keepalive-timeout", tcp_keepalive_timeout, changed_str);
5139 	FR_CHECK_CHANGED_CFG("tcp-idle-timeout", tcp_idle_timeout, changed_str);
5140 	/* Not changed, only if DoH is used, it is then stored in commpoints,
5141 	 * as well as used from cfg. */
5142 	FR_CHECK_CHANGED_CFG("harden-large-queries", harden_large_queries, changed_str);
5143 	FR_CHECK_CHANGED_CFG("http-max-streams", http_max_streams, changed_str);
5144 	FR_CHECK_CHANGED_CFG_STR("http-endpoint", http_endpoint, changed_str);
5145 	FR_CHECK_CHANGED_CFG("http_notls_downstream", http_notls_downstream, changed_str);
5146 	FR_CHECK_CHANGED_CFG("https-port", https_port, changed_str);
5147 	FR_CHECK_CHANGED_CFG("tls-port", ssl_port, changed_str);
5148 	FR_CHECK_CHANGED_CFG_STR("tls-protocols", tls_protocols, changed_str);
5149 	FR_CHECK_CHANGED_CFG_STRLIST("proxy-protocol-port", proxy_protocol_port, changed_str);
5150 	FR_CHECK_CHANGED_CFG_STRLIST("tls-additional-port", tls_additional_port, changed_str);
5151 	FR_CHECK_CHANGED_CFG_STR("interface-automatic-ports", if_automatic_ports, changed_str);
5152 	FR_CHECK_CHANGED_CFG("udp-upstream-without-downstream", udp_upstream_without_downstream, changed_str);
5153 
5154 	if(changed_str[0] != 0) {
5155 		/* The new config changes some items that do not work with
5156 		 * fast reload. */
5157 		if(!fr_output_printf(fr, "The config changes items that are "
5158 			"not compatible with fast_reload, perhaps do reload "
5159 			"or restart: %s", changed_str) ||
5160 			!fr_output_printf(fr, "\n"))
5161 			return 0;
5162 		fr_send_notification(fr, fast_reload_notification_printout);
5163 		return 0;
5164 	}
5165 	return 1;
5166 }
5167 
5168 /** fast reload thread, check nopause config items */
5169 static int
fr_check_nopause_compat_cfg(struct fast_reload_thread * fr,struct config_file * newcfg)5170 fr_check_nopause_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg)
5171 {
5172 	char changed_str[1024];
5173 	struct config_file* cfg = fr->worker->env.cfg;
5174 	if(!fr->fr_nopause)
5175 		return 1; /* The nopause is not enabled, so no problem. */
5176 	changed_str[0]=0;
5177 
5178 	/* Check for iter_env. */
5179 	FR_CHECK_CHANGED_CFG("outbound-msg-retry", outbound_msg_retry, changed_str);
5180 	FR_CHECK_CHANGED_CFG("max-sent-count", max_sent_count, changed_str);
5181 	FR_CHECK_CHANGED_CFG("max-query-restarts", max_query_restarts, changed_str);
5182 	FR_CHECK_CHANGED_CFG_STR("target-fetch-policy", target_fetch_policy, changed_str);
5183 	FR_CHECK_CHANGED_CFG("do-not-query-localhost", donotquery_localhost, changed_str);
5184 	FR_CHECK_CHANGED_CFG_STRLIST("do-not-query-address", donotqueryaddrs, changed_str);
5185 	FR_CHECK_CHANGED_CFG_STRLIST("private-address", private_address, changed_str);
5186 	FR_CHECK_CHANGED_CFG_STRLIST("private-domain", private_domain, changed_str);
5187 	FR_CHECK_CHANGED_CFG_STRLIST("caps-exempt", caps_whitelist, changed_str);
5188 	FR_CHECK_CHANGED_CFG("do-nat64", do_nat64, changed_str);
5189 	FR_CHECK_CHANGED_CFG_STR("nat64-prefix", nat64_prefix, changed_str);
5190 
5191 	/* Check for val_env. */
5192 	FR_CHECK_CHANGED_CFG("val-bogus-ttl", bogus_ttl, changed_str);
5193 	FR_CHECK_CHANGED_CFG("val-date-override", val_date_override, changed_str);
5194 	FR_CHECK_CHANGED_CFG("val-sig-skew-min", val_sig_skew_min, changed_str);
5195 	FR_CHECK_CHANGED_CFG("val-sig-skew-max", val_sig_skew_max, changed_str);
5196 	FR_CHECK_CHANGED_CFG("val-max-restart", val_max_restart, changed_str);
5197 	FR_CHECK_CHANGED_CFG_STR("val-nsec3-keysize-iterations",
5198 		val_nsec3_key_iterations, changed_str);
5199 
5200 	/* Check for infra. */
5201 	FR_CHECK_CHANGED_CFG("infra-host-ttl", host_ttl, changed_str);
5202 	FR_CHECK_CHANGED_CFG("infra-keep-probing", infra_keep_probing, changed_str);
5203 	FR_CHECK_CHANGED_CFG("ratelimit", ratelimit, changed_str);
5204 	FR_CHECK_CHANGED_CFG("ip-ratelimit", ip_ratelimit, changed_str);
5205 	FR_CHECK_CHANGED_CFG("ip-ratelimit-cookie", ip_ratelimit_cookie, changed_str);
5206 	FR_CHECK_CHANGED_CFG_STR2LIST("wait-limit-netblock", wait_limit_netblock, changed_str);
5207 	FR_CHECK_CHANGED_CFG_STR2LIST("wait-limit-cookie-netblock", wait_limit_cookie_netblock, changed_str);
5208 	FR_CHECK_CHANGED_CFG_STR2LIST("ratelimit-below-domain", ratelimit_below_domain, changed_str);
5209 	FR_CHECK_CHANGED_CFG_STR2LIST("ratelimit-for-domain", ratelimit_for_domain, changed_str);
5210 
5211 	/* Check for dnstap. */
5212 	FR_CHECK_CHANGED_CFG("dnstap-send-identity", dnstap_send_identity, changed_str);
5213 	FR_CHECK_CHANGED_CFG("dnstap-send-version", dnstap_send_version, changed_str);
5214 	FR_CHECK_CHANGED_CFG_STR("dnstap-identity", dnstap_identity, changed_str);
5215 	FR_CHECK_CHANGED_CFG_STR("dnstap-version", dnstap_version, changed_str);
5216 
5217 	if(changed_str[0] != 0) {
5218 		/* The new config changes some items that need a pause,
5219 		 * to be able to update the variables. */
5220 		if(!fr_output_printf(fr, "The config changes items that need "
5221 			"the fast_reload +p option, for nopause, "
5222 			"disabled to be reloaded: %s", changed_str) ||
5223 			!fr_output_printf(fr, "\n"))
5224 			return 0;
5225 		fr_send_notification(fr, fast_reload_notification_printout);
5226 		return 0;
5227 	}
5228 	return 1;
5229 }
5230 
5231 /** fast reload thread, clear construct information, deletes items */
5232 static void
fr_construct_clear(struct fast_reload_construct * ct)5233 fr_construct_clear(struct fast_reload_construct* ct)
5234 {
5235 	if(!ct)
5236 		return;
5237 	auth_zones_delete(ct->auth_zones);
5238 	forwards_delete(ct->fwds);
5239 	hints_delete(ct->hints);
5240 	respip_set_delete(ct->respip_set);
5241 	local_zones_delete(ct->local_zones);
5242 	acl_list_delete(ct->acl);
5243 	acl_list_delete(ct->acl_interface);
5244 	tcl_list_delete(ct->tcl);
5245 	edns_strings_delete(ct->edns_strings);
5246 	anchors_delete(ct->anchors);
5247 	views_delete(ct->views);
5248 	free(ct->nsec3_keysize);
5249 	free(ct->nsec3_maxiter);
5250 	free(ct->target_fetch_policy);
5251 	donotq_delete(ct->donotq);
5252 	priv_delete(ct->priv);
5253 	caps_white_delete(ct->caps_white);
5254 	wait_limits_free(&ct->wait_limits_netblock);
5255 	wait_limits_free(&ct->wait_limits_cookie_netblock);
5256 	domain_limits_free(&ct->domain_limits);
5257 #ifdef HAVE_SSL
5258 	/* The SSL contexts can be SSL_CTX_free here. It is reference
5259 	 * counted. So ongoing transfers with can continue.
5260 	 * Once they are done, the context is freed. */
5261 	SSL_CTX_free((SSL_CTX*)ct->listen_dot_sslctx);
5262 	SSL_CTX_free((SSL_CTX*)ct->connect_dot_sslctx);
5263 	SSL_CTX_free((SSL_CTX*)ct->listen_doh_sslctx);
5264 #endif /* HAVE_SSL */
5265 #ifdef HAVE_NGTCP2
5266 	SSL_CTX_free((SSL_CTX*)ct->listen_quic_sslctx);
5267 #endif
5268 	free(ct->ssl_service_key);
5269 	free(ct->ssl_service_pem);
5270 	/* Delete the log identity here so that the global value is not
5271 	 * reset by config_delete. */
5272 	if(ct->oldcfg && ct->oldcfg->log_identity) {
5273 		free(ct->oldcfg->log_identity);
5274 		ct->oldcfg->log_identity = NULL;
5275 	}
5276 	config_delete(ct->oldcfg);
5277 }
5278 
5279 /** get memory for strlist */
5280 static size_t
getmem_config_strlist(struct config_strlist * p)5281 getmem_config_strlist(struct config_strlist* p)
5282 {
5283 	size_t m = 0;
5284 	struct config_strlist* s;
5285 	for(s = p; s; s = s->next)
5286 		m += sizeof(*s) + getmem_str(s->str);
5287 	return m;
5288 }
5289 
5290 /** get memory for str2list */
5291 static size_t
getmem_config_str2list(struct config_str2list * p)5292 getmem_config_str2list(struct config_str2list* p)
5293 {
5294 	size_t m = 0;
5295 	struct config_str2list* s;
5296 	for(s = p; s; s = s->next)
5297 		m += sizeof(*s) + getmem_str(s->str) + getmem_str(s->str2);
5298 	return m;
5299 }
5300 
5301 /** get memory for str3list */
5302 static size_t
getmem_config_str3list(struct config_str3list * p)5303 getmem_config_str3list(struct config_str3list* p)
5304 {
5305 	size_t m = 0;
5306 	struct config_str3list* s;
5307 	for(s = p; s; s = s->next)
5308 		m += sizeof(*s) + getmem_str(s->str) + getmem_str(s->str2)
5309 			+ getmem_str(s->str3);
5310 	return m;
5311 }
5312 
5313 /** get memory for strbytelist */
5314 static size_t
getmem_config_strbytelist(struct config_strbytelist * p)5315 getmem_config_strbytelist(struct config_strbytelist* p)
5316 {
5317 	size_t m = 0;
5318 	struct config_strbytelist* s;
5319 	for(s = p; s; s = s->next)
5320 		m += sizeof(*s) + getmem_str(s->str) + (s->str2?s->str2len:0);
5321 	return m;
5322 }
5323 
5324 /** get memory used by ifs array */
5325 static size_t
getmem_ifs(int numifs,char ** ifs)5326 getmem_ifs(int numifs, char** ifs)
5327 {
5328 	size_t m = 0;
5329 	int i;
5330 	m += numifs * sizeof(char*);
5331 	for(i=0; i<numifs; i++)
5332 		m += getmem_str(ifs[i]);
5333 	return m;
5334 }
5335 
5336 /** get memory for config_stub */
5337 static size_t
getmem_config_stub(struct config_stub * p)5338 getmem_config_stub(struct config_stub* p)
5339 {
5340 	size_t m = 0;
5341 	struct config_stub* s;
5342 	for(s = p; s; s = s->next)
5343 		m += sizeof(*s) + getmem_str(s->name)
5344 			+ getmem_config_strlist(s->hosts)
5345 			+ getmem_config_strlist(s->addrs);
5346 	return m;
5347 }
5348 
5349 /** get memory for config_auth */
5350 static size_t
getmem_config_auth(struct config_auth * p)5351 getmem_config_auth(struct config_auth* p)
5352 {
5353 	size_t m = 0;
5354 	struct config_auth* s;
5355 	for(s = p; s; s = s->next)
5356 		m += sizeof(*s) + getmem_str(s->name)
5357 			+ getmem_config_strlist(s->masters)
5358 			+ getmem_config_strlist(s->urls)
5359 			+ getmem_config_strlist(s->allow_notify)
5360 			+ getmem_str(s->zonefile)
5361 			+ s->rpz_taglistlen
5362 			+ getmem_str(s->rpz_action_override)
5363 			+ getmem_str(s->rpz_log_name)
5364 			+ getmem_str(s->rpz_cname);
5365 	return m;
5366 }
5367 
5368 /** get memory for config_view */
5369 static size_t
getmem_config_view(struct config_view * p)5370 getmem_config_view(struct config_view* p)
5371 {
5372 	size_t m = 0;
5373 	struct config_view* s;
5374 	for(s = p; s; s = s->next)
5375 		m += sizeof(*s) + getmem_str(s->name)
5376 			+ getmem_config_str2list(s->local_zones)
5377 			+ getmem_config_strlist(s->local_data)
5378 			+ getmem_config_strlist(s->local_zones_nodefault)
5379 #ifdef USE_IPSET
5380 			+ getmem_config_strlist(s->local_zones_ipset)
5381 #endif
5382 			+ getmem_config_str2list(s->respip_actions)
5383 			+ getmem_config_str2list(s->respip_data);
5384 
5385 	return m;
5386 }
5387 
5388 /** get memory used by config_file item, estimate */
5389 static size_t
config_file_getmem(struct config_file * cfg)5390 config_file_getmem(struct config_file* cfg)
5391 {
5392 	size_t m = 0;
5393 	m += sizeof(*cfg);
5394 	m += getmem_config_strlist(cfg->proxy_protocol_port);
5395 	m += getmem_str(cfg->ssl_service_key);
5396 	m += getmem_str(cfg->ssl_service_pem);
5397 	m += getmem_str(cfg->tls_cert_bundle);
5398 	m += getmem_config_strlist(cfg->tls_additional_port);
5399 	m += getmem_config_strlist(cfg->tls_session_ticket_keys.first);
5400 	m += getmem_str(cfg->tls_ciphers);
5401 	m += getmem_str(cfg->tls_ciphersuites);
5402 	m += getmem_str(cfg->tls_protocols);
5403 	m += getmem_str(cfg->http_endpoint);
5404 	m += (cfg->outgoing_avail_ports?65536*sizeof(int):0);
5405 	m += getmem_str(cfg->target_fetch_policy);
5406 	m += getmem_str(cfg->if_automatic_ports);
5407 	m += getmem_ifs(cfg->num_ifs, cfg->ifs);
5408 	m += getmem_ifs(cfg->num_out_ifs, cfg->out_ifs);
5409 	m += getmem_config_strlist(cfg->root_hints);
5410 	m += getmem_config_stub(cfg->stubs);
5411 	m += getmem_config_stub(cfg->forwards);
5412 	m += getmem_config_auth(cfg->auths);
5413 	m += getmem_config_view(cfg->views);
5414 	m += getmem_config_strlist(cfg->donotqueryaddrs);
5415 #ifdef CLIENT_SUBNET
5416 	m += getmem_config_strlist(cfg->client_subnet);
5417 	m += getmem_config_strlist(cfg->client_subnet_zone);
5418 #endif
5419 	m += getmem_config_str2list(cfg->acls);
5420 	m += getmem_config_str2list(cfg->tcp_connection_limits);
5421 	m += getmem_config_strlist(cfg->caps_whitelist);
5422 	m += getmem_config_strlist(cfg->private_address);
5423 	m += getmem_config_strlist(cfg->private_domain);
5424 	m += getmem_str(cfg->chrootdir);
5425 	m += getmem_str(cfg->username);
5426 	m += getmem_str(cfg->directory);
5427 	m += getmem_str(cfg->logfile);
5428 	m += getmem_str(cfg->pidfile);
5429 	m += getmem_str(cfg->log_identity);
5430 	m += getmem_str(cfg->identity);
5431 	m += getmem_str(cfg->version);
5432 	m += getmem_str(cfg->http_user_agent);
5433 	m += getmem_str(cfg->nsid_cfg_str);
5434 	m += (cfg->nsid?cfg->nsid_len:0);
5435 	m += getmem_str(cfg->module_conf);
5436 	m += getmem_config_strlist(cfg->trust_anchor_file_list);
5437 	m += getmem_config_strlist(cfg->trust_anchor_list);
5438 	m += getmem_config_strlist(cfg->auto_trust_anchor_file_list);
5439 	m += getmem_config_strlist(cfg->trusted_keys_file_list);
5440 	m += getmem_config_strlist(cfg->domain_insecure);
5441 	m += getmem_str(cfg->val_nsec3_key_iterations);
5442 	m += getmem_config_str2list(cfg->local_zones);
5443 	m += getmem_config_strlist(cfg->local_zones_nodefault);
5444 #ifdef USE_IPSET
5445 	m += getmem_config_strlist(cfg->local_zones_ipset);
5446 #endif
5447 	m += getmem_config_strlist(cfg->local_data);
5448 	m += getmem_config_str3list(cfg->local_zone_overrides);
5449 	m += getmem_config_strbytelist(cfg->local_zone_tags);
5450 	m += getmem_config_strbytelist(cfg->acl_tags);
5451 	m += getmem_config_str3list(cfg->acl_tag_actions);
5452 	m += getmem_config_str3list(cfg->acl_tag_datas);
5453 	m += getmem_config_str2list(cfg->acl_view);
5454 	m += getmem_config_str2list(cfg->interface_actions);
5455 	m += getmem_config_strbytelist(cfg->interface_tags);
5456 	m += getmem_config_str3list(cfg->interface_tag_actions);
5457 	m += getmem_config_str3list(cfg->interface_tag_datas);
5458 	m += getmem_config_str2list(cfg->interface_view);
5459 	m += getmem_config_strbytelist(cfg->respip_tags);
5460 	m += getmem_config_str2list(cfg->respip_actions);
5461 	m += getmem_config_str2list(cfg->respip_data);
5462 	m += getmem_ifs(cfg->num_tags, cfg->tagname);
5463 	m += getmem_config_strlist(cfg->control_ifs.first);
5464 	m += getmem_str(cfg->server_key_file);
5465 	m += getmem_str(cfg->server_cert_file);
5466 	m += getmem_str(cfg->control_key_file);
5467 	m += getmem_str(cfg->control_cert_file);
5468 	m += getmem_config_strlist(cfg->python_script);
5469 	m += getmem_config_strlist(cfg->dynlib_file);
5470 	m += getmem_str(cfg->dns64_prefix);
5471 	m += getmem_config_strlist(cfg->dns64_ignore_aaaa);
5472 	m += getmem_str(cfg->nat64_prefix);
5473 	m += getmem_str(cfg->dnstap_socket_path);
5474 	m += getmem_str(cfg->dnstap_ip);
5475 	m += getmem_str(cfg->dnstap_tls_server_name);
5476 	m += getmem_str(cfg->dnstap_tls_cert_bundle);
5477 	m += getmem_str(cfg->dnstap_tls_client_key_file);
5478 	m += getmem_str(cfg->dnstap_tls_client_cert_file);
5479 	m += getmem_str(cfg->dnstap_identity);
5480 	m += getmem_str(cfg->dnstap_version);
5481 	m += getmem_config_str2list(cfg->ratelimit_for_domain);
5482 	m += getmem_config_str2list(cfg->ratelimit_below_domain);
5483 	m += getmem_config_str2list(cfg->edns_client_strings);
5484 	m += getmem_str(cfg->dnscrypt_provider);
5485 	m += getmem_config_strlist(cfg->dnscrypt_secret_key);
5486 	m += getmem_config_strlist(cfg->dnscrypt_provider_cert);
5487 	m += getmem_config_strlist(cfg->dnscrypt_provider_cert_rotated);
5488 #ifdef USE_IPSECMOD
5489 	m += getmem_config_strlist(cfg->ipsecmod_whitelist);
5490 	m += getmem_str(cfg->ipsecmod_hook);
5491 #endif
5492 #ifdef USE_CACHEDB
5493 	m += getmem_str(cfg->cachedb_backend);
5494 	m += getmem_str(cfg->cachedb_secret);
5495 #ifdef USE_REDIS
5496 	m += getmem_str(cfg->redis_server_host);
5497 	m += getmem_str(cfg->redis_replica_server_host);
5498 	m += getmem_str(cfg->redis_server_path);
5499 	m += getmem_str(cfg->redis_replica_server_path);
5500 	m += getmem_str(cfg->redis_server_password);
5501 	m += getmem_str(cfg->redis_replica_server_password);
5502 #endif
5503 #endif
5504 #ifdef USE_IPSET
5505 	m += getmem_str(cfg->ipset_name_v4);
5506 	m += getmem_str(cfg->ipset_name_v6);
5507 #endif
5508 	return m;
5509 }
5510 
5511 /** fast reload thread, print memory used by construct of items. */
5512 static int
fr_printmem(struct fast_reload_thread * fr,struct config_file * newcfg,struct fast_reload_construct * ct)5513 fr_printmem(struct fast_reload_thread* fr,
5514 	struct config_file* newcfg, struct fast_reload_construct* ct)
5515 {
5516 	size_t mem = 0;
5517 	if(fr_poll_for_quit(fr))
5518 		return 1;
5519 	mem += getmem_str(ct->ssl_service_key);
5520 	mem += getmem_str(ct->ssl_service_pem);
5521 	mem += views_get_mem(ct->views);
5522 	mem += respip_set_get_mem(ct->respip_set);
5523 	mem += auth_zones_get_mem(ct->auth_zones);
5524 	mem += forwards_get_mem(ct->fwds);
5525 	mem += hints_get_mem(ct->hints);
5526 	mem += local_zones_get_mem(ct->local_zones);
5527 	mem += acl_list_get_mem(ct->acl);
5528 	mem += acl_list_get_mem(ct->acl_interface);
5529 	mem += tcl_list_get_mem(ct->tcl);
5530 	mem += edns_strings_get_mem(ct->edns_strings);
5531 	mem += anchors_get_mem(ct->anchors);
5532 	mem += sizeof(*ct->oldcfg);
5533 	mem += config_file_getmem(newcfg);
5534 
5535 	if(!fr_output_printf(fr, "memory use %d bytes\n", (int)mem))
5536 		return 0;
5537 	fr_send_notification(fr, fast_reload_notification_printout);
5538 
5539 	return 1;
5540 }
5541 
5542 /** fast reload thread, setup the acl_interface for the ports that
5543  * the server has. */
5544 static int
ct_acl_interface_setup_ports(struct acl_list * acl_interface,struct daemon * daemon)5545 ct_acl_interface_setup_ports(struct acl_list* acl_interface,
5546 	struct daemon* daemon)
5547 {
5548 	/* clean acl_interface */
5549 	acl_interface_init(acl_interface);
5550 	if(!setup_acl_for_ports(acl_interface, daemon->ports[0]))
5551 		return 0;
5552 	if(daemon->reuseport) {
5553 		size_t i;
5554 		for(i=1; i<daemon->num_ports; i++) {
5555 			if(!setup_acl_for_ports(acl_interface,
5556 				daemon->ports[i]))
5557 				return 0;
5558 		}
5559 	}
5560 	return 1;
5561 }
5562 
5563 /** fast reload, add new change to list of auth zones */
5564 static int
fr_add_auth_zone_change(struct fast_reload_thread * fr,struct auth_zone * old_z,struct auth_zone * new_z,int is_deleted,int is_added,int is_changed)5565 fr_add_auth_zone_change(struct fast_reload_thread* fr, struct auth_zone* old_z,
5566 	struct auth_zone* new_z, int is_deleted, int is_added, int is_changed)
5567 {
5568 	struct fast_reload_auth_change* item;
5569 	item = calloc(1, sizeof(*item));
5570 	if(!item) {
5571 		log_err("malloc failure in add auth zone change");
5572 		return 0;
5573 	}
5574 	item->old_z = old_z;
5575 	item->new_z = new_z;
5576 	item->is_deleted = is_deleted;
5577 	item->is_added = is_added;
5578 	item->is_changed = is_changed;
5579 
5580 	item->next = fr->auth_zone_change_list;
5581 	fr->auth_zone_change_list = item;
5582 	return 1;
5583 }
5584 
5585 /** See if auth master is equal */
5586 static int
xfr_auth_master_equal(struct auth_master * m1,struct auth_master * m2)5587 xfr_auth_master_equal(struct auth_master* m1, struct auth_master* m2)
5588 {
5589 	if(!m1 && !m2)
5590 		return 1;
5591 	if(!m1 || !m2)
5592 		return 0;
5593 
5594 	if((m1->host && !m2->host) || (!m1->host && m2->host))
5595 		return 0;
5596 	if(m1->host && m2->host && strcmp(m1->host, m2->host) != 0)
5597 		return 0;
5598 
5599 	if((m1->file && !m2->file) || (!m1->file && m2->file))
5600 		return 0;
5601 	if(m1->file && m2->file && strcmp(m1->file, m2->file) != 0)
5602 		return 0;
5603 
5604 	if((m1->http && !m2->http) || (!m1->http && m2->http))
5605 		return 0;
5606 	if((m1->ixfr && !m2->ixfr) || (!m1->ixfr && m2->ixfr))
5607 		return 0;
5608 	if((m1->allow_notify && !m2->allow_notify) || (!m1->allow_notify && m2->allow_notify))
5609 		return 0;
5610 	if((m1->ssl && !m2->ssl) || (!m1->ssl && m2->ssl))
5611 		return 0;
5612 	if(m1->port != m2->port)
5613 		return 0;
5614 	return 1;
5615 }
5616 
5617 /** See if list of auth masters is equal */
5618 static int
xfr_masterlist_equal(struct auth_master * list1,struct auth_master * list2)5619 xfr_masterlist_equal(struct auth_master* list1, struct auth_master* list2)
5620 {
5621 	struct auth_master* p1 = list1, *p2 = list2;
5622 	while(p1 && p2) {
5623 		if(!xfr_auth_master_equal(p1, p2))
5624 			return 0;
5625 		p1 = p1->next;
5626 		p2 = p2->next;
5627 	}
5628 	if(!p1 && !p2)
5629 		return 1;
5630 	return 0;
5631 }
5632 
5633 /** See if configuration has changed. */
5634 static int
xfr_config_equal(struct auth_xfer * xfr1,struct auth_xfer * xfr2)5635 xfr_config_equal(struct auth_xfer* xfr1, struct auth_xfer* xfr2)
5636 {
5637 	if(xfr1 == NULL && xfr2 == NULL)
5638 		return 1;
5639 	if(xfr1 == NULL && xfr2 != NULL)
5640 		return 0;
5641 	if(xfr1 != NULL && xfr2 == NULL)
5642 		return 0;
5643 	if(xfr1->max_transfer_size != xfr2->max_transfer_size)
5644 		return 0;
5645 	if(xfr1->max_transfer_time != xfr2->max_transfer_time)
5646 		return 0;
5647 	return 1;
5648 }
5649 
5650 /** See if the list of masters has changed. */
5651 static int
xfr_masters_equal(struct auth_xfer * xfr1,struct auth_xfer * xfr2)5652 xfr_masters_equal(struct auth_xfer* xfr1, struct auth_xfer* xfr2)
5653 {
5654 	if(xfr1 == NULL && xfr2 == NULL)
5655 		return 1;
5656 	if(xfr1 == NULL && xfr2 != NULL)
5657 		return 0;
5658 	if(xfr1 != NULL && xfr2 == NULL)
5659 		return 0;
5660 	if(xfr_masterlist_equal(xfr1->task_probe->masters,
5661 		xfr2->task_probe->masters) &&
5662 		xfr_masterlist_equal(xfr1->task_transfer->masters,
5663 		xfr2->task_transfer->masters))
5664 		return 1;
5665 	return 0;
5666 }
5667 
5668 /** Check what has changed in auth zones, like added and deleted zones */
5669 static int
auth_zones_check_changes(struct fast_reload_thread * fr,struct fast_reload_construct * ct)5670 auth_zones_check_changes(struct fast_reload_thread* fr,
5671 	struct fast_reload_construct* ct)
5672 {
5673 	/* Check every zone in turn. */
5674 	struct auth_zone* new_z, *old_z;
5675 	struct module_env* env = &fr->worker->env;
5676 
5677 	fr->old_auth_zones = ct->auth_zones;
5678 	/* Nobody is using the new ct version yet.
5679 	 * Also the ct lock is picked up before the env lock for auth_zones. */
5680 	lock_rw_rdlock(&ct->auth_zones->lock);
5681 
5682 	/* Find deleted zones by looping over the current list and looking
5683 	 * up in the new tree. */
5684 	lock_rw_rdlock(&env->auth_zones->lock);
5685 	RBTREE_FOR(old_z, struct auth_zone*, &env->auth_zones->ztree) {
5686 		new_z = auth_zone_find(ct->auth_zones, old_z->name,
5687 			old_z->namelen, old_z->dclass);
5688 		if(!new_z) {
5689 			/* The zone has been removed. */
5690 			if(!fr_add_auth_zone_change(fr, old_z, NULL, 1, 0,
5691 				0)) {
5692 				lock_rw_unlock(&env->auth_zones->lock);
5693 				lock_rw_unlock(&ct->auth_zones->lock);
5694 				return 0;
5695 			}
5696 		}
5697 	}
5698 	lock_rw_unlock(&env->auth_zones->lock);
5699 
5700 	/* Find added zones by looping over new list and lookup in current. */
5701 	RBTREE_FOR(new_z, struct auth_zone*, &ct->auth_zones->ztree) {
5702 		lock_rw_rdlock(&env->auth_zones->lock);
5703 		old_z = auth_zone_find(env->auth_zones, new_z->name,
5704 			new_z->namelen, new_z->dclass);
5705 		if(!old_z) {
5706 			/* The zone has been added. */
5707 			lock_rw_unlock(&env->auth_zones->lock);
5708 			if(!fr_add_auth_zone_change(fr, NULL, new_z, 0, 1,
5709 				0)) {
5710 				lock_rw_unlock(&ct->auth_zones->lock);
5711 				return 0;
5712 			}
5713 		} else {
5714 			uint32_t old_serial = 0, new_serial = 0;
5715 			int have_old = 0, have_new = 0;
5716 			struct auth_xfer* old_xfr, *new_xfr;
5717 			lock_rw_rdlock(&new_z->lock);
5718 			lock_rw_rdlock(&old_z->lock);
5719 			new_xfr = auth_xfer_find(ct->auth_zones, new_z->name,
5720 				new_z->namelen, new_z->dclass);
5721 			old_xfr = auth_xfer_find(env->auth_zones, old_z->name,
5722 				old_z->namelen, old_z->dclass);
5723 			if(new_xfr) {
5724 				lock_basic_lock(&new_xfr->lock);
5725 			}
5726 			if(old_xfr) {
5727 				lock_basic_lock(&old_xfr->lock);
5728 			}
5729 			lock_rw_unlock(&env->auth_zones->lock);
5730 
5731 			/* Change in the auth zone can be detected. */
5732 			/* A change in serial number means that auth_xfer
5733 			 * has to be updated. */
5734 			have_old = (auth_zone_get_serial(old_z,
5735 				&old_serial)!=0);
5736 			have_new = (auth_zone_get_serial(new_z,
5737 				&new_serial)!=0);
5738 			/* A change in primaries, also means it is different
5739 			 * and the change makes it fire new transfers, from
5740 			 * the new primaries. */
5741 			/* Treat as changed when the old zone has an
5742 			 * outstanding ZONEMD DS/DNSKEY mesh callback.
5743 			 * This will make the worker pickup change code
5744 			 * remove the mesh callback, before the old zone is
5745 			 * deleted. Also it makes a new zonemd lookup.
5746 			 * The new lookup is needed, because the new zone
5747 			 * entry needs to have a valid zonemd result,
5748 			 * and if that is bad, needs to be invalidated.
5749 			 * Also if there is a race event where the
5750 			 * outstanding callback makes the zone invalid,
5751 			 * before fast-reload completes, the change makes
5752 			 * the new zone entry have a new zonemd lookup,
5753 			 * to then invalidate that new zone.
5754 			 * There is also a brief operational window at
5755 			 * program start when a zonemd has to be looked
5756 			 * up on-line, where the zone is operational.
5757 			 * And this copies that for such a race event.
5758 			 */
5759 			if(have_old != have_new || old_serial != new_serial
5760 				|| !xfr_masters_equal(old_xfr, new_xfr)
5761 				|| !xfr_config_equal(old_xfr, new_xfr)
5762 				|| old_z->zonemd_callback_env != NULL) {
5763 				/* The zone has been changed. */
5764 				if(!fr_add_auth_zone_change(fr, old_z, new_z,
5765 					0, 0, 1)) {
5766 					lock_rw_unlock(&old_z->lock);
5767 					lock_rw_unlock(&new_z->lock);
5768 					lock_rw_unlock(&ct->auth_zones->lock);
5769 					if(new_xfr) {
5770 						lock_basic_unlock(&new_xfr->lock);
5771 					}
5772 					if(old_xfr) {
5773 						lock_basic_unlock(&old_xfr->lock);
5774 					}
5775 					return 0;
5776 				}
5777 			}
5778 
5779 			if(new_xfr) {
5780 				lock_basic_unlock(&new_xfr->lock);
5781 			}
5782 			if(old_xfr) {
5783 				lock_basic_unlock(&old_xfr->lock);
5784 			}
5785 			lock_rw_unlock(&old_z->lock);
5786 			lock_rw_unlock(&new_z->lock);
5787 		}
5788 	}
5789 
5790 	lock_rw_unlock(&ct->auth_zones->lock);
5791 	return 1;
5792 }
5793 
5794 /** Check if the sslctxs have changed. */
5795 static int
fr_check_sslctx_change(struct fast_reload_thread * fr,struct config_file * newcfg)5796 fr_check_sslctx_change(struct fast_reload_thread* fr,
5797 	struct config_file* newcfg)
5798 {
5799 #ifdef HAVE_SSL
5800 	struct daemon* daemon = fr->worker->daemon;
5801 	if(newcfg->ssl_service_key && newcfg->ssl_service_key[0]) {
5802 		if(!daemon->ssl_service_key ||
5803 			ssl_cert_changed(daemon, newcfg))
5804 			return 1;
5805 	} else {
5806 		if(daemon->ssl_service_key)
5807 			return 1; /* it is removed */
5808 	}
5809 	if((daemon->cfg->tls_cert_bundle && !newcfg->tls_cert_bundle) ||
5810 	   (!daemon->cfg->tls_cert_bundle && newcfg->tls_cert_bundle) ||
5811 	   (daemon->cfg->tls_cert_bundle && newcfg->tls_cert_bundle &&
5812 	    strcmp(daemon->cfg->tls_cert_bundle, newcfg->tls_cert_bundle)!=0))
5813 		return 1; /* The tls-cert-bundle has changed and return
5814 			true here makes it reload the connect_dot_sslctx. */
5815 #else
5816 	(void)fr; (void)newcfg;
5817 #endif /* HAVE_SSL */
5818 	return 0;
5819 }
5820 
5821 /** Create the SSL CTXs when they have changed. */
5822 static int
ct_create_sslctxs(struct fast_reload_construct * ct,struct config_file * newcfg,struct daemon * daemon)5823 ct_create_sslctxs(struct fast_reload_construct* ct,
5824 	struct config_file* newcfg, struct daemon* daemon)
5825 {
5826 #ifdef HAVE_SSL
5827 	char* chroot = daemon->chroot;
5828 	char* key = newcfg->ssl_service_key;
5829 	char* pem = newcfg->ssl_service_pem;
5830 
5831 	if(!(newcfg->ssl_service_key && newcfg->ssl_service_key[0])) {
5832 		/* Leave listen ctxs and file str at NULL */
5833 		ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
5834 			daemon, newcfg);
5835 		if(!ct->connect_dot_sslctx)
5836 			return 0;
5837 		return 1;
5838 	}
5839 
5840 	if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
5841 		key += strlen(chroot);
5842 	if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
5843 		pem += strlen(chroot);
5844 
5845 	ct->listen_dot_sslctx = daemon_setup_listen_dot_sslctx(daemon, newcfg);
5846 	if(!ct->listen_dot_sslctx)
5847 		return 0;
5848 #ifdef HAVE_NGHTTP2_NGHTTP2_H
5849 	if(cfg_has_https(newcfg)) {
5850 		ct->listen_doh_sslctx = daemon_setup_listen_doh_sslctx(
5851 			daemon, newcfg);
5852 		if(!ct->listen_doh_sslctx)
5853 			return 0;
5854 	}
5855 #endif
5856 #ifdef HAVE_NGTCP2
5857 	if(cfg_has_quic(newcfg)) {
5858 		ct->listen_quic_sslctx = daemon_setup_listen_quic_sslctx(
5859 			daemon, newcfg);
5860 		if(!ct->listen_quic_sslctx)
5861 			return 0;
5862 	}
5863 #endif /* HAVE_NGTCP2 */
5864 	ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(daemon,
5865 		newcfg);
5866 	if(!ct->connect_dot_sslctx)
5867 		return 0;
5868 
5869 	/* Store mtime and names */
5870 	ct->ssl_service_key = strdup(newcfg->ssl_service_key);
5871 	if(!ct->ssl_service_key) {
5872 		log_err("ct_create_sslctxs: out of memory");
5873 		return 0;
5874 	}
5875 	ct->ssl_service_pem = strdup(newcfg->ssl_service_pem);
5876 	if(!ct->ssl_service_pem) {
5877 		log_err("ct_create_sslctxs: out of memory");
5878 		return 0;
5879 	}
5880 	if(!file_get_mtime(key, &ct->mtime_ssl_service_key,
5881 		&ct->mtime_ns_ssl_service_key, NULL))
5882 		log_err("Could not stat(%s): %s",
5883 			key, strerror(errno));
5884 	if(!file_get_mtime(pem, &ct->mtime_ssl_service_pem,
5885 		&ct->mtime_ns_ssl_service_pem, NULL))
5886 		log_err("Could not stat(%s): %s",
5887 			pem, strerror(errno));
5888 #else
5889 	(void)ct; (void)newcfg; (void)daemon;
5890 #endif /* HAVE_SSL */
5891 	return 1;
5892 }
5893 
5894 /** fast reload thread, construct from config the new items */
5895 static int
fr_construct_from_config(struct fast_reload_thread * fr,struct config_file * newcfg,struct fast_reload_construct * ct)5896 fr_construct_from_config(struct fast_reload_thread* fr,
5897 	struct config_file* newcfg, struct fast_reload_construct* ct)
5898 {
5899 	int have_view_respip_cfg = 0;
5900 
5901 	fr->sslctxs_changed = fr_check_sslctx_change(fr, newcfg);
5902 	if(fr->sslctxs_changed) {
5903 		if(!ct_create_sslctxs(ct, newcfg, fr->worker->daemon)) {
5904 			fr_construct_clear(ct);
5905 			return 0;
5906 		}
5907 	}
5908 	if(!(ct->views = views_create())) {
5909 		fr_construct_clear(ct);
5910 		return 0;
5911 	}
5912 	if(!views_apply_cfg(ct->views, newcfg)) {
5913 		fr_construct_clear(ct);
5914 		return 0;
5915 	}
5916 	if(fr_poll_for_quit(fr))
5917 		return 1;
5918 
5919 	if(!(ct->acl = acl_list_create())) {
5920 		fr_construct_clear(ct);
5921 		return 0;
5922 	}
5923 	if(!acl_list_apply_cfg(ct->acl, newcfg, ct->views)) {
5924 		fr_construct_clear(ct);
5925 		return 0;
5926 	}
5927 	if(fr_poll_for_quit(fr))
5928 		return 1;
5929 
5930 	if(!(ct->acl_interface = acl_list_create())) {
5931 		fr_construct_clear(ct);
5932 		return 0;
5933 	}
5934 	if(!ct_acl_interface_setup_ports(ct->acl_interface,
5935 		fr->worker->daemon)) {
5936 		fr_construct_clear(ct);
5937 		return 0;
5938 	}
5939 	if(!acl_interface_apply_cfg(ct->acl_interface, newcfg, ct->views)) {
5940 		fr_construct_clear(ct);
5941 		return 0;
5942 	}
5943 	if(fr_poll_for_quit(fr))
5944 		return 1;
5945 
5946 	if(!(ct->tcl = tcl_list_create())) {
5947 		fr_construct_clear(ct);
5948 		return 0;
5949 	}
5950 	if(!tcl_list_apply_cfg(ct->tcl, newcfg)) {
5951 		fr_construct_clear(ct);
5952 		return 0;
5953 	}
5954 	if(fr->worker->daemon->tcl->tree.count != 0)
5955 		fr->worker->daemon->fast_reload_tcl_has_changes = 1;
5956 	else	fr->worker->daemon->fast_reload_tcl_has_changes = 0;
5957 	if(fr_poll_for_quit(fr))
5958 		return 1;
5959 
5960 	if(!(ct->auth_zones = auth_zones_create())) {
5961 		fr_construct_clear(ct);
5962 		return 0;
5963 	}
5964 	if(!auth_zones_apply_cfg(ct->auth_zones, newcfg, 1, &ct->use_rpz,
5965 		fr->worker->daemon->env, &fr->worker->daemon->mods)) {
5966 		fr_construct_clear(ct);
5967 		return 0;
5968 	}
5969 	if(!auth_zones_check_changes(fr, ct)) {
5970 		fr_construct_clear(ct);
5971 		return 0;
5972 	}
5973 	if(fr_poll_for_quit(fr))
5974 		return 1;
5975 
5976 	if(!(ct->fwds = forwards_create())) {
5977 		fr_construct_clear(ct);
5978 		return 0;
5979 	}
5980 	if(!forwards_apply_cfg(ct->fwds, newcfg)) {
5981 		fr_construct_clear(ct);
5982 		return 0;
5983 	}
5984 	if(fr_poll_for_quit(fr))
5985 		return 1;
5986 
5987 	if(!(ct->hints = hints_create())) {
5988 		fr_construct_clear(ct);
5989 		return 0;
5990 	}
5991 	if(!hints_apply_cfg(ct->hints, newcfg)) {
5992 		fr_construct_clear(ct);
5993 		return 0;
5994 	}
5995 	if(fr_poll_for_quit(fr))
5996 		return 1;
5997 
5998 	if(!(ct->local_zones = local_zones_create())) {
5999 		fr_construct_clear(ct);
6000 		return 0;
6001 	}
6002 	if(!local_zones_apply_cfg(ct->local_zones, newcfg)) {
6003 		fr_construct_clear(ct);
6004 		return 0;
6005 	}
6006 	if(fr_poll_for_quit(fr))
6007 		return 1;
6008 
6009 	if(!(ct->respip_set = respip_set_create())) {
6010 		fr_construct_clear(ct);
6011 		return 0;
6012 	}
6013 	if(!respip_global_apply_cfg(ct->respip_set, newcfg)) {
6014 		fr_construct_clear(ct);
6015 		return 0;
6016 	}
6017 	if(fr_poll_for_quit(fr))
6018 		return 1;
6019 	if(!respip_views_apply_cfg(ct->views, newcfg, &have_view_respip_cfg)) {
6020 		fr_construct_clear(ct);
6021 		return 0;
6022 	}
6023 	ct->use_response_ip = !respip_set_is_empty(ct->respip_set) ||
6024 		have_view_respip_cfg;
6025 	if(fr_poll_for_quit(fr))
6026 		return 1;
6027 
6028 	if(!(ct->edns_strings = edns_strings_create())) {
6029 		fr_construct_clear(ct);
6030 		return 0;
6031 	}
6032 	if(!edns_strings_apply_cfg(ct->edns_strings, newcfg)) {
6033 		fr_construct_clear(ct);
6034 		return 0;
6035 	}
6036 	if(fr_poll_for_quit(fr))
6037 		return 1;
6038 
6039 	if(fr->worker->env.anchors) {
6040 		/* There are trust anchors already, so create it for reload. */
6041 		if(!(ct->anchors = anchors_create())) {
6042 			fr_construct_clear(ct);
6043 			return 0;
6044 		}
6045 		if(!anchors_apply_cfg(ct->anchors, newcfg)) {
6046 			fr_construct_clear(ct);
6047 			return 0;
6048 		}
6049 		if(fr_poll_for_quit(fr))
6050 			return 1;
6051 	}
6052 
6053 	if(!val_env_parse_key_iter(newcfg->val_nsec3_key_iterations,
6054 		&ct->nsec3_keysize, &ct->nsec3_maxiter,
6055 		&ct->nsec3_keyiter_count)) {
6056 		fr_construct_clear(ct);
6057 		return 0;
6058 	}
6059 	if(fr_poll_for_quit(fr))
6060 		return 1;
6061 
6062 	if(!read_fetch_policy(&ct->target_fetch_policy,
6063 		&ct->max_dependency_depth, newcfg->target_fetch_policy)) {
6064 		fr_construct_clear(ct);
6065 		return 0;
6066 	}
6067 	if(!(ct->donotq = donotq_create())) {
6068 		fr_construct_clear(ct);
6069 		return 0;
6070 	}
6071 	if(!donotq_apply_cfg(ct->donotq, newcfg)) {
6072 		fr_construct_clear(ct);
6073 		return 0;
6074 	}
6075 	if(!(ct->priv = priv_create())) {
6076 		fr_construct_clear(ct);
6077 		return 0;
6078 	}
6079 	if(!priv_apply_cfg(ct->priv, newcfg)) {
6080 		fr_construct_clear(ct);
6081 		return 0;
6082 	}
6083 	if(newcfg->caps_whitelist) {
6084 		if(!(ct->caps_white = caps_white_create())) {
6085 			fr_construct_clear(ct);
6086 			return 0;
6087 		}
6088 		if(!caps_white_apply_cfg(ct->caps_white, newcfg)) {
6089 			fr_construct_clear(ct);
6090 			return 0;
6091 		}
6092 	}
6093 	if(!nat64_apply_cfg(&ct->nat64, newcfg)) {
6094 		fr_construct_clear(ct);
6095 		return 0;
6096 	}
6097 	if(fr_poll_for_quit(fr))
6098 		return 1;
6099 
6100 	if(!setup_wait_limits(&ct->wait_limits_netblock,
6101 		&ct->wait_limits_cookie_netblock, newcfg)) {
6102 		fr_construct_clear(ct);
6103 		return 0;
6104 	}
6105 	if(!setup_domain_limits(&ct->domain_limits, newcfg)) {
6106 		fr_construct_clear(ct);
6107 		return 0;
6108 	}
6109 	if(fr_poll_for_quit(fr))
6110 		return 1;
6111 
6112 	if(!(ct->oldcfg = (struct config_file*)calloc(1,
6113 		sizeof(*ct->oldcfg)))) {
6114 		fr_construct_clear(ct);
6115 		log_err("out of memory");
6116 		return 0;
6117 	}
6118 	if(fr->fr_verb >= 2) {
6119 		if(!fr_printmem(fr, newcfg, ct))
6120 			return 0;
6121 	}
6122 	return 1;
6123 }
6124 
6125 /** fast reload thread, finish timers */
6126 static int
fr_finish_time(struct fast_reload_thread * fr,struct timeval * time_start,struct timeval * time_read,struct timeval * time_construct,struct timeval * time_reload,struct timeval * time_end)6127 fr_finish_time(struct fast_reload_thread* fr, struct timeval* time_start,
6128 	struct timeval* time_read, struct timeval* time_construct,
6129 	struct timeval* time_reload, struct timeval* time_end)
6130 {
6131 	struct timeval total, readtime, constructtime, reloadtime, deletetime;
6132 	if(gettimeofday(time_end, NULL) < 0)
6133 		log_err("gettimeofday: %s", strerror(errno));
6134 
6135 	timeval_subtract(&total, time_end, time_start);
6136 	timeval_subtract(&readtime, time_read, time_start);
6137 	timeval_subtract(&constructtime, time_construct, time_read);
6138 	timeval_subtract(&reloadtime, time_reload, time_construct);
6139 	timeval_subtract(&deletetime, time_end, time_reload);
6140 	if(!fr_output_printf(fr, "read disk  %3d.%6.6ds\n",
6141 		(int)readtime.tv_sec, (int)readtime.tv_usec))
6142 		return 0;
6143 	if(!fr_output_printf(fr, "construct  %3d.%6.6ds\n",
6144 		(int)constructtime.tv_sec, (int)constructtime.tv_usec))
6145 		return 0;
6146 	if(!fr_output_printf(fr, "reload     %3d.%6.6ds\n",
6147 		(int)reloadtime.tv_sec, (int)reloadtime.tv_usec))
6148 		return 0;
6149 	if(!fr_output_printf(fr, "deletes    %3d.%6.6ds\n",
6150 		(int)deletetime.tv_sec, (int)deletetime.tv_usec))
6151 		return 0;
6152 	if(!fr_output_printf(fr, "total time %3d.%6.6ds\n", (int)total.tv_sec,
6153 		(int)total.tv_usec))
6154 		return 0;
6155 	fr_send_notification(fr, fast_reload_notification_printout);
6156 	return 1;
6157 }
6158 
6159 /** Swap auth zone information */
6160 static void
auth_zones_swap(struct auth_zones * az,struct auth_zones * data)6161 auth_zones_swap(struct auth_zones* az, struct auth_zones* data)
6162 {
6163 	rbtree_type oldztree = az->ztree;
6164 	int old_have_downstream = az->have_downstream;
6165 	struct auth_zone* old_rpz_first = az->rpz_first;
6166 
6167 	az->ztree = data->ztree;
6168 	data->ztree = oldztree;
6169 
6170 	az->have_downstream = data->have_downstream;
6171 	data->have_downstream = old_have_downstream;
6172 
6173 	/* Leave num_query_up and num_query_down, the statistics can
6174 	 * remain counted. */
6175 
6176 	az->rpz_first = data->rpz_first;
6177 	data->rpz_first = old_rpz_first;
6178 
6179 	/* The xtree is not swapped. This contains the auth_xfer elements
6180 	 * that contain tasks in progress, like zone transfers.
6181 	 * The unchanged zones can keep their tasks in the tree, and thus
6182 	 * the xfer elements can continue to be their callbacks. */
6183 }
6184 
6185 /** Swap two void* */
6186 static void
void_ptr_swap(void ** a,void ** b)6187 void_ptr_swap(void** a, void **b)
6188 {
6189 	void* tmp = *a;
6190 	*a = *b;
6191 	*b = tmp;
6192 }
6193 
6194 /** Swap two char* */
6195 static void
char_ptr_swap(char ** a,char ** b)6196 char_ptr_swap(char** a, char **b)
6197 {
6198 	char* tmp = *a;
6199 	*a = *b;
6200 	*b = tmp;
6201 }
6202 
6203 /** Swap and set ssl ctx information */
6204 static void
sslctxs_swap(struct daemon * daemon,struct fast_reload_construct * ct)6205 sslctxs_swap(struct daemon* daemon, struct fast_reload_construct* ct)
6206 {
6207 	void_ptr_swap(&daemon->listen_dot_sslctx, &ct->listen_dot_sslctx);
6208 	void_ptr_swap(&daemon->connect_dot_sslctx, &ct->connect_dot_sslctx);
6209 #ifdef HAVE_NGHTTP2_NGHTTP2_H
6210 	void_ptr_swap(&daemon->listen_doh_sslctx, &ct->listen_doh_sslctx);
6211 #endif
6212 #ifdef HAVE_NGTCP2
6213 	void_ptr_swap(&daemon->listen_quic_sslctx, &ct->listen_quic_sslctx);
6214 #endif /* HAVE_NGTCP2 */
6215 	char_ptr_swap(&daemon->ssl_service_key, &ct->ssl_service_key);
6216 	char_ptr_swap(&daemon->ssl_service_pem, &ct->ssl_service_pem);
6217 	daemon->mtime_ssl_service_key = ct->mtime_ssl_service_key;
6218 	daemon->mtime_ns_ssl_service_key = ct->mtime_ns_ssl_service_key;
6219 	daemon->mtime_ssl_service_pem = ct->mtime_ssl_service_pem;
6220 	daemon->mtime_ns_ssl_service_pem = ct->mtime_ns_ssl_service_pem;
6221 }
6222 
6223 #if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
6224 /** Fast reload thread, if atomics are available, copy the config items
6225  * one by one with atomic store operations. */
6226 static void
fr_atomic_copy_cfg(struct config_file * oldcfg,struct config_file * cfg,struct config_file * newcfg)6227 fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
6228 	struct config_file* newcfg)
6229 {
6230 #define COPY_VAR_int(var) oldcfg->var = cfg->var; atomic_store((_Atomic int*)&cfg->var, newcfg->var); newcfg->var = 0;
6231 #define COPY_VAR_ptr(var) oldcfg->var = cfg->var; atomic_store((void* _Atomic*)&cfg->var, newcfg->var); newcfg->var = 0;
6232 #define COPY_VAR_unsigned_int(var) oldcfg->var = cfg->var; atomic_store((_Atomic unsigned*)&cfg->var, newcfg->var); newcfg->var = 0;
6233 #define COPY_VAR_size_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic size_t*)&cfg->var, newcfg->var); newcfg->var = 0;
6234 #define COPY_VAR_uint8_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic uint8_t*)&cfg->var, newcfg->var); newcfg->var = 0;
6235 #define COPY_VAR_uint16_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic uint16_t*)&cfg->var, newcfg->var); newcfg->var = 0;
6236 #define COPY_VAR_uint32_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic uint32_t*)&cfg->var, newcfg->var); newcfg->var = 0;
6237 #define COPY_VAR_int32_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic int32_t*)&cfg->var, newcfg->var); newcfg->var = 0;
6238 	/* If config file items are missing from this list, they are
6239 	 * not updated by fast-reload +p. */
6240 	/* For missing items, the oldcfg item is not updated, still NULL,
6241 	 * and the cfg stays the same. The newcfg item is untouched.
6242 	 * The newcfg item is then deleted later. */
6243 	/* Items that need synchronisation are omitted from the list.
6244 	 * Use fast-reload without +p to update them together. */
6245 	COPY_VAR_int(verbosity);
6246 	COPY_VAR_int(stat_interval);
6247 	COPY_VAR_int(stat_cumulative);
6248 	COPY_VAR_int(stat_extended);
6249 	COPY_VAR_int(stat_inhibit_zero);
6250 	COPY_VAR_int(num_threads);
6251 	COPY_VAR_int(port);
6252 	COPY_VAR_int(do_ip4);
6253 	COPY_VAR_int(do_ip6);
6254 	COPY_VAR_int(do_nat64);
6255 	COPY_VAR_int(prefer_ip4);
6256 	COPY_VAR_int(prefer_ip6);
6257 	COPY_VAR_int(do_udp);
6258 	COPY_VAR_int(do_tcp);
6259 	COPY_VAR_size_t(max_reuse_tcp_queries);
6260 	COPY_VAR_int(tcp_reuse_timeout);
6261 	COPY_VAR_int(tcp_auth_query_timeout);
6262 	COPY_VAR_int(tcp_upstream);
6263 	COPY_VAR_int(udp_upstream_without_downstream);
6264 	COPY_VAR_int(tcp_mss);
6265 	COPY_VAR_int(outgoing_tcp_mss);
6266 	COPY_VAR_int(tcp_idle_timeout);
6267 	COPY_VAR_int(do_tcp_keepalive);
6268 	COPY_VAR_int(tcp_keepalive_timeout);
6269 	COPY_VAR_int(sock_queue_timeout);
6270 	COPY_VAR_ptr(proxy_protocol_port);
6271 	COPY_VAR_ptr(ssl_service_key);
6272 	COPY_VAR_ptr(ssl_service_pem);
6273 	COPY_VAR_int(ssl_port);
6274 	COPY_VAR_int(ssl_upstream);
6275 	COPY_VAR_ptr(tls_cert_bundle);
6276 	COPY_VAR_int(tls_win_cert);
6277 	COPY_VAR_ptr(tls_additional_port);
6278 	/* The first is used to walk through the list but last is
6279 	 * only used during config read. */
6280 	COPY_VAR_ptr(tls_session_ticket_keys.first);
6281 	COPY_VAR_ptr(tls_session_ticket_keys.last);
6282 	COPY_VAR_ptr(tls_ciphers);
6283 	COPY_VAR_ptr(tls_ciphersuites);
6284 	COPY_VAR_ptr(tls_protocols);
6285 	COPY_VAR_int(tls_use_sni);
6286 	COPY_VAR_int(https_port);
6287 	COPY_VAR_ptr(http_endpoint);
6288 	COPY_VAR_uint32_t(http_max_streams);
6289 	COPY_VAR_size_t(http_query_buffer_size);
6290 	COPY_VAR_size_t(http_response_buffer_size);
6291 	COPY_VAR_int(http_nodelay);
6292 	COPY_VAR_int(http_notls_downstream);
6293 	COPY_VAR_int(outgoing_num_ports);
6294 	COPY_VAR_size_t(outgoing_num_tcp);
6295 	COPY_VAR_size_t(incoming_num_tcp);
6296 	COPY_VAR_ptr(outgoing_avail_ports);
6297 	COPY_VAR_size_t(edns_buffer_size);
6298 	COPY_VAR_size_t(stream_wait_size);
6299 	COPY_VAR_size_t(msg_buffer_size);
6300 	COPY_VAR_size_t(msg_cache_size);
6301 	COPY_VAR_size_t(msg_cache_slabs);
6302 	COPY_VAR_size_t(num_queries_per_thread);
6303 	COPY_VAR_size_t(jostle_time);
6304 	COPY_VAR_size_t(rrset_cache_size);
6305 	COPY_VAR_size_t(rrset_cache_slabs);
6306 	COPY_VAR_int(host_ttl);
6307 	COPY_VAR_size_t(infra_cache_slabs);
6308 	COPY_VAR_size_t(infra_cache_numhosts);
6309 	COPY_VAR_int(infra_cache_min_rtt);
6310 	COPY_VAR_int(infra_cache_max_rtt);
6311 	COPY_VAR_int(infra_keep_probing);
6312 	COPY_VAR_int(delay_close);
6313 	COPY_VAR_int(udp_connect);
6314 	COPY_VAR_ptr(target_fetch_policy);
6315 	COPY_VAR_int(fast_server_permil);
6316 	COPY_VAR_size_t(fast_server_num);
6317 	COPY_VAR_int(if_automatic);
6318 	COPY_VAR_ptr(if_automatic_ports);
6319 	COPY_VAR_size_t(so_rcvbuf);
6320 	COPY_VAR_size_t(so_sndbuf);
6321 	COPY_VAR_int(so_reuseport);
6322 	COPY_VAR_int(ip_transparent);
6323 	COPY_VAR_int(ip_freebind);
6324 	COPY_VAR_int(ip_dscp);
6325 	/* Not copied because the length and items could then not match.
6326 	   num_ifs, ifs, num_out_ifs, out_ifs
6327 	*/
6328 	COPY_VAR_ptr(root_hints);
6329 	COPY_VAR_ptr(stubs);
6330 	COPY_VAR_ptr(forwards);
6331 	COPY_VAR_ptr(auths);
6332 	COPY_VAR_ptr(views);
6333 	COPY_VAR_ptr(donotqueryaddrs);
6334 #ifdef CLIENT_SUBNET
6335 	COPY_VAR_ptr(client_subnet);
6336 	COPY_VAR_ptr(client_subnet_zone);
6337 	COPY_VAR_uint16_t(client_subnet_opcode);
6338 	COPY_VAR_int(client_subnet_always_forward);
6339 	COPY_VAR_uint8_t(max_client_subnet_ipv4);
6340 	COPY_VAR_uint8_t(max_client_subnet_ipv6);
6341 	COPY_VAR_uint8_t(min_client_subnet_ipv4);
6342 	COPY_VAR_uint8_t(min_client_subnet_ipv6);
6343 	COPY_VAR_uint32_t(max_ecs_tree_size_ipv4);
6344 	COPY_VAR_uint32_t(max_ecs_tree_size_ipv6);
6345 #endif
6346 	COPY_VAR_ptr(acls);
6347 	COPY_VAR_int(donotquery_localhost);
6348 	COPY_VAR_ptr(tcp_connection_limits);
6349 	COPY_VAR_int(harden_short_bufsize);
6350 	COPY_VAR_int(harden_large_queries);
6351 	COPY_VAR_int(harden_glue);
6352 	COPY_VAR_int(harden_dnssec_stripped);
6353 	COPY_VAR_int(harden_below_nxdomain);
6354 	COPY_VAR_int(harden_referral_path);
6355 	COPY_VAR_int(harden_algo_downgrade);
6356 	COPY_VAR_int(harden_unknown_additional);
6357 	COPY_VAR_int(use_caps_bits_for_id);
6358 	COPY_VAR_ptr(caps_whitelist);
6359 	COPY_VAR_ptr(private_address);
6360 	COPY_VAR_ptr(private_domain);
6361 	COPY_VAR_size_t(unwanted_threshold);
6362 	COPY_VAR_int(max_ttl);
6363 	COPY_VAR_int(min_ttl);
6364 	COPY_VAR_int(max_negative_ttl);
6365 	COPY_VAR_int(min_negative_ttl);
6366 	COPY_VAR_int(prefetch);
6367 	COPY_VAR_int(prefetch_key);
6368 	COPY_VAR_int(deny_any);
6369 	COPY_VAR_ptr(chrootdir);
6370 	COPY_VAR_ptr(username);
6371 	COPY_VAR_ptr(directory);
6372 	COPY_VAR_ptr(logfile);
6373 	COPY_VAR_ptr(pidfile);
6374 	COPY_VAR_int(use_syslog);
6375 	COPY_VAR_int(log_time_ascii);
6376 	COPY_VAR_int(log_queries);
6377 	COPY_VAR_int(log_replies);
6378 	COPY_VAR_int(log_tag_queryreply);
6379 	COPY_VAR_int(log_local_actions);
6380 	COPY_VAR_int(log_servfail);
6381 	COPY_VAR_ptr(log_identity);
6382 	COPY_VAR_int(log_destaddr);
6383 	COPY_VAR_int(log_thread_id);
6384 	COPY_VAR_int(hide_identity);
6385 	COPY_VAR_int(hide_version);
6386 	COPY_VAR_int(hide_trustanchor);
6387 	COPY_VAR_int(hide_http_user_agent);
6388 	COPY_VAR_ptr(identity);
6389 	COPY_VAR_ptr(version);
6390 	COPY_VAR_ptr(http_user_agent);
6391 	COPY_VAR_ptr(nsid_cfg_str);
6392 	/* Not copied because the length and items could then not match.
6393 	nsid;
6394 	nsid_len;
6395 	*/
6396 	COPY_VAR_ptr(module_conf);
6397 	COPY_VAR_ptr(trust_anchor_file_list);
6398 	COPY_VAR_ptr(trust_anchor_list);
6399 	COPY_VAR_ptr(auto_trust_anchor_file_list);
6400 	COPY_VAR_ptr(trusted_keys_file_list);
6401 	COPY_VAR_ptr(domain_insecure);
6402 	COPY_VAR_int(trust_anchor_signaling);
6403 	COPY_VAR_int(root_key_sentinel);
6404 	COPY_VAR_int32_t(val_date_override);
6405 	COPY_VAR_int32_t(val_sig_skew_min);
6406 	COPY_VAR_int32_t(val_sig_skew_max);
6407 	COPY_VAR_int32_t(val_max_restart);
6408 	COPY_VAR_int(bogus_ttl);
6409 	COPY_VAR_int(val_clean_additional);
6410 	COPY_VAR_int(val_log_level);
6411 	COPY_VAR_int(val_log_squelch);
6412 	COPY_VAR_int(val_permissive_mode);
6413 	COPY_VAR_int(aggressive_nsec);
6414 	COPY_VAR_int(ignore_cd);
6415 	COPY_VAR_int(disable_edns_do);
6416 	COPY_VAR_int(serve_expired);
6417 	COPY_VAR_int(serve_expired_ttl);
6418 	COPY_VAR_int(serve_expired_ttl_reset);
6419 	COPY_VAR_int(serve_expired_reply_ttl);
6420 	COPY_VAR_int(serve_expired_client_timeout);
6421 	COPY_VAR_int(ede_serve_expired);
6422 	COPY_VAR_int(dns_error_reporting);
6423 	COPY_VAR_int(serve_original_ttl);
6424 	COPY_VAR_ptr(val_nsec3_key_iterations);
6425 	COPY_VAR_int(zonemd_permissive_mode);
6426 	COPY_VAR_unsigned_int(add_holddown);
6427 	COPY_VAR_unsigned_int(del_holddown);
6428 	COPY_VAR_unsigned_int(keep_missing);
6429 	COPY_VAR_int(permit_small_holddown);
6430 	COPY_VAR_size_t(key_cache_size);
6431 	COPY_VAR_size_t(key_cache_slabs);
6432 	COPY_VAR_size_t(neg_cache_size);
6433 	COPY_VAR_ptr(local_zones);
6434 	COPY_VAR_ptr(local_zones_nodefault);
6435 #ifdef USE_IPSET
6436 	COPY_VAR_ptr(local_zones_ipset);
6437 #endif
6438 	COPY_VAR_int(local_zones_disable_default);
6439 	COPY_VAR_ptr(local_data);
6440 	COPY_VAR_ptr(local_zone_overrides);
6441 	COPY_VAR_int(unblock_lan_zones);
6442 	COPY_VAR_int(insecure_lan_zones);
6443 	/* These reference tags
6444 	COPY_VAR_ptr(local_zone_tags);
6445 	COPY_VAR_ptr(acl_tags);
6446 	COPY_VAR_ptr(acl_tag_actions);
6447 	COPY_VAR_ptr(acl_tag_datas);
6448 	*/
6449 	COPY_VAR_ptr(acl_view);
6450 	COPY_VAR_ptr(interface_actions);
6451 	/* These reference tags
6452 	COPY_VAR_ptr(interface_tags);
6453 	COPY_VAR_ptr(interface_tag_actions);
6454 	COPY_VAR_ptr(interface_tag_datas);
6455 	*/
6456 	COPY_VAR_ptr(interface_view);
6457 	/* This references tags
6458 	COPY_VAR_ptr(respip_tags);
6459 	*/
6460 	COPY_VAR_ptr(respip_actions);
6461 	COPY_VAR_ptr(respip_data);
6462 	/* Not copied because the length and items could then not match.
6463 	 * also the respip module keeps a pointer to the array in its state.
6464 	   tagname, num_tags
6465 	*/
6466 	COPY_VAR_int(remote_control_enable);
6467 	/* The first is used to walk through the list but last is
6468 	 * only used during config read. */
6469 	COPY_VAR_ptr(control_ifs.first);
6470 	COPY_VAR_ptr(control_ifs.last);
6471 	COPY_VAR_int(control_use_cert);
6472 	COPY_VAR_int(control_port);
6473 	COPY_VAR_ptr(server_key_file);
6474 	COPY_VAR_ptr(server_cert_file);
6475 	COPY_VAR_ptr(control_key_file);
6476 	COPY_VAR_ptr(control_cert_file);
6477 	COPY_VAR_ptr(python_script);
6478 	COPY_VAR_ptr(dynlib_file);
6479 	COPY_VAR_int(use_systemd);
6480 	COPY_VAR_int(do_daemonize);
6481 	COPY_VAR_int(minimal_responses);
6482 	COPY_VAR_int(rrset_roundrobin);
6483 	COPY_VAR_int(unknown_server_time_limit);
6484 	COPY_VAR_int(discard_timeout);
6485 	COPY_VAR_int(wait_limit);
6486 	COPY_VAR_int(wait_limit_cookie);
6487 	COPY_VAR_ptr(wait_limit_netblock);
6488 	COPY_VAR_ptr(wait_limit_cookie_netblock);
6489 	COPY_VAR_size_t(max_udp_size);
6490 	COPY_VAR_ptr(dns64_prefix);
6491 	COPY_VAR_int(dns64_synthall);
6492 	COPY_VAR_ptr(dns64_ignore_aaaa);
6493 	COPY_VAR_ptr(nat64_prefix);
6494 	COPY_VAR_int(dnstap);
6495 	COPY_VAR_int(dnstap_bidirectional);
6496 	COPY_VAR_ptr(dnstap_socket_path);
6497 	COPY_VAR_ptr(dnstap_ip);
6498 	COPY_VAR_int(dnstap_tls);
6499 	COPY_VAR_ptr(dnstap_tls_server_name);
6500 	COPY_VAR_ptr(dnstap_tls_cert_bundle);
6501 	COPY_VAR_ptr(dnstap_tls_client_key_file);
6502 	COPY_VAR_ptr(dnstap_tls_client_cert_file);
6503 	COPY_VAR_int(dnstap_send_identity);
6504 	COPY_VAR_int(dnstap_send_version);
6505 	COPY_VAR_ptr(dnstap_identity);
6506 	COPY_VAR_ptr(dnstap_version);
6507 	COPY_VAR_int(dnstap_sample_rate);
6508 	COPY_VAR_int(dnstap_log_resolver_query_messages);
6509 	COPY_VAR_int(dnstap_log_resolver_response_messages);
6510 	COPY_VAR_int(dnstap_log_client_query_messages);
6511 	COPY_VAR_int(dnstap_log_client_response_messages);
6512 	COPY_VAR_int(dnstap_log_forwarder_query_messages);
6513 	COPY_VAR_int(dnstap_log_forwarder_response_messages);
6514 	COPY_VAR_int(disable_dnssec_lame_check);
6515 	COPY_VAR_int(ip_ratelimit);
6516 	COPY_VAR_int(ip_ratelimit_cookie);
6517 	COPY_VAR_size_t(ip_ratelimit_slabs);
6518 	COPY_VAR_size_t(ip_ratelimit_size);
6519 	COPY_VAR_int(ip_ratelimit_factor);
6520 	COPY_VAR_int(ip_ratelimit_backoff);
6521 	COPY_VAR_int(ratelimit);
6522 	COPY_VAR_size_t(ratelimit_slabs);
6523 	COPY_VAR_size_t(ratelimit_size);
6524 	COPY_VAR_ptr(ratelimit_for_domain);
6525 	COPY_VAR_ptr(ratelimit_below_domain);
6526 	COPY_VAR_int(ratelimit_factor);
6527 	COPY_VAR_int(ratelimit_backoff);
6528 	COPY_VAR_int(outbound_msg_retry);
6529 	COPY_VAR_int(max_sent_count);
6530 	COPY_VAR_int(max_query_restarts);
6531 	COPY_VAR_int(qname_minimisation);
6532 	COPY_VAR_int(qname_minimisation_strict);
6533 	COPY_VAR_int(shm_enable);
6534 	COPY_VAR_int(shm_key);
6535 	COPY_VAR_ptr(edns_client_strings);
6536 	COPY_VAR_uint16_t(edns_client_string_opcode);
6537 	COPY_VAR_int(dnscrypt);
6538 	COPY_VAR_int(dnscrypt_port);
6539 	COPY_VAR_ptr(dnscrypt_provider);
6540 	COPY_VAR_ptr(dnscrypt_secret_key);
6541 	COPY_VAR_ptr(dnscrypt_provider_cert);
6542 	COPY_VAR_ptr(dnscrypt_provider_cert_rotated);
6543 	COPY_VAR_size_t(dnscrypt_shared_secret_cache_size);
6544 	COPY_VAR_size_t(dnscrypt_shared_secret_cache_slabs);
6545 	COPY_VAR_size_t(dnscrypt_nonce_cache_size);
6546 	COPY_VAR_size_t(dnscrypt_nonce_cache_slabs);
6547 	COPY_VAR_int(pad_responses);
6548 	COPY_VAR_size_t(pad_responses_block_size);
6549 	COPY_VAR_int(pad_queries);
6550 	COPY_VAR_size_t(pad_queries_block_size);
6551 #ifdef USE_IPSECMOD
6552 	COPY_VAR_int(ipsecmod_enabled);
6553 	COPY_VAR_ptr(ipsecmod_whitelist);
6554 	COPY_VAR_ptr(ipsecmod_hook);
6555 	COPY_VAR_int(ipsecmod_ignore_bogus);
6556 	COPY_VAR_int(ipsecmod_max_ttl);
6557 	COPY_VAR_int(ipsecmod_strict);
6558 #endif
6559 #ifdef USE_CACHEDB
6560 	COPY_VAR_ptr(cachedb_backend);
6561 	COPY_VAR_ptr(cachedb_secret);
6562 	COPY_VAR_int(cachedb_no_store);
6563 	COPY_VAR_int(cachedb_check_when_serve_expired);
6564 #ifdef USE_REDIS
6565 	COPY_VAR_ptr(redis_server_host);
6566 	COPY_VAR_ptr(redis_replica_server_host);
6567 	COPY_VAR_int(redis_server_port);
6568 	COPY_VAR_int(redis_replica_server_port);
6569 	COPY_VAR_ptr(redis_server_path);
6570 	COPY_VAR_ptr(redis_replica_server_path);
6571 	COPY_VAR_ptr(redis_server_password);
6572 	COPY_VAR_ptr(redis_replica_server_password);
6573 	COPY_VAR_int(redis_timeout);
6574 	COPY_VAR_int(redis_replica_timeout);
6575 	COPY_VAR_int(redis_command_timeout);
6576 	COPY_VAR_int(redis_replica_command_timeout);
6577 	COPY_VAR_int(redis_connect_timeout);
6578 	COPY_VAR_int(redis_replica_connect_timeout);
6579 	COPY_VAR_int(redis_expire_records);
6580 	COPY_VAR_int(redis_logical_db);
6581 	COPY_VAR_int(redis_replica_logical_db);
6582 #endif
6583 #endif
6584 	COPY_VAR_int(do_answer_cookie);
6585 	/* Not copied because the length and content could then not match.
6586 	   cookie_secret[40], cookie_secret_len
6587 	*/
6588 #ifdef USE_IPSET
6589 	COPY_VAR_ptr(ipset_name_v4);
6590 	COPY_VAR_ptr(ipset_name_v6);
6591 #endif
6592 	COPY_VAR_int(ede);
6593 	COPY_VAR_int(iter_scrub_ns);
6594 	COPY_VAR_int(iter_scrub_cname);
6595 	COPY_VAR_int(iter_scrub_rrsig);
6596 	COPY_VAR_int(max_global_quota);
6597 	COPY_VAR_int(iter_scrub_promiscuous);
6598 
6599 #undef COPY_VAR_int
6600 #undef COPY_VAR_ptr
6601 #undef COPY_VAR_unsigned_int
6602 #undef COPY_VAR_size_t
6603 #undef COPY_VAR_uint8_t
6604 #undef COPY_VAR_uint16_t
6605 #undef COPY_VAR_uint32_t
6606 #undef COPY_VAR_int32_t
6607 }
6608 #endif /* ATOMIC_POINTER_LOCK_FREE && HAVE_LINK_ATOMIC_STORE */
6609 
6610 /** fast reload thread, adjust the cache sizes */
6611 static void
fr_adjust_cache(struct module_env * env,struct config_file * oldcfg)6612 fr_adjust_cache(struct module_env* env, struct config_file* oldcfg)
6613 {
6614 	if(env->cfg->msg_cache_size != oldcfg->msg_cache_size)
6615 		slabhash_adjust_size(env->msg_cache, env->cfg->msg_cache_size);
6616 	if(env->cfg->rrset_cache_size != oldcfg->rrset_cache_size)
6617 		slabhash_adjust_size(&env->rrset_cache->table,
6618 			env->cfg->rrset_cache_size);
6619 	if(env->key_cache &&
6620 		env->cfg->key_cache_size != oldcfg->key_cache_size)
6621 		slabhash_adjust_size(env->key_cache->slab,
6622 			env->cfg->key_cache_size);
6623 	if(env->cfg->infra_cache_numhosts != oldcfg->infra_cache_numhosts) {
6624 		size_t inframem = env->cfg->infra_cache_numhosts *
6625 			(sizeof(struct infra_key) + sizeof(struct infra_data)
6626 			+ INFRA_BYTES_NAME);
6627 		slabhash_adjust_size(env->infra_cache->hosts, inframem);
6628 	}
6629 	if(env->cfg->ratelimit_size != oldcfg->ratelimit_size) {
6630 		slabhash_adjust_size(env->infra_cache->domain_rates,
6631 			env->cfg->ratelimit_size);
6632 		slabhash_adjust_size(env->infra_cache->client_ip_rates,
6633 			env->cfg->ratelimit_size);
6634 	}
6635 	if(env->neg_cache &&
6636 		env->cfg->neg_cache_size != oldcfg->neg_cache_size) {
6637 		val_neg_adjust_size(env->neg_cache, env->cfg->neg_cache_size);
6638 	}
6639 }
6640 
6641 /** fast reload thread, adjust the iterator env */
6642 static void
fr_adjust_iter_env(struct module_env * env,struct fast_reload_construct * ct)6643 fr_adjust_iter_env(struct module_env* env, struct fast_reload_construct* ct)
6644 {
6645 	int m;
6646 	struct iter_env* iter_env = NULL;
6647 	/* There is no comparison here to see if no options changed and thus
6648 	 * no swap is needed, the trees with addresses and domains can be
6649 	 * large and that would take too long. Instead the trees are
6650 	 * swapped in. */
6651 
6652 	/* Because the iterator env is not locked, the update cannot happen
6653 	 * when fr nopause is used. Without it the fast reload pauses the
6654 	 * other threads, so they are not currently using the structure. */
6655 	m = modstack_find(env->modstack, "iterator");
6656 	if(m != -1) iter_env = (struct iter_env*)env->modinfo[m];
6657 	if(iter_env) {
6658 		/* Swap the data so that the delete happens afterwards. */
6659 		int* oldtargetfetchpolicy = iter_env->target_fetch_policy;
6660 		int oldmaxdependencydepth = iter_env->max_dependency_depth;
6661 		struct iter_donotq* olddonotq = iter_env->donotq;
6662 		struct iter_priv* oldpriv = iter_env->priv;
6663 		struct rbtree_type* oldcapswhite = iter_env->caps_white;
6664 		struct iter_nat64 oldnat64 = iter_env->nat64;
6665 
6666 		iter_env->target_fetch_policy = ct->target_fetch_policy;
6667 		iter_env->max_dependency_depth = ct->max_dependency_depth;
6668 		iter_env->donotq = ct->donotq;
6669 		iter_env->priv = ct->priv;
6670 		iter_env->caps_white = ct->caps_white;
6671 		iter_env->nat64 = ct->nat64;
6672 		iter_env->outbound_msg_retry = env->cfg->outbound_msg_retry;
6673 		iter_env->max_sent_count = env->cfg->max_sent_count;
6674 		iter_env->max_query_restarts = env->cfg->max_query_restarts;
6675 
6676 		ct->target_fetch_policy = oldtargetfetchpolicy;
6677 		ct->max_dependency_depth = oldmaxdependencydepth;
6678 		ct->donotq = olddonotq;
6679 		ct->priv = oldpriv;
6680 		ct->caps_white = oldcapswhite;
6681 		ct->nat64 = oldnat64;
6682 	}
6683 }
6684 
6685 /** fast reload thread, adjust the validator env */
6686 static void
fr_adjust_val_env(struct module_env * env,struct fast_reload_construct * ct,struct config_file * oldcfg)6687 fr_adjust_val_env(struct module_env* env, struct fast_reload_construct* ct,
6688 	struct config_file* oldcfg)
6689 {
6690 	int m;
6691 	struct val_env* val_env = NULL;
6692 	if(env->cfg->bogus_ttl == oldcfg->bogus_ttl &&
6693 		env->cfg->val_date_override == oldcfg->val_date_override &&
6694 		env->cfg->val_sig_skew_min == oldcfg->val_sig_skew_min &&
6695 		env->cfg->val_sig_skew_max == oldcfg->val_sig_skew_max &&
6696 		env->cfg->val_max_restart == oldcfg->val_max_restart &&
6697 		strcmp(env->cfg->val_nsec3_key_iterations,
6698 		oldcfg->val_nsec3_key_iterations) == 0)
6699 		return; /* no changes */
6700 
6701 	/* Because the validator env is not locked, the update cannot happen
6702 	 * when fr nopause is used. Without it the fast reload pauses the
6703 	 * other threads, so they are not currently using the structure. */
6704 	m = modstack_find(env->modstack, "validator");
6705 	if(m != -1) val_env = (struct val_env*)env->modinfo[m];
6706 	if(val_env) {
6707 		/* Swap the arrays so that the delete happens afterwards. */
6708 		size_t* oldkeysize = val_env->nsec3_keysize;
6709 		size_t* oldmaxiter = val_env->nsec3_maxiter;
6710 		val_env->nsec3_keysize = NULL;
6711 		val_env->nsec3_maxiter = NULL;
6712 		val_env_apply_cfg(val_env, env->cfg, ct->nsec3_keysize,
6713 			ct->nsec3_maxiter, ct->nsec3_keyiter_count);
6714 		ct->nsec3_keysize = oldkeysize;
6715 		ct->nsec3_maxiter = oldmaxiter;
6716 		if(env->neg_cache) {
6717 			lock_basic_lock(&env->neg_cache->lock);
6718 			env->neg_cache->nsec3_max_iter = val_env->
6719 				nsec3_maxiter[val_env->nsec3_keyiter_count-1];
6720 			lock_basic_unlock(&env->neg_cache->lock);
6721 		}
6722 	}
6723 }
6724 
6725 /** fast reload thread, adjust the infra cache parameters */
6726 static void
fr_adjust_infra(struct module_env * env,struct fast_reload_construct * ct)6727 fr_adjust_infra(struct module_env* env, struct fast_reload_construct* ct)
6728 {
6729 	struct infra_cache* infra = env->infra_cache;
6730 	struct config_file* cfg = env->cfg;
6731 	struct rbtree_type oldwaitlim = infra->wait_limits_netblock;
6732 	struct rbtree_type oldwaitlimcookie =
6733 		infra->wait_limits_cookie_netblock;
6734 	struct rbtree_type olddomainlim = infra->domain_limits;
6735 
6736 	/* The size of the infra cache and ip rates is changed
6737 	 * in fr_adjust_cache. */
6738 	infra->host_ttl = cfg->host_ttl;
6739 	infra->infra_keep_probing = cfg->infra_keep_probing;
6740 	infra_dp_ratelimit = cfg->ratelimit;
6741 	infra_ip_ratelimit = cfg->ip_ratelimit;
6742 	infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
6743 	infra->wait_limits_netblock = ct->wait_limits_netblock;
6744 	infra->wait_limits_cookie_netblock = ct->wait_limits_cookie_netblock;
6745 	infra->domain_limits = ct->domain_limits;
6746 
6747 	ct->wait_limits_netblock = oldwaitlim;
6748 	ct->wait_limits_cookie_netblock = oldwaitlimcookie;
6749 	ct->domain_limits = olddomainlim;
6750 }
6751 
6752 /** fast reload thread, reload config with putting the new config items
6753  * in place and swapping out the old items. */
6754 static int
fr_reload_config(struct fast_reload_thread * fr,struct config_file * newcfg,struct fast_reload_construct * ct)6755 fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
6756 	struct fast_reload_construct* ct)
6757 {
6758 	struct daemon* daemon = fr->worker->daemon;
6759 	struct module_env* env = daemon->env;
6760 
6761 	/* These are constructed in the fr_construct_from_config routine. */
6762 	log_assert(ct->oldcfg);
6763 	log_assert(ct->fwds);
6764 	log_assert(ct->hints);
6765 
6766 	/* Grab big locks to satisfy lock conditions. */
6767 	lock_rw_wrlock(&ct->views->lock);
6768 	lock_rw_wrlock(&env->views->lock);
6769 	lock_rw_wrlock(&ct->respip_set->lock);
6770 	lock_rw_wrlock(&env->respip_set->lock);
6771 	lock_rw_wrlock(&ct->local_zones->lock);
6772 	lock_rw_wrlock(&daemon->local_zones->lock);
6773 	lock_rw_wrlock(&ct->auth_zones->rpz_lock);
6774 	lock_rw_wrlock(&env->auth_zones->rpz_lock);
6775 	lock_rw_wrlock(&ct->auth_zones->lock);
6776 	lock_rw_wrlock(&env->auth_zones->lock);
6777 	lock_rw_wrlock(&ct->fwds->lock);
6778 	lock_rw_wrlock(&env->fwds->lock);
6779 	lock_rw_wrlock(&ct->hints->lock);
6780 	lock_rw_wrlock(&env->hints->lock);
6781 	if(ct->anchors) {
6782 		lock_basic_lock(&ct->anchors->lock);
6783 		lock_basic_lock(&env->anchors->lock);
6784 	}
6785 
6786 #if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
6787 	if(fr->fr_nopause) {
6788 		fr_atomic_copy_cfg(ct->oldcfg, env->cfg, newcfg);
6789 	} else {
6790 #endif
6791 		/* Store old config elements. */
6792 		*ct->oldcfg = *env->cfg;
6793 		/* Insert new config elements. */
6794 		*env->cfg = *newcfg;
6795 #if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
6796 	}
6797 #endif
6798 
6799 	if(env->cfg->log_identity || ct->oldcfg->log_identity) {
6800 		/* pick up new log_identity string to use for log output. */
6801 		log_ident_set_or_default(env->cfg->log_identity);
6802 	}
6803 	/* the newcfg elements are in env->cfg, so should not be freed here. */
6804 #if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
6805 	/* if used, the routine that copies the config has zeroed items. */
6806 	if(!fr->fr_nopause)
6807 #endif
6808 		memset(newcfg, 0, sizeof(*newcfg));
6809 
6810 	/* Quickly swap the tree roots themselves with the already allocated
6811 	 * elements. This is a quick swap operation on the pointer.
6812 	 * The other threads are stopped and locks are held, so that a
6813 	 * consistent view of the configuration, before, and after, exists
6814 	 * towards the state machine for query resolution. */
6815 	forwards_swap_tree(env->fwds, ct->fwds);
6816 	hints_swap_tree(env->hints, ct->hints);
6817 	views_swap_tree(env->views, ct->views);
6818 	acl_list_swap_tree(daemon->acl, ct->acl);
6819 	acl_list_swap_tree(daemon->acl_interface, ct->acl_interface);
6820 	tcl_list_swap_tree(daemon->tcl, ct->tcl);
6821 	local_zones_swap_tree(daemon->local_zones, ct->local_zones);
6822 	respip_set_swap_tree(env->respip_set, ct->respip_set);
6823 	daemon->use_response_ip = ct->use_response_ip;
6824 	daemon->use_rpz = ct->use_rpz;
6825 	auth_zones_swap(env->auth_zones, ct->auth_zones);
6826 	edns_strings_swap_tree(env->edns_strings, ct->edns_strings);
6827 	anchors_swap_tree(env->anchors, ct->anchors);
6828 #ifdef USE_CACHEDB
6829 	daemon->env->cachedb_enabled = cachedb_is_enabled(&daemon->mods,
6830 		daemon->env);
6831 #endif
6832 	if(fr->sslctxs_changed) {
6833 		sslctxs_swap(daemon, ct);
6834 	}
6835 #ifdef USE_DNSTAP
6836 	if(env->cfg->dnstap) {
6837 		if(!fr->fr_nopause) {
6838 			if(!dt_apply_cfg(daemon->dtenv, env->cfg))
6839 				log_warn("fast_reload: dnstap identity/version metadata not updated due to allocation failure");
6840 		} else {
6841 			dt_apply_logcfg(daemon->dtenv, env->cfg);
6842 		}
6843 	}
6844 #endif
6845 	fr_adjust_cache(env, ct->oldcfg);
6846 	if(!fr->fr_nopause) {
6847 		fr_adjust_iter_env(env, ct);
6848 		fr_adjust_val_env(env, ct, ct->oldcfg);
6849 		fr_adjust_infra(env, ct);
6850 	}
6851 
6852 	/* Set globals with new config. */
6853 	config_apply(env->cfg);
6854 
6855 	lock_rw_unlock(&ct->views->lock);
6856 	lock_rw_unlock(&env->views->lock);
6857 	lock_rw_unlock(&ct->respip_set->lock);
6858 	lock_rw_unlock(&env->respip_set->lock);
6859 	lock_rw_unlock(&ct->local_zones->lock);
6860 	lock_rw_unlock(&daemon->local_zones->lock);
6861 	lock_rw_unlock(&ct->auth_zones->lock);
6862 	lock_rw_unlock(&env->auth_zones->lock);
6863 	lock_rw_unlock(&ct->auth_zones->rpz_lock);
6864 	lock_rw_unlock(&env->auth_zones->rpz_lock);
6865 	lock_rw_unlock(&ct->fwds->lock);
6866 	lock_rw_unlock(&env->fwds->lock);
6867 	lock_rw_unlock(&ct->hints->lock);
6868 	lock_rw_unlock(&env->hints->lock);
6869 	if(ct->anchors) {
6870 		lock_basic_unlock(&ct->anchors->lock);
6871 		lock_basic_unlock(&env->anchors->lock);
6872 	}
6873 
6874 	return 1;
6875 }
6876 
6877 /** fast reload, poll for ack incoming. */
6878 static void
fr_poll_for_ack(struct fast_reload_thread * fr)6879 fr_poll_for_ack(struct fast_reload_thread* fr)
6880 {
6881 	int loopexit = 0, bcount = 0;
6882 	uint32_t cmd;
6883 	ssize_t ret;
6884 
6885 	if(fr->need_to_quit)
6886 		return;
6887 	/* Is there data? */
6888 	if(!sock_poll_timeout(fr->commpair[1], -1, 1, 0, NULL)) {
6889 		log_err("fr_poll_for_ack: poll failed");
6890 		return;
6891 	}
6892 
6893 	/* Read the data */
6894 	while(1) {
6895 		if(++loopexit > IPC_LOOP_MAX) {
6896 			log_err("fr_poll_for_ack: recv loops %s",
6897 				sock_strerror(errno));
6898 			return;
6899 		}
6900 		ret = recv(fr->commpair[1], ((char*)&cmd)+bcount,
6901 			sizeof(cmd)-bcount, 0);
6902 		if(ret == -1) {
6903 			if(
6904 #ifndef USE_WINSOCK
6905 				errno == EINTR || errno == EAGAIN
6906 #  ifdef EWOULDBLOCK
6907 				|| errno == EWOULDBLOCK
6908 #  endif
6909 #else
6910 				WSAGetLastError() == WSAEINTR ||
6911 				WSAGetLastError() == WSAEINPROGRESS ||
6912 				WSAGetLastError() == WSAEWOULDBLOCK
6913 #endif
6914 				)
6915 				continue; /* Try again. */
6916 			log_err("fr_poll_for_ack: recv: %s",
6917 				sock_strerror(errno));
6918 			return;
6919 		} else if(ret+(ssize_t)bcount != sizeof(cmd)) {
6920 			bcount += ret;
6921 			if((size_t)bcount < sizeof(cmd))
6922 				continue;
6923 		}
6924 		break;
6925 	}
6926 	if(cmd == fast_reload_notification_exit) {
6927 		fr->need_to_quit = 1;
6928 		verbose(VERB_ALGO, "fast reload wait for ack: "
6929 			"exit notification received");
6930 		return;
6931 	}
6932 	if(cmd != fast_reload_notification_reload_ack) {
6933 		verbose(VERB_ALGO, "fast reload wait for ack: "
6934 			"wrong notification %d", (int)cmd);
6935 	}
6936 }
6937 
6938 /** fast reload thread, reload ipc communication to stop and start threads. */
6939 static int
fr_reload_ipc(struct fast_reload_thread * fr,struct config_file * newcfg,struct fast_reload_construct * ct)6940 fr_reload_ipc(struct fast_reload_thread* fr, struct config_file* newcfg,
6941 	struct fast_reload_construct* ct)
6942 {
6943 	int result = 1;
6944 	if(!fr->fr_nopause) {
6945 		fr_send_notification(fr, fast_reload_notification_reload_stop);
6946 		fr_poll_for_ack(fr);
6947 	}
6948 	if(!fr_reload_config(fr, newcfg, ct)) {
6949 		result = 0;
6950 	}
6951 	if(!fr->fr_nopause) {
6952 		fr_send_notification(fr, fast_reload_notification_reload_start);
6953 		fr_poll_for_ack(fr);
6954 	}
6955 	return result;
6956 }
6957 
6958 /** fast reload thread, load config */
6959 static int
fr_load_config(struct fast_reload_thread * fr,struct timeval * time_read,struct timeval * time_construct,struct timeval * time_reload)6960 fr_load_config(struct fast_reload_thread* fr, struct timeval* time_read,
6961 	struct timeval* time_construct, struct timeval* time_reload)
6962 {
6963 	struct fast_reload_construct ct;
6964 	struct config_file* newcfg = NULL;
6965 	memset(&ct, 0, sizeof(ct));
6966 
6967 	/* Read file. */
6968 	if(!fr_read_config(fr, &newcfg))
6969 		return 0;
6970 	if(gettimeofday(time_read, NULL) < 0)
6971 		log_err("gettimeofday: %s", strerror(errno));
6972 	if(fr_poll_for_quit(fr)) {
6973 		config_delete(newcfg);
6974 		return 1;
6975 	}
6976 
6977 	/* Check if the config can be loaded */
6978 	if(!fr_check_tag_defines(fr, newcfg)) {
6979 		config_delete(newcfg);
6980 		return 0;
6981 	}
6982 	if(!fr_check_tag_datas(fr, newcfg)) {
6983 		config_delete(newcfg);
6984 		return 0;
6985 	}
6986 	if(!fr_check_compat_cfg(fr, newcfg)) {
6987 		config_delete(newcfg);
6988 		return 0;
6989 	}
6990 	if(!fr_check_nopause_compat_cfg(fr, newcfg)) {
6991 		config_delete(newcfg);
6992 		return 0;
6993 	}
6994 	if(fr_poll_for_quit(fr)) {
6995 		config_delete(newcfg);
6996 		return 1;
6997 	}
6998 
6999 	/* Construct items. */
7000 	if(!fr_construct_from_config(fr, newcfg, &ct)) {
7001 		config_delete(newcfg);
7002 		if(!fr_output_printf(fr, "Could not construct from the "
7003 			"config, check for errors with unbound-checkconf, or "
7004 			"out of memory. The parse errors are printed in "
7005 			"the log.\n"))
7006 			return 0;
7007 		fr_send_notification(fr, fast_reload_notification_printout);
7008 		return 0;
7009 	}
7010 	if(gettimeofday(time_construct, NULL) < 0)
7011 		log_err("gettimeofday: %s", strerror(errno));
7012 	if(fr_poll_for_quit(fr)) {
7013 		config_delete(newcfg);
7014 		fr_construct_clear(&ct);
7015 		return 1;
7016 	}
7017 
7018 	/* Reload server. */
7019 	if(!fr_reload_ipc(fr, newcfg, &ct)) {
7020 		config_delete(newcfg);
7021 		fr_construct_clear(&ct);
7022 		if(!fr_output_printf(fr, "error: reload failed\n"))
7023 			return 0;
7024 		fr_send_notification(fr, fast_reload_notification_printout);
7025 		return 0;
7026 	}
7027 	if(gettimeofday(time_reload, NULL) < 0)
7028 		log_err("gettimeofday: %s", strerror(errno));
7029 
7030 	if(fr_poll_for_quit(fr)) {
7031 		config_delete(newcfg);
7032 		fr_construct_clear(&ct);
7033 		return 1;
7034 	}
7035 	if(fr->fr_nopause) {
7036 		/* Poll every thread, with a no-work poll item over the
7037 		 * command pipe. This makes the worker thread surely move
7038 		 * to deal with that event, and thus the thread is no longer
7039 		 * holding, eg. a string item from the old config struct.
7040 		 * And then the old config struct can safely be deleted.
7041 		 * Only needed when nopause is used, because without that
7042 		 * the worker threads are already waiting on a command pipe
7043 		 * item. This nopause command pipe item does not take work,
7044 		 * it returns immediately, so it does not delay the workers.
7045 		 * They can be polled one at a time. But its processing causes
7046 		 * the worker to have released data items from old config.
7047 		 * This also makes sure the threads are not holding locks on
7048 		 * individual items in the local_zones, views, respip_set. */
7049 		fr_send_notification(fr,
7050 			fast_reload_notification_reload_nopause_poll);
7051 		fr_poll_for_ack(fr);
7052 	}
7053 
7054 	/* Delete old. */
7055 	config_delete(newcfg);
7056 	fr_construct_clear(&ct);
7057 	return 1;
7058 }
7059 
7060 /** fast reload thread. the thread main function */
fast_reload_thread_main(void * arg)7061 static void* fast_reload_thread_main(void* arg)
7062 {
7063 	struct fast_reload_thread* fast_reload_thread = (struct fast_reload_thread*)arg;
7064 	struct timeval time_start, time_read, time_construct, time_reload,
7065 		time_end;
7066 	const char name[16] = "unbound/freload"; /* seems to be the safest size
7067 						    between different OSes */
7068 
7069 #if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
7070 	fast_reload_thread->thread_tid = gettid();
7071 	if(fast_reload_thread->thread_tid_log)
7072 		log_thread_set(&fast_reload_thread->thread_tid);
7073 	else
7074 #endif
7075 		log_thread_set(&fast_reload_thread->threadnum);
7076 
7077 	ub_thread_setname(ub_thread_self(), name);
7078 	(void)name; /* When setname is not defined, ignore the name variable. */
7079 
7080 	verbose(VERB_ALGO, "start fast reload thread");
7081 	if(fast_reload_thread->fr_verb >= 1) {
7082 		fr_init_time(&time_start, &time_read, &time_construct,
7083 			&time_reload, &time_end);
7084 		if(fr_poll_for_quit(fast_reload_thread))
7085 			goto done;
7086 	}
7087 
7088 	/* print output to the client */
7089 	if(fast_reload_thread->fr_verb >= 1) {
7090 		if(!fr_output_printf(fast_reload_thread, "thread started\n"))
7091 			goto done_error;
7092 		fr_send_notification(fast_reload_thread,
7093 			fast_reload_notification_printout);
7094 		if(fr_poll_for_quit(fast_reload_thread))
7095 			goto done;
7096 	}
7097 
7098 	if(!fr_load_config(fast_reload_thread, &time_read, &time_construct,
7099 		&time_reload))
7100 		goto done_error;
7101 	if(fr_poll_for_quit(fast_reload_thread))
7102 		goto done;
7103 
7104 	if(fast_reload_thread->fr_verb >= 1) {
7105 		if(!fr_finish_time(fast_reload_thread, &time_start, &time_read,
7106 			&time_construct, &time_reload, &time_end))
7107 			goto done_error;
7108 		if(fr_poll_for_quit(fast_reload_thread))
7109 			goto done;
7110 	}
7111 
7112 	if(!fr_output_printf(fast_reload_thread, "ok\n"))
7113 		goto done_error;
7114 	fr_send_notification(fast_reload_thread,
7115 		fast_reload_notification_printout);
7116 	verbose(VERB_ALGO, "stop fast reload thread");
7117 	/* If this is not an exit due to quit earlier, send regular done. */
7118 	if(!fast_reload_thread->need_to_quit)
7119 		fr_send_notification(fast_reload_thread,
7120 			fast_reload_notification_done);
7121 	/* If during the fast_reload_notification_done send,
7122 	 * fast_reload_notification_exit was received, ack it. If the
7123 	 * thread is exiting due to quit received earlier, also ack it.*/
7124 done:
7125 	if(fast_reload_thread->need_to_quit)
7126 		fr_send_notification(fast_reload_thread,
7127 			fast_reload_notification_exited);
7128 	return NULL;
7129 done_error:
7130 	verbose(VERB_ALGO, "stop fast reload thread with done_error");
7131 	fr_send_notification(fast_reload_thread,
7132 		fast_reload_notification_done_error);
7133 	return NULL;
7134 }
7135 #endif /* !THREADS_DISABLED */
7136 
7137 /** create a socketpair for bidirectional communication, false on failure */
7138 static int
create_socketpair(int * pair,struct ub_randstate * rand)7139 create_socketpair(int* pair, struct ub_randstate* rand)
7140 {
7141 #ifndef USE_WINSOCK
7142 	if(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
7143 		log_err("socketpair: %s", strerror(errno));
7144 		return 0;
7145 	}
7146 	(void)rand;
7147 #else
7148 	struct sockaddr_in addr, baddr, accaddr, connaddr;
7149 	socklen_t baddrlen, accaddrlen, connaddrlen;
7150 	uint8_t localhost[] = {127, 0, 0, 1};
7151 	uint8_t nonce[16], recvnonce[16];
7152 	size_t i;
7153 	int lst, pollin_event, bcount, loopcount;
7154 	int connect_poll_timeout = 200; /* msec to wait for connection */
7155 	ssize_t ret;
7156 	pair[0] = -1;
7157 	pair[1] = -1;
7158 	for(i=0; i<sizeof(nonce); i++) {
7159 		nonce[i] = ub_random_max(rand, 256);
7160 	}
7161 	lst = socket(AF_INET, SOCK_STREAM, 0);
7162 	if(lst == -1) {
7163 		log_err("create_socketpair: socket: %s", sock_strerror(errno));
7164 		return 0;
7165 	}
7166 	memset(&addr, 0, sizeof(addr));
7167 	addr.sin_family = AF_INET;
7168 	addr.sin_port = 0;
7169 	memcpy(&addr.sin_addr, localhost, 4);
7170 	if(bind(lst, (struct sockaddr*)&addr, (socklen_t)sizeof(addr))
7171 		== -1) {
7172 		log_err("create socketpair: bind: %s", sock_strerror(errno));
7173 		sock_close(lst);
7174 		return 0;
7175 	}
7176 	if(listen(lst, 12) == -1) {
7177 		log_err("create socketpair: listen: %s", sock_strerror(errno));
7178 		sock_close(lst);
7179 		return 0;
7180 	}
7181 
7182 	pair[1] = socket(AF_INET, SOCK_STREAM, 0);
7183 	if(pair[1] == -1) {
7184 		log_err("create socketpair: socket: %s", sock_strerror(errno));
7185 		sock_close(lst);
7186 		return 0;
7187 	}
7188 	baddrlen = (socklen_t)sizeof(baddr);
7189 	if(getsockname(lst, (struct sockaddr*)&baddr, &baddrlen) == -1) {
7190 		log_err("create socketpair: getsockname: %s",
7191 			sock_strerror(errno));
7192 		sock_close(lst);
7193 		sock_close(pair[1]);
7194 		pair[1] = -1;
7195 		return 0;
7196 	}
7197 	if(baddrlen > (socklen_t)sizeof(baddr)) {
7198 		log_err("create socketpair: getsockname returned addr too big");
7199 		sock_close(lst);
7200 		sock_close(pair[1]);
7201 		pair[1] = -1;
7202 		return 0;
7203 	}
7204 	/* the socket is blocking */
7205 	if(connect(pair[1], (struct sockaddr*)&baddr, baddrlen) == -1) {
7206 		log_err("create socketpair: connect: %s",
7207 			sock_strerror(errno));
7208 		sock_close(lst);
7209 		sock_close(pair[1]);
7210 		pair[1] = -1;
7211 		return 0;
7212 	}
7213 	if(!sock_poll_timeout(lst, connect_poll_timeout, 1, 0, &pollin_event)) {
7214 		log_err("create socketpair: poll for accept failed: %s",
7215 			sock_strerror(errno));
7216 		sock_close(lst);
7217 		sock_close(pair[1]);
7218 		pair[1] = -1;
7219 		return 0;
7220 	}
7221 	if(!pollin_event) {
7222 		log_err("create socketpair: poll timeout for accept");
7223 		sock_close(lst);
7224 		sock_close(pair[1]);
7225 		pair[1] = -1;
7226 		return 0;
7227 	}
7228 	accaddrlen = (socklen_t)sizeof(accaddr);
7229 	pair[0] = accept(lst, (struct sockaddr*)&accaddr, &accaddrlen);
7230 	if(pair[0] == -1) {
7231 		log_err("create socketpair: accept: %s", sock_strerror(errno));
7232 		sock_close(lst);
7233 		sock_close(pair[1]);
7234 		pair[1] = -1;
7235 		return 0;
7236 	}
7237 	if(accaddrlen > (socklen_t)sizeof(accaddr)) {
7238 		log_err("create socketpair: accept returned addr too big");
7239 		sock_close(lst);
7240 		sock_close(pair[0]);
7241 		sock_close(pair[1]);
7242 		pair[0] = -1;
7243 		pair[1] = -1;
7244 		return 0;
7245 	}
7246 	if(accaddr.sin_family != AF_INET ||
7247 	   memcmp(localhost, &accaddr.sin_addr, 4) != 0) {
7248 		log_err("create socketpair: accept from wrong address");
7249 		sock_close(lst);
7250 		sock_close(pair[0]);
7251 		sock_close(pair[1]);
7252 		pair[0] = -1;
7253 		pair[1] = -1;
7254 		return 0;
7255 	}
7256 	connaddrlen = (socklen_t)sizeof(connaddr);
7257 	if(getsockname(pair[1], (struct sockaddr*)&connaddr, &connaddrlen)
7258 		== -1) {
7259 		log_err("create socketpair: getsockname connectedaddr: %s",
7260 			sock_strerror(errno));
7261 		sock_close(lst);
7262 		sock_close(pair[0]);
7263 		sock_close(pair[1]);
7264 		pair[0] = -1;
7265 		pair[1] = -1;
7266 		return 0;
7267 	}
7268 	if(connaddrlen > (socklen_t)sizeof(connaddr)) {
7269 		log_err("create socketpair: getsockname connectedaddr returned addr too big");
7270 		sock_close(lst);
7271 		sock_close(pair[0]);
7272 		sock_close(pair[1]);
7273 		pair[0] = -1;
7274 		pair[1] = -1;
7275 		return 0;
7276 	}
7277 	if(connaddr.sin_family != AF_INET ||
7278 	   memcmp(localhost, &connaddr.sin_addr, 4) != 0) {
7279 		log_err("create socketpair: getsockname connectedaddr returned wrong address");
7280 		sock_close(lst);
7281 		sock_close(pair[0]);
7282 		sock_close(pair[1]);
7283 		pair[0] = -1;
7284 		pair[1] = -1;
7285 		return 0;
7286 	}
7287 	if(accaddr.sin_port != connaddr.sin_port) {
7288 		log_err("create socketpair: accept from wrong port");
7289 		sock_close(lst);
7290 		sock_close(pair[0]);
7291 		sock_close(pair[1]);
7292 		pair[0] = -1;
7293 		pair[1] = -1;
7294 		return 0;
7295 	}
7296 	sock_close(lst);
7297 
7298 	loopcount = 0;
7299 	bcount = 0;
7300 	while(1) {
7301 		if(++loopcount > IPC_LOOP_MAX) {
7302 			log_err("create socketpair: send failed due to loop");
7303 			sock_close(pair[0]);
7304 			sock_close(pair[1]);
7305 			pair[0] = -1;
7306 			pair[1] = -1;
7307 			return 0;
7308 		}
7309 		ret = send(pair[1], (void*)(nonce+bcount),
7310 			sizeof(nonce)-bcount, 0);
7311 		if(ret == -1) {
7312 			if(
7313 #ifndef USE_WINSOCK
7314 				errno == EINTR || errno == EAGAIN
7315 #  ifdef EWOULDBLOCK
7316 				|| errno == EWOULDBLOCK
7317 #  endif
7318 #else
7319 				WSAGetLastError() == WSAEINTR ||
7320 				WSAGetLastError() == WSAEINPROGRESS ||
7321 				WSAGetLastError() == WSAEWOULDBLOCK
7322 #endif
7323 				)
7324 				continue; /* Try again. */
7325 			log_err("create socketpair: send: %s", sock_strerror(errno));
7326 			sock_close(pair[0]);
7327 			sock_close(pair[1]);
7328 			pair[0] = -1;
7329 			pair[1] = -1;
7330 			return 0;
7331 		} else if(ret+(ssize_t)bcount != sizeof(nonce)) {
7332 			bcount += ret;
7333 			if((size_t)bcount < sizeof(nonce))
7334 				continue;
7335 		}
7336 		break;
7337 	}
7338 
7339 	if(!sock_poll_timeout(pair[0], connect_poll_timeout, 1, 0, &pollin_event)) {
7340 		log_err("create socketpair: poll failed: %s",
7341 			sock_strerror(errno));
7342 		sock_close(pair[0]);
7343 		sock_close(pair[1]);
7344 		pair[0] = -1;
7345 		pair[1] = -1;
7346 		return 0;
7347 	}
7348 	if(!pollin_event) {
7349 		log_err("create socketpair: poll timeout for recv");
7350 		sock_close(pair[0]);
7351 		sock_close(pair[1]);
7352 		pair[0] = -1;
7353 		pair[1] = -1;
7354 		return 0;
7355 	}
7356 
7357 	loopcount = 0;
7358 	bcount = 0;
7359 	while(1) {
7360 		if(++loopcount > IPC_LOOP_MAX) {
7361 			log_err("create socketpair: recv failed due to loop");
7362 			sock_close(pair[0]);
7363 			sock_close(pair[1]);
7364 			pair[0] = -1;
7365 			pair[1] = -1;
7366 			return 0;
7367 		}
7368 		ret = recv(pair[0], (void*)(recvnonce+bcount),
7369 			sizeof(nonce)-bcount, 0);
7370 		if(ret == -1) {
7371 			if(
7372 #ifndef USE_WINSOCK
7373 				errno == EINTR || errno == EAGAIN
7374 #  ifdef EWOULDBLOCK
7375 				|| errno == EWOULDBLOCK
7376 #  endif
7377 #else
7378 				WSAGetLastError() == WSAEINTR ||
7379 				WSAGetLastError() == WSAEINPROGRESS ||
7380 				WSAGetLastError() == WSAEWOULDBLOCK
7381 #endif
7382 				)
7383 				continue; /* Try again. */
7384 			log_err("create socketpair: recv: %s", sock_strerror(errno));
7385 			sock_close(pair[0]);
7386 			sock_close(pair[1]);
7387 			pair[0] = -1;
7388 			pair[1] = -1;
7389 			return 0;
7390 		} else if(ret == 0) {
7391 			log_err("create socketpair: stream closed");
7392 			sock_close(pair[0]);
7393 			sock_close(pair[1]);
7394 			pair[0] = -1;
7395 			pair[1] = -1;
7396 			return 0;
7397 		} else if(ret+(ssize_t)bcount != sizeof(nonce)) {
7398 			bcount += ret;
7399 			if((size_t)bcount < sizeof(nonce))
7400 				continue;
7401 		}
7402 		break;
7403 	}
7404 
7405 	if(memcmp(nonce, recvnonce, sizeof(nonce)) != 0) {
7406 		log_err("create socketpair: recv wrong nonce");
7407 		sock_close(pair[0]);
7408 		sock_close(pair[1]);
7409 		pair[0] = -1;
7410 		pair[1] = -1;
7411 		return 0;
7412 	}
7413 #endif
7414 	return 1;
7415 }
7416 
7417 /** fast reload thread. setup the thread info */
7418 static int
fast_reload_thread_setup(struct worker * worker,int fr_verb,int fr_nopause,int fr_drop_mesh)7419 fast_reload_thread_setup(struct worker* worker, int fr_verb, int fr_nopause,
7420 	int fr_drop_mesh)
7421 {
7422 	struct fast_reload_thread* fr;
7423 	int numworkers = worker->daemon->num;
7424 	worker->daemon->fast_reload_thread = (struct fast_reload_thread*)
7425 		calloc(1, sizeof(*worker->daemon->fast_reload_thread));
7426 	if(!worker->daemon->fast_reload_thread)
7427 		return 0;
7428 	fr = worker->daemon->fast_reload_thread;
7429 	fr->fr_verb = fr_verb;
7430 	fr->fr_nopause = fr_nopause;
7431 	fr->fr_drop_mesh = fr_drop_mesh;
7432 	worker->daemon->fast_reload_drop_mesh = fr->fr_drop_mesh;
7433 	/* The thread id printed in logs, numworker+1 is the dnstap thread.
7434 	 * This is numworkers+2. */
7435 	fr->threadnum = numworkers+2;
7436 	fr->commpair[0] = -1;
7437 	fr->commpair[1] = -1;
7438 	fr->commreload[0] = -1;
7439 	fr->commreload[1] = -1;
7440 	if(!create_socketpair(fr->commpair, worker->daemon->rand)) {
7441 		free(fr);
7442 		worker->daemon->fast_reload_thread = NULL;
7443 		return 0;
7444 	}
7445 	fr->worker = worker;
7446 	fr->fr_output = (struct config_strlist_head*)calloc(1,
7447 		sizeof(*fr->fr_output));
7448 	if(!fr->fr_output) {
7449 		sock_close(fr->commpair[0]);
7450 		sock_close(fr->commpair[1]);
7451 		free(fr);
7452 		worker->daemon->fast_reload_thread = NULL;
7453 		return 0;
7454 	}
7455 	if(!create_socketpair(fr->commreload, worker->daemon->rand)) {
7456 		sock_close(fr->commpair[0]);
7457 		sock_close(fr->commpair[1]);
7458 		free(fr->fr_output);
7459 		free(fr);
7460 		worker->daemon->fast_reload_thread = NULL;
7461 		return 0;
7462 	}
7463 	lock_basic_init(&fr->fr_output_lock);
7464 	lock_protect(&fr->fr_output_lock, fr->fr_output,
7465 		sizeof(*fr->fr_output));
7466 #ifdef HAVE_GETTID
7467 	fr->thread_tid_log = worker->env.cfg->log_thread_id;
7468 #endif
7469 	return 1;
7470 }
7471 
7472 /** fast reload, delete auth zone change list */
7473 static void
fr_auth_change_list_delete(struct fast_reload_auth_change * auth_zone_change_list)7474 fr_auth_change_list_delete(
7475 	struct fast_reload_auth_change* auth_zone_change_list)
7476 {
7477 	struct fast_reload_auth_change* item, *next;
7478 	item = auth_zone_change_list;
7479 	while(item) {
7480 		next = item->next;
7481 		free(item);
7482 		item = next;
7483 	}
7484 }
7485 
7486 /** fast reload thread. desetup and delete the thread info. */
7487 static void
fast_reload_thread_desetup(struct fast_reload_thread * fast_reload_thread)7488 fast_reload_thread_desetup(struct fast_reload_thread* fast_reload_thread)
7489 {
7490 	if(!fast_reload_thread)
7491 		return;
7492 	if(fast_reload_thread->service_event &&
7493 		fast_reload_thread->service_event_is_added) {
7494 		ub_event_del(fast_reload_thread->service_event);
7495 		fast_reload_thread->service_event_is_added = 0;
7496 	}
7497 	if(fast_reload_thread->service_event)
7498 		ub_event_free(fast_reload_thread->service_event);
7499 	sock_close(fast_reload_thread->commpair[0]);
7500 	sock_close(fast_reload_thread->commpair[1]);
7501 	sock_close(fast_reload_thread->commreload[0]);
7502 	sock_close(fast_reload_thread->commreload[1]);
7503 	if(fast_reload_thread->printq) {
7504 		fr_main_perform_printout(fast_reload_thread);
7505 		/* If it is empty now, there is nothing to print on fd. */
7506 		if(fr_printq_empty(fast_reload_thread->printq)) {
7507 			fr_printq_delete(fast_reload_thread->printq);
7508 		} else {
7509 			/* Keep the printq around to printout the remaining
7510 			 * text to the remote client. Until it is done, it
7511 			 * sits on a list, that is in the daemon struct.
7512 			 * The event can then spool the remaining text to the
7513 			 * remote client and eventually delete itself from the
7514 			 * callback. */
7515 			fr_printq_list_insert(fast_reload_thread->printq,
7516 				fast_reload_thread->worker->daemon);
7517 			fast_reload_thread->printq = NULL;
7518 		}
7519 	}
7520 	lock_basic_destroy(&fast_reload_thread->fr_output_lock);
7521 	if(fast_reload_thread->fr_output) {
7522 		config_delstrlist(fast_reload_thread->fr_output->first);
7523 		free(fast_reload_thread->fr_output);
7524 	}
7525 	fr_auth_change_list_delete(fast_reload_thread->auth_zone_change_list);
7526 
7527 	free(fast_reload_thread);
7528 }
7529 
7530 /**
7531  * Fast reload thread, send a command to the thread. Blocking on timeout.
7532  * It handles received input from the thread, if any is received.
7533  */
7534 static void
fr_send_cmd_to(struct fast_reload_thread * fr,enum fast_reload_notification status,int check_cmds,int blocking)7535 fr_send_cmd_to(struct fast_reload_thread* fr,
7536 	enum fast_reload_notification status, int check_cmds, int blocking)
7537 {
7538 	int outevent, loopexit = 0, bcount = 0;
7539 	uint32_t cmd;
7540 	ssize_t ret;
7541 	verbose(VERB_ALGO, "send notification to fast reload thread: %s",
7542 		fr_notification_to_string(status));
7543 	cmd = status;
7544 	while(1) {
7545 		if(++loopexit > IPC_LOOP_MAX) {
7546 			log_err("send notification to fast reload: could not send notification: loop");
7547 			return;
7548 		}
7549 		if(check_cmds)
7550 			fr_check_cmd_from_thread(fr);
7551 		/* wait for socket to become writable */
7552 		if(!sock_poll_timeout(fr->commpair[0],
7553 			(blocking?-1:IPC_NOTIFICATION_WAIT),
7554 			0, 1, &outevent)) {
7555 			log_err("send notification to fast reload: poll failed");
7556 			return;
7557 		}
7558 		if(!outevent)
7559 			continue;
7560 		/* keep static analyzer happy; send(-1,..) */
7561 		log_assert(fr->commpair[0] >= 0);
7562 		ret = send(fr->commpair[0], ((char*)&cmd)+bcount,
7563 			sizeof(cmd)-bcount, 0);
7564 		if(ret == -1) {
7565 			if(
7566 #ifndef USE_WINSOCK
7567 				errno == EINTR || errno == EAGAIN
7568 #  ifdef EWOULDBLOCK
7569 				|| errno == EWOULDBLOCK
7570 #  endif
7571 #else
7572 				WSAGetLastError() == WSAEINTR ||
7573 				WSAGetLastError() == WSAEINPROGRESS ||
7574 				WSAGetLastError() == WSAEWOULDBLOCK
7575 #endif
7576 				)
7577 				continue; /* Try again. */
7578 			log_err("send notification to fast reload: send: %s",
7579 				sock_strerror(errno));
7580 			return;
7581 		} else if(ret+(ssize_t)bcount != sizeof(cmd)) {
7582 			bcount += ret;
7583 			if((size_t)bcount < sizeof(cmd))
7584 				continue;
7585 		}
7586 		break;
7587 	}
7588 }
7589 
7590 /** Fast reload, the main thread handles that the fast reload thread has
7591  * exited. */
7592 static void
fr_main_perform_done(struct fast_reload_thread * fr)7593 fr_main_perform_done(struct fast_reload_thread* fr)
7594 {
7595 	struct worker* worker = fr->worker;
7596 	verbose(VERB_ALGO, "join with fastreload thread");
7597 	ub_thread_join(fr->tid);
7598 	verbose(VERB_ALGO, "joined with fastreload thread");
7599 	fast_reload_thread_desetup(fr);
7600 	worker->daemon->fast_reload_thread = NULL;
7601 }
7602 
7603 /** Append strlist after strlist */
7604 static void
cfg_strlist_append_listhead(struct config_strlist_head * list,struct config_strlist_head * more)7605 cfg_strlist_append_listhead(struct config_strlist_head* list,
7606 	struct config_strlist_head* more)
7607 {
7608 	if(!more->first)
7609 		return;
7610 	if(list->last)
7611 		list->last->next = more->first;
7612 	else
7613 		list->first = more->first;
7614 	list->last = more->last;
7615 }
7616 
7617 /** Fast reload, the remote control thread handles that the fast reload thread
7618  * has output to be printed, on the linked list that is locked. */
7619 static void
fr_main_perform_printout(struct fast_reload_thread * fr)7620 fr_main_perform_printout(struct fast_reload_thread* fr)
7621 {
7622 	struct config_strlist_head out;
7623 
7624 	/* Fetch the list of items to be printed */
7625 	lock_basic_lock(&fr->fr_output_lock);
7626 	out.first = fr->fr_output->first;
7627 	out.last = fr->fr_output->last;
7628 	fr->fr_output->first = NULL;
7629 	fr->fr_output->last = NULL;
7630 	lock_basic_unlock(&fr->fr_output_lock);
7631 
7632 	if(!fr->printq || !fr->printq->client_cp) {
7633 		/* There is no output socket, delete it. */
7634 		config_delstrlist(out.first);
7635 		return;
7636 	}
7637 
7638 	/* Put them on the output list, not locked because the list
7639 	 * producer and consumer are both owned by the remote control thread,
7640 	 * it moves the items to the list for printing in the event callback
7641 	 * for the client_cp. */
7642 	cfg_strlist_append_listhead(fr->printq->to_print, &out);
7643 
7644 	/* Set the client_cp to output if not already */
7645 	if(!fr->printq->client_cp->event_added)
7646 		comm_point_listen_for_rw(fr->printq->client_cp, 0, 1);
7647 }
7648 
7649 /** fast reload, receive ack from workers that they are waiting, run
7650  * by the mainthr after sending them reload_stop. */
7651 static void
fr_read_ack_from_workers(struct fast_reload_thread * fr)7652 fr_read_ack_from_workers(struct fast_reload_thread* fr)
7653 {
7654 	struct daemon* daemon = fr->worker->daemon;
7655 	/* Every worker sends one byte, wait for num-1 bytes. */
7656 	int count=0, total=daemon->num-1;
7657 	while(count < total) {
7658 		uint8_t r;
7659 		ssize_t ret;
7660 		ret = recv(fr->commreload[0], (void*)&r, 1, 0);
7661 		if(ret == -1) {
7662 			if(
7663 #ifndef USE_WINSOCK
7664 				errno == EINTR || errno == EAGAIN
7665 #  ifdef EWOULDBLOCK
7666 				|| errno == EWOULDBLOCK
7667 #  endif
7668 #else
7669 				WSAGetLastError() == WSAEINTR ||
7670 				WSAGetLastError() == WSAEINPROGRESS ||
7671 				WSAGetLastError() == WSAEWOULDBLOCK
7672 #endif
7673 				)
7674 				continue; /* Try again */
7675 			log_err("worker reload ack: recv failed: %s",
7676 				sock_strerror(errno));
7677 			return;
7678 		}
7679 		count++;
7680 		verbose(VERB_ALGO, "worker reload ack from (uint8_t)%d",
7681 			(int)r);
7682 	}
7683 }
7684 
7685 /** fast reload, poll for reload_start in mainthr waiting on a notification
7686  * from the fast reload thread. */
7687 static void
fr_poll_for_reload_start(struct fast_reload_thread * fr)7688 fr_poll_for_reload_start(struct fast_reload_thread* fr)
7689 {
7690 	int loopexit = 0, bcount = 0;
7691 	uint32_t cmd;
7692 	ssize_t ret;
7693 
7694 	/* Is there data? */
7695 	if(!sock_poll_timeout(fr->commpair[0], -1, 1, 0, NULL)) {
7696 		log_err("fr_poll_for_reload_start: poll failed");
7697 		return;
7698 	}
7699 
7700 	/* Read the data */
7701 	while(1) {
7702 		if(++loopexit > IPC_LOOP_MAX) {
7703 			log_err("fr_poll_for_reload_start: recv loops %s",
7704 				sock_strerror(errno));
7705 			return;
7706 		}
7707 		ret = recv(fr->commpair[0], ((char*)&cmd)+bcount,
7708 			sizeof(cmd)-bcount, 0);
7709 		if(ret == -1) {
7710 			if(
7711 #ifndef USE_WINSOCK
7712 				errno == EINTR || errno == EAGAIN
7713 #  ifdef EWOULDBLOCK
7714 				|| errno == EWOULDBLOCK
7715 #  endif
7716 #else
7717 				WSAGetLastError() == WSAEINTR ||
7718 				WSAGetLastError() == WSAEINPROGRESS ||
7719 				WSAGetLastError() == WSAEWOULDBLOCK
7720 #endif
7721 				)
7722 				continue; /* Try again. */
7723 			log_err("fr_poll_for_reload_start: recv: %s",
7724 				sock_strerror(errno));
7725 			return;
7726 		} else if(ret+(ssize_t)bcount != sizeof(cmd)) {
7727 			bcount += ret;
7728 			if((size_t)bcount < sizeof(cmd))
7729 				continue;
7730 		}
7731 		break;
7732 	}
7733 	if(cmd != fast_reload_notification_reload_start) {
7734 		verbose(VERB_ALGO, "fast reload wait for ack: "
7735 			"wrong notification %d", (int)cmd);
7736 	}
7737 }
7738 
7739 /** Pick up the worker mesh changes, after fast reload. */
7740 static void
fr_worker_pickup_mesh(struct worker * worker)7741 fr_worker_pickup_mesh(struct worker* worker)
7742 {
7743 	struct mesh_area* mesh = worker->env.mesh;
7744 	struct config_file* cfg = worker->env.cfg;
7745 	mesh->use_response_ip = worker->daemon->use_response_ip;
7746 	mesh->use_rpz = worker->daemon->use_rpz;
7747 	mesh->max_reply_states = cfg->num_queries_per_thread;
7748 	mesh->max_forever_states = (mesh->max_reply_states+1)/2;
7749 #ifndef S_SPLINT_S
7750 	mesh->jostle_max.tv_sec = (time_t)(cfg->jostle_time / 1000);
7751 	mesh->jostle_max.tv_usec = (time_t)((cfg->jostle_time % 1000)*1000);
7752 #endif
7753 }
7754 
7755 /**
7756  * Remove the old tcl_addr entries from the open connections.
7757  * They are only incremented when an accept is performed on a tcp comm point.
7758  * @param front: listening comm ports of the worker.
7759  */
7760 static void
tcl_remove_old(struct listen_dnsport * front)7761 tcl_remove_old(struct listen_dnsport* front)
7762 {
7763 	struct listen_list* l;
7764 	l = front->cps;
7765 	while(l) {
7766 		if(l->com->type == comm_tcp_accept) {
7767 			int i;
7768 			for(i=0; i<l->com->max_tcp_count; i++) {
7769 				if(l->com->tcp_handlers[i]->tcl_addr) {
7770 					/* Because the increment of the
7771 					 * connection limit was in the old
7772 					 * tcl list, the new list does not
7773 					 * need a decrement. With NULL it is
7774 					 * not decremented when the connection
7775 					 * is done, and also there is no
7776 					 * reference to the old connection
7777 					 * limit structure. */
7778 					l->com->tcp_handlers[i]->tcl_addr =
7779 						NULL;
7780 				}
7781 			}
7782 		}
7783 		l = l->next;
7784 	}
7785 }
7786 
7787 /** Stop zonemd lookup */
7788 static void
auth_zone_zonemd_stop_lookup(struct auth_zone * z,struct mesh_area * mesh)7789 auth_zone_zonemd_stop_lookup(struct auth_zone* z, struct mesh_area* mesh)
7790 {
7791 	struct query_info qinfo;
7792 	uint16_t qflags = BIT_RD;
7793 	qinfo.qname_len = z->namelen;
7794 	qinfo.qname = z->name;
7795 	qinfo.qclass = z->dclass;
7796 	qinfo.qtype = z->zonemd_callback_qtype;
7797 	qinfo.local_alias = NULL;
7798 
7799 	mesh_remove_callback(mesh, &qinfo, qflags,
7800 		&auth_zonemd_dnskey_lookup_callback, z,
7801 		z->zonemd_callback_unique_info);
7802 }
7803 
7804 /** Pick up the auth zone locks. */
7805 static void
fr_pickup_auth_locks(struct worker * worker,struct auth_zone * namez,struct auth_zone * old_z,struct auth_zone * new_z,struct auth_xfer ** xfr,struct auth_xfer ** loadxfr)7806 fr_pickup_auth_locks(struct worker* worker, struct auth_zone* namez,
7807 	struct auth_zone* old_z, struct auth_zone* new_z,
7808 	struct auth_xfer** xfr, struct auth_xfer** loadxfr)
7809 {
7810 	uint8_t nm[LDNS_MAX_DOMAINLEN+1];
7811 	size_t nmlen;
7812 	uint16_t dclass;
7813 
7814 	log_assert(namez->namelen <= sizeof(nm));
7815 	lock_rw_rdlock(&namez->lock);
7816 	nmlen = namez->namelen;
7817 	dclass = namez->dclass;
7818 	memmove(nm, namez->name, nmlen);
7819 	lock_rw_unlock(&namez->lock);
7820 
7821 	lock_rw_wrlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
7822 	lock_rw_wrlock(&worker->env.auth_zones->lock);
7823 	if(new_z) {
7824 		lock_rw_wrlock(&new_z->lock);
7825 	}
7826 	if(old_z) {
7827 		lock_rw_wrlock(&old_z->lock);
7828 	}
7829 	if(loadxfr)
7830 		*loadxfr = auth_xfer_find(worker->daemon->fast_reload_thread->
7831 			old_auth_zones, nm, nmlen, dclass);
7832 	if(xfr)
7833 		*xfr = auth_xfer_find(worker->env.auth_zones, nm, nmlen,
7834 			dclass);
7835 	if(loadxfr && *loadxfr) {
7836 		lock_basic_lock(&(*loadxfr)->lock);
7837 	}
7838 	if(xfr && *xfr) {
7839 		lock_basic_lock(&(*xfr)->lock);
7840 	}
7841 }
7842 
7843 /** Fast reload, worker picks up deleted auth zone */
7844 static void
fr_worker_auth_del(struct worker * worker,struct fast_reload_auth_change * item,int for_change)7845 fr_worker_auth_del(struct worker* worker, struct fast_reload_auth_change* item,
7846 	int for_change)
7847 {
7848 	int released = 0; /* Did this routine release callbacks. */
7849 	struct auth_xfer* xfr = NULL;
7850 
7851 	lock_rw_wrlock(&item->old_z->lock);
7852 	if(item->old_z->zonemd_callback_env &&
7853 	   item->old_z->zonemd_callback_env->worker == worker){
7854 		/* This worker was performing a zonemd lookup,
7855 		 * stop the lookup and remove that entry. */
7856 		auth_zone_zonemd_stop_lookup(item->old_z, worker->env.mesh);
7857 		item->old_z->zonemd_callback_env = NULL;
7858 	}
7859 	lock_rw_unlock(&item->old_z->lock);
7860 
7861 	fr_pickup_auth_locks(worker, item->old_z, item->old_z, NULL, &xfr,
7862 		NULL);
7863 	lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
7864 	lock_rw_unlock(&worker->env.auth_zones->lock);
7865 	lock_rw_unlock(&item->old_z->lock);
7866 	if(xfr) {
7867 		/* Release callbacks on the xfr, if this worker holds them. */
7868 		if(xfr->task_nextprobe->worker == worker ||
7869 			xfr->task_probe->worker == worker ||
7870 			xfr->task_transfer->worker == worker) {
7871 			released = 1;
7872 			xfr_disown_tasks(xfr, worker);
7873 		}
7874 		lock_basic_unlock(&xfr->lock);
7875 	}
7876 
7877 	if(!for_change && (released || worker->thread_num == 0)) {
7878 		/* See if the xfr item can be deleted. */
7879 		xfr = NULL;
7880 		fr_pickup_auth_locks(worker, item->old_z, item->old_z, NULL,
7881 			&xfr, NULL);
7882 		lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
7883 		lock_rw_unlock(&item->old_z->lock);
7884 		if(xfr && xfr->task_nextprobe->worker == NULL &&
7885 			xfr->task_probe->worker == NULL &&
7886 			xfr->task_transfer->worker == NULL) {
7887 			(void)rbtree_delete(&worker->env.auth_zones->xtree,
7888 				&xfr->node);
7889 			lock_rw_unlock(&worker->env.auth_zones->lock);
7890 			lock_basic_unlock(&xfr->lock);
7891 			auth_xfer_delete(xfr);
7892 		} else {
7893 			lock_rw_unlock(&worker->env.auth_zones->lock);
7894 			if(xfr) {
7895 				lock_basic_unlock(&xfr->lock);
7896 			}
7897 		}
7898 	}
7899 }
7900 
7901 /** Fast reload, auth xfer config is picked up */
7902 static void
auth_xfr_pickup_config(struct auth_xfer * loadxfr,struct auth_xfer * xfr)7903 auth_xfr_pickup_config(struct auth_xfer* loadxfr, struct auth_xfer* xfr)
7904 {
7905 	struct auth_master *probe_masters, *transfer_masters;
7906 	log_assert(loadxfr->namelen == xfr->namelen);
7907 	log_assert(loadxfr->namelabs == xfr->namelabs);
7908 	log_assert(loadxfr->dclass == xfr->dclass);
7909 
7910 	xfr->max_transfer_size = loadxfr->max_transfer_size;
7911 	xfr->max_transfer_time =  loadxfr->max_transfer_time;
7912 
7913 	/* The lists can be swapped in, the other xfr struct will be deleted
7914 	 * afterwards. */
7915 	probe_masters = xfr->task_probe->masters;
7916 	transfer_masters = xfr->task_transfer->masters;
7917 	xfr->task_probe->masters = loadxfr->task_probe->masters;
7918 	xfr->task_transfer->masters = loadxfr->task_transfer->masters;
7919 	loadxfr->task_probe->masters = probe_masters;
7920 	loadxfr->task_transfer->masters = transfer_masters;
7921 }
7922 
7923 /** Fast reload, worker picks up added auth zone */
7924 static void
fr_worker_auth_add(struct worker * worker,struct fast_reload_auth_change * item,int for_change)7925 fr_worker_auth_add(struct worker* worker, struct fast_reload_auth_change* item,
7926 	int for_change)
7927 {
7928 	struct auth_xfer* xfr = NULL, *loadxfr = NULL;
7929 
7930 	/* Start zone transfers and lookups. */
7931 	fr_pickup_auth_locks(worker, item->new_z, NULL, item->new_z, &xfr,
7932 		&loadxfr);
7933 	if(xfr == NULL && item->new_z->zone_is_slave) {
7934 		/* The xfr item needs to be created. The auth zones lock
7935 		 * is held to make this possible. */
7936 		xfr = auth_xfer_create(worker->env.auth_zones, item->new_z);
7937 		if(!xfr) {
7938 			log_err("out of memory in fr_worker_auth_add");
7939 			lock_rw_unlock(&item->new_z->lock);
7940 			lock_rw_unlock(&worker->env.auth_zones->lock);
7941 			lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
7942 			if(loadxfr) {
7943 				lock_basic_unlock(&loadxfr->lock);
7944 			}
7945 			return;
7946 		}
7947 		auth_xfr_pickup_config(loadxfr, xfr);
7948 		/* Serial information is copied into the xfr struct. */
7949 		if(!xfr_find_soa(item->new_z, xfr)) {
7950 			xfr->serial = 0;
7951 		}
7952 	} else if(for_change && xfr) {
7953 		if(!xfr_find_soa(item->new_z, xfr)) {
7954 			xfr->serial = 0;
7955 		}
7956 	}
7957 	auth_zone_pickup_initial_zone(item->new_z, &worker->env);
7958 	lock_rw_unlock(&item->new_z->lock);
7959 	lock_rw_unlock(&worker->env.auth_zones->lock);
7960 	lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
7961 	if(loadxfr) {
7962 		lock_basic_unlock(&loadxfr->lock);
7963 	}
7964 	if(xfr) {
7965 		auth_xfer_pickup_initial_zone(xfr, &worker->env);
7966 		if(for_change) {
7967 			xfr->task_probe->only_lookup = 0;
7968 		}
7969 		lock_basic_unlock(&xfr->lock);
7970 	}
7971 
7972 	/* Perform ZONEMD verification lookups. */
7973 	lock_rw_wrlock(&item->new_z->lock);
7974 	/* holding only the new_z lock */
7975 	auth_zone_verify_zonemd(item->new_z, &worker->env,
7976 		&worker->env.mesh->mods, NULL, 0, 1);
7977 	lock_rw_unlock(&item->new_z->lock);
7978 }
7979 
7980 /** Fast reload, worker picks up changed auth zone */
7981 static void
fr_worker_auth_cha(struct worker * worker,struct fast_reload_auth_change * item)7982 fr_worker_auth_cha(struct worker* worker, struct fast_reload_auth_change* item)
7983 {
7984 	int todelete = 0;
7985 	struct auth_xfer* loadxfr = NULL, *xfr = NULL;
7986 	/* Since the zone has been changed, by rereading it from zone file,
7987 	 * existing transfers and probes are likely for the old version.
7988 	 * Stop them, and start new ones if needed. */
7989 	fr_worker_auth_del(worker, item, 1);
7990 
7991 	if(worker->thread_num != 0)
7992 		return;
7993 
7994 	/* The old callbacks are stopped, tasks have been disowned. The
7995 	 * new config contents can be picked up. SOA information is picked
7996 	 * up in the auth_add routine, as it has the new_z ready. */
7997 
7998 	fr_pickup_auth_locks(worker, item->new_z, item->old_z, item->new_z,
7999 		&xfr, &loadxfr);
8000 
8001 	/* The xfr is not there any more if the zone is not set to have
8002 	 * zone transfers. Or the xfr needs to be created if it is set to
8003 	 * have zone transfers. */
8004 	if(loadxfr && xfr) {
8005 		/* Copy the config from loadxfr to the xfr in current use. */
8006 		auth_xfr_pickup_config(loadxfr, xfr);
8007 	} else if(!loadxfr && xfr) {
8008 		/* Delete the xfr. */
8009 		(void)rbtree_delete(&worker->env.auth_zones->xtree,
8010 			&xfr->node);
8011 		todelete = 1;
8012 		item->new_z->zone_is_slave = 0;
8013 	} else if(loadxfr && !xfr) {
8014 		/* Create the xfr. */
8015 		xfr = auth_xfer_create(worker->env.auth_zones, item->new_z);
8016 		if(!xfr) {
8017 			log_err("out of memory in fr_worker_auth_cha");
8018 			lock_rw_unlock(&item->new_z->lock);
8019 			lock_rw_unlock(&item->old_z->lock);
8020 			lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
8021 			lock_rw_unlock(&worker->env.auth_zones->lock);
8022 			if(loadxfr) {
8023 				lock_basic_unlock(&loadxfr->lock);
8024 			}
8025 			return;
8026 		}
8027 		auth_xfr_pickup_config(loadxfr, xfr);
8028 		item->new_z->zone_is_slave = 1;
8029 	}
8030 	lock_rw_unlock(&item->new_z->lock);
8031 	lock_rw_unlock(&item->old_z->lock);
8032 	lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
8033 	lock_rw_unlock(&worker->env.auth_zones->lock);
8034 	if(loadxfr) {
8035 		lock_basic_unlock(&loadxfr->lock);
8036 	}
8037 	if(xfr) {
8038 		lock_basic_unlock(&xfr->lock);
8039 	}
8040 	if(todelete) {
8041 		auth_xfer_delete(xfr);
8042 	}
8043 
8044 	fr_worker_auth_add(worker, item, 1);
8045 }
8046 
8047 /** Fast reload, the worker picks up changes in auth zones. */
8048 static void
fr_worker_pickup_auth_changes(struct worker * worker,struct fast_reload_auth_change * auth_zone_change_list)8049 fr_worker_pickup_auth_changes(struct worker* worker,
8050 	struct fast_reload_auth_change* auth_zone_change_list)
8051 {
8052 	struct fast_reload_auth_change* item;
8053 	for(item = auth_zone_change_list; item; item = item->next) {
8054 		if(item->is_deleted) {
8055 			fr_worker_auth_del(worker, item, 0);
8056 		}
8057 		if(item->is_added) {
8058 			if(worker->thread_num == 0) {
8059 				fr_worker_auth_add(worker, item, 0);
8060 			}
8061 		}
8062 		if(item->is_changed) {
8063 			fr_worker_auth_cha(worker, item);
8064 		}
8065 	}
8066 }
8067 
8068 /** Fast reload, the worker picks up changes in listen_dnsport. */
8069 static void
fr_worker_pickup_listen_dnsport(struct worker * worker)8070 fr_worker_pickup_listen_dnsport(struct worker* worker)
8071 {
8072 	struct listen_dnsport* front = worker->front;
8073 	struct daemon* daemon = worker->daemon;
8074 	if(worker->daemon->fast_reload_thread->sslctxs_changed) {
8075 		struct listen_list* ll;
8076 		void* dot_sslctx = daemon->listen_dot_sslctx;
8077 		void* doh_sslctx = daemon->listen_doh_sslctx;
8078 #ifdef HAVE_NGTCP2
8079 		void* quic_sslctx = daemon->listen_quic_sslctx;
8080 #endif  /* HAVE_NGTCP2 */
8081 		for(ll = front->cps; ll; ll = ll->next) {
8082 			struct comm_point* cp = ll->com;
8083 			if(cp->type == comm_tcp_accept &&
8084 				cp->tcp_handlers &&
8085 				cp->max_tcp_count > 0 &&
8086 				cp->tcp_handlers[0]->type == comm_http) {
8087 				if(cp->ssl)
8088 					cp->ssl = doh_sslctx;
8089 			} else if(cp->type == comm_tcp_accept) {
8090 				if(cp->ssl)
8091 					cp->ssl = dot_sslctx;
8092 #ifdef HAVE_NGTCP2
8093 			} else if(cp->type == comm_doq) {
8094 				if(cp->ssl) {
8095 					cp->ssl = quic_sslctx;
8096 					if(cp->doq_socket)
8097 						cp->doq_socket->ctx =
8098 							(SSL_CTX*)quic_sslctx;
8099 				}
8100 #endif  /* HAVE_NGTCP2 */
8101 			}
8102 		}
8103 	}
8104 }
8105 
8106 /** Fast reload, the worker picks up changes in outside_network. */
8107 static void
fr_worker_pickup_outside_network(struct worker * worker)8108 fr_worker_pickup_outside_network(struct worker* worker)
8109 {
8110 	struct outside_network* outnet = worker->back;
8111 	struct config_file* cfg = worker->env.cfg;
8112 	outnet->use_caps_for_id = cfg->use_caps_bits_for_id;
8113 	outnet->unwanted_threshold = cfg->unwanted_threshold;
8114 	outnet->tls_use_sni = cfg->tls_use_sni;
8115 	outnet->tcp_mss = cfg->outgoing_tcp_mss;
8116 	outnet->ip_dscp = cfg->ip_dscp;
8117 	outnet->max_reuse_tcp_queries = cfg->max_reuse_tcp_queries;
8118 	outnet->tcp_reuse_timeout = cfg->tcp_reuse_timeout;
8119 	outnet->tcp_auth_query_timeout = cfg->tcp_auth_query_timeout;
8120 	outnet->delayclose = cfg->delay_close;
8121 	if(worker->daemon->fast_reload_thread->sslctxs_changed)
8122 		outnet->sslctx = worker->daemon->connect_dot_sslctx;
8123 	if(outnet->delayclose) {
8124 #ifndef S_SPLINT_S
8125 		outnet->delay_tv.tv_sec = cfg->delay_close/1000;
8126 		outnet->delay_tv.tv_usec = (cfg->delay_close%1000)*1000;
8127 #endif
8128 	}
8129 }
8130 
8131 #ifdef USE_DNSTAP
8132 /** Fast reload, the worker picks up changes to DNSTAP configuration. */
8133 static void
fr_worker_pickup_dnstap_changes(struct worker * worker)8134 fr_worker_pickup_dnstap_changes(struct worker* worker)
8135 {
8136 	struct dt_env* w_dtenv = &worker->dtenv;
8137 	struct dt_env* d_dtenv = worker->daemon->dtenv;
8138 	log_assert(d_dtenv != NULL || !worker->daemon->cfg->dnstap);
8139 	if(d_dtenv == NULL) {
8140 		/* There is no environment when DNSTAP was not enabled
8141 		 * in the configuration. */
8142 		return;
8143 	}
8144 	w_dtenv->identity = d_dtenv->identity;
8145 	w_dtenv->len_identity = d_dtenv->len_identity;
8146 	w_dtenv->version = d_dtenv->version;
8147 	w_dtenv->len_version = d_dtenv->len_version;
8148 	w_dtenv->log_resolver_query_messages =
8149 		d_dtenv->log_resolver_query_messages;
8150 	w_dtenv->log_resolver_response_messages =
8151 		d_dtenv->log_resolver_response_messages;
8152 	w_dtenv->log_client_query_messages =
8153 		d_dtenv->log_client_query_messages;
8154 	w_dtenv->log_client_response_messages =
8155 		d_dtenv->log_client_response_messages;
8156 	w_dtenv->log_forwarder_query_messages =
8157 		d_dtenv->log_forwarder_query_messages;
8158 	w_dtenv->log_forwarder_response_messages =
8159 		d_dtenv->log_forwarder_response_messages;
8160 	lock_basic_lock(&d_dtenv->sample_lock);
8161 	w_dtenv->sample_rate = d_dtenv->sample_rate;
8162 	lock_basic_unlock(&d_dtenv->sample_lock);
8163 }
8164 #endif /* USE_DNSTAP */
8165 
8166 void
fast_reload_worker_pickup_changes(struct worker * worker)8167 fast_reload_worker_pickup_changes(struct worker* worker)
8168 {
8169 	/* The pickup of changes is called when the fast reload has
8170 	 * a synchronized moment, and all the threads are paused and the
8171 	 * reload has been applied. Then the worker can pick up the new
8172 	 * changes and store them in worker-specific structs.
8173 	 * The pickup is also called when there is no pause, and then
8174 	 * it is called after the reload has completed, and the worker
8175 	 * get a signal to release old information, it can then pick
8176 	 * up the new information. But in the mean time, the reload has
8177 	 * swapped in trees, and the worker has been running with the
8178 	 * older information for some time. */
8179 	fr_worker_pickup_mesh(worker);
8180 
8181 	/* If the tcp connection limit has changed, the open connections
8182 	 * need to remove their reference for the old tcp limits counters. */
8183 	if(worker->daemon->fast_reload_tcl_has_changes)
8184 		tcl_remove_old(worker->front);
8185 
8186 	/* If there are zonemd lookups, but the zone was deleted, the
8187 	 * lookups should be cancelled. */
8188 	fr_worker_pickup_auth_changes(worker,
8189 		worker->daemon->fast_reload_thread->auth_zone_change_list);
8190 #ifdef USE_CACHEDB
8191 	worker->env.cachedb_enabled = worker->daemon->env->cachedb_enabled;
8192 #endif
8193 	fr_worker_pickup_listen_dnsport(worker);
8194 	fr_worker_pickup_outside_network(worker);
8195 #ifdef USE_DNSTAP
8196 	fr_worker_pickup_dnstap_changes(worker);
8197 #endif
8198 }
8199 
8200 /** fast reload thread, handle reload_stop notification, send reload stop
8201  * to other threads over IPC and collect their ack. When that is done,
8202  * ack to the caller, the fast reload thread, and wait for it to send start. */
8203 static void
fr_main_perform_reload_stop(struct fast_reload_thread * fr)8204 fr_main_perform_reload_stop(struct fast_reload_thread* fr)
8205 {
8206 	struct daemon* daemon = fr->worker->daemon;
8207 	int i;
8208 
8209 	/* Send reload_stop to other threads. */
8210 	for(i=0; i<daemon->num; i++) {
8211 		if(i == fr->worker->thread_num)
8212 			continue; /* Do not send to ourselves. */
8213 		worker_send_cmd(daemon->workers[i], worker_cmd_reload_stop);
8214 	}
8215 
8216 	/* Wait for the other threads to ack. */
8217 	fr_read_ack_from_workers(fr);
8218 
8219 	/* Send ack to fast reload thread. */
8220 	fr_send_cmd_to(fr, fast_reload_notification_reload_ack, 0, 1);
8221 
8222 	/* Wait for reload_start from fast reload thread to resume. */
8223 	fr_poll_for_reload_start(fr);
8224 
8225 	/* Send reload_start to other threads */
8226 	for(i=0; i<daemon->num; i++) {
8227 		if(i == fr->worker->thread_num)
8228 			continue; /* Do not send to ourselves. */
8229 		worker_send_cmd(daemon->workers[i], worker_cmd_reload_start);
8230 	}
8231 
8232 	/* Pick up changes for this worker. */
8233 	if(fr->worker->daemon->fast_reload_drop_mesh) {
8234 		verbose(VERB_ALGO, "worker: drop mesh queries after reload");
8235 		mesh_delete_all(fr->worker->env.mesh);
8236 	}
8237 	fast_reload_worker_pickup_changes(fr->worker);
8238 
8239 	/* Wait for the other threads to ack. */
8240 	fr_read_ack_from_workers(fr);
8241 
8242 	/* Send ack to fast reload thread. */
8243 	fr_send_cmd_to(fr, fast_reload_notification_reload_ack, 0, 1);
8244 
8245 	verbose(VERB_ALGO, "worker resume after reload");
8246 }
8247 
8248 /** Fast reload, the main thread performs the nopause poll. It polls every
8249  * other worker thread briefly over the command pipe ipc. The command takes
8250  * no time for the worker, it can return immediately. After that it sends
8251  * an acknowledgement to the fastreload thread. */
8252 static void
fr_main_perform_reload_nopause_poll(struct fast_reload_thread * fr)8253 fr_main_perform_reload_nopause_poll(struct fast_reload_thread* fr)
8254 {
8255 	struct daemon* daemon = fr->worker->daemon;
8256 	int i;
8257 
8258 	/* Send the reload_poll to other threads. They can respond
8259 	 * one at a time. */
8260 	for(i=0; i<daemon->num; i++) {
8261 		if(i == fr->worker->thread_num)
8262 			continue; /* Do not send to ourselves. */
8263 		worker_send_cmd(daemon->workers[i], worker_cmd_reload_poll);
8264 	}
8265 
8266 	/* Wait for the other threads to ack. */
8267 	fr_read_ack_from_workers(fr);
8268 	fast_reload_worker_pickup_changes(fr->worker);
8269 
8270 	/* Send ack to fast reload thread. */
8271 	fr_send_cmd_to(fr, fast_reload_notification_reload_ack, 0, 1);
8272 }
8273 
8274 /** Fast reload, perform the command received from the fast reload thread */
8275 static void
fr_main_perform_cmd(struct fast_reload_thread * fr,enum fast_reload_notification status)8276 fr_main_perform_cmd(struct fast_reload_thread* fr,
8277 	enum fast_reload_notification status)
8278 {
8279 	verbose(VERB_ALGO, "main perform fast reload status: %s",
8280 		fr_notification_to_string(status));
8281 	if(status == fast_reload_notification_printout) {
8282 		fr_main_perform_printout(fr);
8283 	} else if(status == fast_reload_notification_done ||
8284 		status == fast_reload_notification_done_error ||
8285 		status == fast_reload_notification_exited) {
8286 		fr_main_perform_done(fr);
8287 	} else if(status == fast_reload_notification_reload_stop) {
8288 		fr_main_perform_reload_stop(fr);
8289 	} else if(status == fast_reload_notification_reload_nopause_poll) {
8290 		fr_main_perform_reload_nopause_poll(fr);
8291 	} else {
8292 		log_err("main received unknown status from fast reload: %d %s",
8293 			(int)status, fr_notification_to_string(status));
8294 	}
8295 }
8296 
8297 /** Fast reload, handle command from fast reload to the main thread. */
8298 static void
fr_main_handle_cmd(struct fast_reload_thread * fr)8299 fr_main_handle_cmd(struct fast_reload_thread* fr)
8300 {
8301 	enum fast_reload_notification status;
8302 	ssize_t ret;
8303 	/* keep static analyzer happy; recv(-1,..) */
8304 	log_assert(fr->commpair[0] >= 0);
8305 	ret = recv(fr->commpair[0],
8306 		((char*)&fr->service_read_cmd)+fr->service_read_cmd_count,
8307 		sizeof(fr->service_read_cmd)-fr->service_read_cmd_count, 0);
8308 	if(ret == -1) {
8309 		if(
8310 #ifndef USE_WINSOCK
8311 			errno == EINTR || errno == EAGAIN
8312 #  ifdef EWOULDBLOCK
8313 			|| errno == EWOULDBLOCK
8314 #  endif
8315 #else
8316 			WSAGetLastError() == WSAEINTR ||
8317 			WSAGetLastError() == WSAEINPROGRESS
8318 #endif
8319 			)
8320 			return; /* Continue later. */
8321 #ifdef USE_WINSOCK
8322 		if(WSAGetLastError() == WSAEWOULDBLOCK) {
8323 			ub_winsock_tcp_wouldblock(fr->service_event,
8324 				UB_EV_READ);
8325 			return; /* Continue later. */
8326 		}
8327 #endif
8328 		log_err("read cmd from fast reload thread, recv: %s",
8329 			sock_strerror(errno));
8330 		return;
8331 	} else if(ret == 0) {
8332 		verbose(VERB_ALGO, "closed connection from fast reload thread");
8333 		fr->service_read_cmd_count = 0;
8334 		/* handle this like an error */
8335 		fr->service_read_cmd = fast_reload_notification_done_error;
8336 	} else if(ret + (ssize_t)fr->service_read_cmd_count <
8337 		(ssize_t)sizeof(fr->service_read_cmd)) {
8338 		fr->service_read_cmd_count += ret;
8339 		/* Continue later. */
8340 		return;
8341 	}
8342 	status = fr->service_read_cmd;
8343 	fr->service_read_cmd = 0;
8344 	fr->service_read_cmd_count = 0;
8345 	fr_main_perform_cmd(fr, status);
8346 }
8347 
8348 /** Fast reload, poll for and handle cmd from fast reload thread. */
8349 static void
fr_check_cmd_from_thread(struct fast_reload_thread * fr)8350 fr_check_cmd_from_thread(struct fast_reload_thread* fr)
8351 {
8352 	int inevent = 0;
8353 	struct worker* worker = fr->worker;
8354 	/* Stop in case the thread has exited, or there is no read event. */
8355 	while(worker->daemon->fast_reload_thread) {
8356 		if(!sock_poll_timeout(fr->commpair[0], 0, 1, 0, &inevent)) {
8357 			log_err("check for cmd from fast reload thread: "
8358 				"poll failed");
8359 #ifdef USE_WINSOCK
8360 			if(worker->daemon->fast_reload_thread)
8361 				ub_winsock_tcp_wouldblock(worker->daemon->
8362 					fast_reload_thread->service_event,
8363 					UB_EV_READ);
8364 #endif
8365 			return;
8366 		}
8367 		if(!inevent) {
8368 #ifdef USE_WINSOCK
8369 			if(worker->daemon->fast_reload_thread)
8370 				ub_winsock_tcp_wouldblock(worker->daemon->
8371 					fast_reload_thread->service_event,
8372 					UB_EV_READ);
8373 #endif
8374 			return;
8375 		}
8376 		fr_main_handle_cmd(fr);
8377 	}
8378 }
8379 
fast_reload_service_cb(int ATTR_UNUSED (fd),short ATTR_UNUSED (bits),void * arg)8380 void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits),
8381 	void* arg)
8382 {
8383 	struct fast_reload_thread* fast_reload_thread =
8384 		(struct fast_reload_thread*)arg;
8385 	struct worker* worker = fast_reload_thread->worker;
8386 
8387 	/* Read and handle the command */
8388 	fr_main_handle_cmd(fast_reload_thread);
8389 	if(worker->daemon->fast_reload_thread != NULL) {
8390 		/* If not exited, see if there are more pending statuses
8391 		 * from the fast reload thread. */
8392 		fr_check_cmd_from_thread(fast_reload_thread);
8393 	}
8394 }
8395 
8396 #ifdef HAVE_SSL
8397 /** fast reload, send client item over SSL. Returns number of bytes
8398  * printed, 0 on wait later, or -1 on failure. */
8399 static int
fr_client_send_item_ssl(struct fast_reload_printq * printq)8400 fr_client_send_item_ssl(struct fast_reload_printq* printq)
8401 {
8402 	int r;
8403 	ERR_clear_error();
8404 	r = SSL_write(printq->remote.ssl,
8405 		printq->client_item+printq->client_byte_count,
8406 		printq->client_len - printq->client_byte_count);
8407 	if(r <= 0) {
8408 		int want = SSL_get_error(printq->remote.ssl, r);
8409 		if(want == SSL_ERROR_ZERO_RETURN) {
8410 			log_err("fast_reload print to remote client: "
8411 				"SSL_write says connection closed.");
8412 			return -1;
8413 		} else if(want == SSL_ERROR_WANT_READ) {
8414 			/* wait for read condition */
8415 			printq->client_cp->ssl_shake_state = comm_ssl_shake_hs_read;
8416 			comm_point_listen_for_rw(printq->client_cp, 1, 0);
8417 			return 0;
8418 		} else if(want == SSL_ERROR_WANT_WRITE) {
8419 #ifdef USE_WINSOCK
8420 			ub_winsock_tcp_wouldblock(comm_point_internal(printq->client_cp), UB_EV_WRITE);
8421 #endif
8422 			return 0; /* write more later */
8423 		} else if(want == SSL_ERROR_SYSCALL) {
8424 #ifdef EPIPE
8425 			if(errno == EPIPE && verbosity < 2) {
8426 				/* silence 'broken pipe' */
8427 				return -1;
8428 			}
8429 #endif
8430 			if(errno != 0)
8431 				log_err("fast_reload print to remote client: "
8432 					"SSL_write syscall: %s",
8433 					sock_strerror(errno));
8434 			return -1;
8435 		}
8436 		log_crypto_err_io("fast_reload print to remote client: "
8437 			"could not SSL_write", want);
8438 		return -1;
8439 	}
8440 	return r;
8441 }
8442 #endif /* HAVE_SSL */
8443 
8444 /** fast reload, send client item for fd, returns bytes sent, or 0 for wait
8445  * later, or -1 on failure. */
8446 static int
fr_client_send_item_fd(struct fast_reload_printq * printq)8447 fr_client_send_item_fd(struct fast_reload_printq* printq)
8448 {
8449 	int r;
8450 	r = (int)send(printq->remote.fd,
8451 		printq->client_item+printq->client_byte_count,
8452 		printq->client_len - printq->client_byte_count, 0);
8453 	if(r == -1) {
8454 		if(
8455 #ifndef USE_WINSOCK
8456 			errno == EINTR || errno == EAGAIN
8457 #  ifdef EWOULDBLOCK
8458 			|| errno == EWOULDBLOCK
8459 #  endif
8460 #else
8461 			WSAGetLastError() == WSAEINTR ||
8462 			WSAGetLastError() == WSAEINPROGRESS ||
8463 			WSAGetLastError() == WSAEWOULDBLOCK
8464 #endif
8465 			) {
8466 #ifdef USE_WINSOCK
8467 			ub_winsock_tcp_wouldblock(comm_point_internal(printq->client_cp), UB_EV_WRITE);
8468 #endif
8469 			return 0; /* Try again. */
8470 		}
8471 		log_err("fast_reload print to remote client: send failed: %s",
8472 			sock_strerror(errno));
8473 		return -1;
8474 	}
8475 	return r;
8476 }
8477 
8478 /** fast reload, send current client item. false on failure or wait later. */
8479 static int
fr_client_send_item(struct fast_reload_printq * printq)8480 fr_client_send_item(struct fast_reload_printq* printq)
8481 {
8482 	int r;
8483 #ifdef HAVE_SSL
8484 	if(printq->remote.ssl) {
8485 		r = fr_client_send_item_ssl(printq);
8486 	} else {
8487 #endif
8488 		r = fr_client_send_item_fd(printq);
8489 #ifdef HAVE_SSL
8490 	}
8491 #endif
8492 	if(r == 0) {
8493 		/* Wait for later. */
8494 		return 0;
8495 	} else if(r == -1) {
8496 		/* It failed, close comm point and stop sending. */
8497 		fr_printq_remove(printq);
8498 		return 0;
8499 	}
8500 	printq->client_byte_count += r;
8501 	if(printq->client_byte_count < printq->client_len)
8502 		return 0; /* Print more later. */
8503 	return 1;
8504 }
8505 
8506 /** fast reload, pick up the next item to print */
8507 static void
fr_client_pickup_next_item(struct fast_reload_printq * printq)8508 fr_client_pickup_next_item(struct fast_reload_printq* printq)
8509 {
8510 	struct config_strlist* item;
8511 	/* Pop first off the list. */
8512 	if(!printq->to_print->first) {
8513 		printq->client_item = NULL;
8514 		printq->client_len = 0;
8515 		printq->client_byte_count = 0;
8516 		return;
8517 	}
8518 	item = printq->to_print->first;
8519 	if(item->next) {
8520 		printq->to_print->first = item->next;
8521 	} else {
8522 		printq->to_print->first = NULL;
8523 		printq->to_print->last = NULL;
8524 	}
8525 	item->next = NULL;
8526 	printq->client_len = 0;
8527 	printq->client_byte_count = 0;
8528 	printq->client_item = item->str;
8529 	item->str = NULL;
8530 	free(item);
8531 	/* The len is the number of bytes to print out, and thus excludes
8532 	 * the terminator zero. */
8533 	if(printq->client_item)
8534 		printq->client_len = (int)strlen(printq->client_item);
8535 }
8536 
fast_reload_client_callback(struct comm_point * ATTR_UNUSED (c),void * arg,int err,struct comm_reply * ATTR_UNUSED (rep))8537 int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), void* arg,
8538 	int err, struct comm_reply* ATTR_UNUSED(rep))
8539 {
8540 	struct fast_reload_printq* printq = (struct fast_reload_printq*)arg;
8541 	if(!printq->client_cp) {
8542 		fr_printq_remove(printq);
8543 		return 0; /* the output is closed and deleted */
8544 	}
8545 	if(err != NETEVENT_NOERROR) {
8546 		verbose(VERB_ALGO, "fast reload client: error, close it");
8547 		fr_printq_remove(printq);
8548 		return 0;
8549 	}
8550 #ifdef HAVE_SSL
8551 	if(printq->client_cp->ssl_shake_state == comm_ssl_shake_hs_read) {
8552 		/* read condition satisfied back to writing */
8553 		comm_point_listen_for_rw(printq->client_cp, 0, 1);
8554 		printq->client_cp->ssl_shake_state = comm_ssl_shake_none;
8555 	}
8556 #endif /* HAVE_SSL */
8557 
8558 	/* Pickup an item if there are none */
8559 	if(!printq->client_item) {
8560 		fr_client_pickup_next_item(printq);
8561 	}
8562 	if(!printq->client_item) {
8563 		if(printq->in_list) {
8564 			/* Nothing more to print, it can be removed. */
8565 			fr_printq_remove(printq);
8566 			return 0;
8567 		}
8568 		/* Done with printing for now. */
8569 		comm_point_stop_listening(printq->client_cp);
8570 		return 0;
8571 	}
8572 
8573 	/* Try to print out a number of items, if they can print in full. */
8574 	while(printq->client_item) {
8575 		/* Send current item, if any. */
8576 		if(printq->client_item && printq->client_len != 0 &&
8577 			printq->client_byte_count < printq->client_len) {
8578 			if(!fr_client_send_item(printq))
8579 				return 0;
8580 		}
8581 
8582 		/* The current item is done. */
8583 		if(printq->client_item) {
8584 			free(printq->client_item);
8585 			printq->client_item = NULL;
8586 			printq->client_len = 0;
8587 			printq->client_byte_count = 0;
8588 		}
8589 		if(!printq->to_print->first) {
8590 			if(printq->in_list) {
8591 				/* Nothing more to print, it can be removed. */
8592 				fr_printq_remove(printq);
8593 				return 0;
8594 			}
8595 			/* Done with printing for now. */
8596 			comm_point_stop_listening(printq->client_cp);
8597 			return 0;
8598 		}
8599 		fr_client_pickup_next_item(printq);
8600 	}
8601 
8602 	return 0;
8603 }
8604 
8605 #ifndef THREADS_DISABLED
8606 /** fast reload printq create */
8607 static struct fast_reload_printq*
fr_printq_create(struct comm_point * c,struct worker * worker)8608 fr_printq_create(struct comm_point* c, struct worker* worker)
8609 {
8610 	struct fast_reload_printq* printq = calloc(1, sizeof(*printq));
8611 	if(!printq)
8612 		return NULL;
8613 	printq->to_print = calloc(1, sizeof(*printq->to_print));
8614 	if(!printq->to_print) {
8615 		free(printq);
8616 		return NULL;
8617 	}
8618 	printq->worker = worker;
8619 	printq->client_cp = c;
8620 	printq->client_cp->callback = fast_reload_client_callback;
8621 	printq->client_cp->cb_arg = printq;
8622 	return printq;
8623 }
8624 #endif /* !THREADS_DISABLED */
8625 
8626 /** fast reload printq delete */
8627 static void
fr_printq_delete(struct fast_reload_printq * printq)8628 fr_printq_delete(struct fast_reload_printq* printq)
8629 {
8630 	if(!printq)
8631 		return;
8632 #ifdef HAVE_SSL
8633 	if(printq->remote.ssl) {
8634 		SSL_shutdown(printq->remote.ssl);
8635 		SSL_free(printq->remote.ssl);
8636 	}
8637 #endif
8638 	comm_point_delete(printq->client_cp);
8639 	if(printq->to_print) {
8640 		config_delstrlist(printq->to_print->first);
8641 		free(printq->to_print);
8642 	}
8643 	free(printq);
8644 }
8645 
8646 /** fast reload printq, returns true if the list is empty and no item */
8647 static int
fr_printq_empty(struct fast_reload_printq * printq)8648 fr_printq_empty(struct fast_reload_printq* printq)
8649 {
8650 	if(printq->to_print->first == NULL && printq->client_item == NULL)
8651 		return 1;
8652 	return 0;
8653 }
8654 
8655 /** fast reload printq, insert onto list */
8656 static void
fr_printq_list_insert(struct fast_reload_printq * printq,struct daemon * daemon)8657 fr_printq_list_insert(struct fast_reload_printq* printq, struct daemon* daemon)
8658 {
8659 	if(printq->in_list)
8660 		return;
8661 	printq->next = daemon->fast_reload_printq_list;
8662 	if(printq->next)
8663 		printq->next->prev = printq;
8664 	printq->prev = NULL;
8665 	printq->in_list = 1;
8666 	daemon->fast_reload_printq_list = printq;
8667 }
8668 
8669 /** fast reload printq delete list */
8670 void
fast_reload_printq_list_delete(struct fast_reload_printq * list)8671 fast_reload_printq_list_delete(struct fast_reload_printq* list)
8672 {
8673 	struct fast_reload_printq* printq = list, *next;
8674 	while(printq) {
8675 		next = printq->next;
8676 		fr_printq_delete(printq);
8677 		printq = next;
8678 	}
8679 }
8680 
8681 /** fast reload printq remove the item from the printq list */
8682 static void
fr_printq_list_remove(struct fast_reload_printq * printq)8683 fr_printq_list_remove(struct fast_reload_printq* printq)
8684 {
8685 	struct daemon* daemon = printq->worker->daemon;
8686 	if(printq->prev == NULL)
8687 		daemon->fast_reload_printq_list = printq->next;
8688 	else	printq->prev->next = printq->next;
8689 	if(printq->next)
8690 		printq->next->prev = printq->prev;
8691 	printq->in_list = 0;
8692 }
8693 
8694 /** fast reload printq, remove the printq when no longer needed,
8695  * like the stream is closed. */
8696 static void
fr_printq_remove(struct fast_reload_printq * printq)8697 fr_printq_remove(struct fast_reload_printq* printq)
8698 {
8699 	if(!printq)
8700 		return;
8701 	if(printq->worker->daemon->fast_reload_thread &&
8702 		printq->worker->daemon->fast_reload_thread->printq == printq)
8703 		printq->worker->daemon->fast_reload_thread->printq = NULL;
8704 	if(printq->in_list)
8705 		fr_printq_list_remove(printq);
8706 	fr_printq_delete(printq);
8707 }
8708 
8709 /** fast reload thread, send stop command to the thread, from the main thread.
8710  */
8711 static void
fr_send_stop(struct fast_reload_thread * fr)8712 fr_send_stop(struct fast_reload_thread* fr)
8713 {
8714 	fr_send_cmd_to(fr, fast_reload_notification_exit, 1, 0);
8715 }
8716 
8717 void
fast_reload_thread_start(RES * ssl,struct worker * worker,struct rc_state * s,int fr_verb,int fr_nopause,int fr_drop_mesh)8718 fast_reload_thread_start(RES* ssl, struct worker* worker, struct rc_state* s,
8719 	int fr_verb, int fr_nopause, int fr_drop_mesh)
8720 {
8721 	if(worker->daemon->fast_reload_thread) {
8722 		log_err("fast reload thread already running");
8723 		return;
8724 	}
8725 	if(!fast_reload_thread_setup(worker, fr_verb, fr_nopause,
8726 		fr_drop_mesh)) {
8727 		if(!ssl_printf(ssl, "error could not setup thread\n"))
8728 			return;
8729 		return;
8730 	}
8731 	worker->daemon->fast_reload_thread->started = 1;
8732 
8733 #ifndef THREADS_DISABLED
8734 	/* Setup command listener in remote servicing thread */
8735 	/* The listener has to be nonblocking, so the the remote servicing
8736 	 * thread can continue to service DNS queries, the fast reload
8737 	 * thread is going to read the config from disk and apply it. */
8738 	/* The commpair[1] element can stay blocking, it is used by the
8739 	 * fast reload thread to communicate back. The thread needs to wait
8740 	 * at these times, when it has to check briefly it can use poll. */
8741 	fd_set_nonblock(worker->daemon->fast_reload_thread->commpair[0]);
8742 	worker->daemon->fast_reload_thread->service_event = ub_event_new(
8743 		comm_base_internal(worker->base),
8744 		worker->daemon->fast_reload_thread->commpair[0],
8745 		UB_EV_READ | UB_EV_PERSIST, fast_reload_service_cb,
8746 		worker->daemon->fast_reload_thread);
8747 	if(!worker->daemon->fast_reload_thread->service_event) {
8748 		fast_reload_thread_desetup(worker->daemon->fast_reload_thread);
8749 		if(!ssl_printf(ssl, "error out of memory\n"))
8750 			return;
8751 		return;
8752 	}
8753 	if(ub_event_add(worker->daemon->fast_reload_thread->service_event,
8754 		NULL) != 0) {
8755 		fast_reload_thread_desetup(worker->daemon->fast_reload_thread);
8756 		if(!ssl_printf(ssl, "error out of memory adding service event\n"))
8757 			return;
8758 		return;
8759 	}
8760 	worker->daemon->fast_reload_thread->service_event_is_added = 1;
8761 
8762 	/* Setup the comm point to the remote control client as an event
8763 	 * on the remote servicing thread, which it already is.
8764 	 * It needs a new callback to service it. */
8765 	log_assert(s);
8766 	state_list_remove_elem(&s->rc->busy_list, s->c);
8767 	s->rc->active --;
8768 	/* Set the comm point file descriptor to nonblocking. So that
8769 	 * printout to the remote control client does not block the
8770 	 * server thread from servicing DNS queries. */
8771 	fd_set_nonblock(s->c->fd);
8772 	worker->daemon->fast_reload_thread->printq = fr_printq_create(s->c,
8773 		worker);
8774 	if(!worker->daemon->fast_reload_thread->printq) {
8775 		fast_reload_thread_desetup(worker->daemon->fast_reload_thread);
8776 		if(!ssl_printf(ssl, "error out of memory create printq\n"))
8777 			return;
8778 		return;
8779 	}
8780 	worker->daemon->fast_reload_thread->printq->remote = *ssl;
8781 	s->rc = NULL; /* move away the rc state */
8782 	/* Nothing to print right now, so no need to have it active. */
8783 	comm_point_stop_listening(worker->daemon->fast_reload_thread->printq->client_cp);
8784 
8785 	/* Start fast reload thread */
8786 	ub_thread_create(&worker->daemon->fast_reload_thread->tid,
8787 		fast_reload_thread_main, worker->daemon->fast_reload_thread);
8788 #else
8789 	(void)s;
8790 #endif
8791 }
8792 
8793 void
fast_reload_thread_stop(struct fast_reload_thread * fast_reload_thread)8794 fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread)
8795 {
8796 	struct worker* worker = fast_reload_thread->worker;
8797 	if(!fast_reload_thread)
8798 		return;
8799 	fr_send_stop(fast_reload_thread);
8800 	if(worker->daemon->fast_reload_thread != NULL) {
8801 		/* If it did not exit yet, join with the thread now. It is
8802 		 * going to exit because the exit command is sent to it. */
8803 		fr_main_perform_done(fast_reload_thread);
8804 	}
8805 }
8806