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